I am trying to port a program from Perl to Arduino C. In the manual I found that math expressions within abs() are discouraged. My current Perl code does a abs($var-1). How could I do this the best way on the Arduino (without changing the value of var) if abs(var-1) does not work?
I don't know about discouraging math within abs I would just directly translate from Perl. Is $var a string in Perl or a regular number? I don't believe Perl distinguishes integers and floats but you need to define int or float in Arduino C.
Because of the way the abs() function is implemented, avoid using other functions inside the brackets, it may lead to incorrect results.
abs(a++); // avoid this - yields incorrect results
a++; // use this instead -
abs(a); // keep other math outside the function
That's what made me think that I need to do it differently. But if this is not the case, then I will happily use the direct equivalent abs(var-1). And yes, $var can be a string or an integer in Perl. I have defined it as a int in my Arduino code.
You can always do
y=$var-1 and then abs(y) to be sure. The following from the reference page is just strange:
abs(a++); // avoid this - yields incorrect results
a++; // use this instead -
abs(a); // keep other math outside the function
Maybe the person that wrote the above didn't know what a++ is supposed to do. If he wants a to increment before the abs, he should use abs(++a).
If abs() is a function, then its parameter is parsed and calculated before the function call is made. End of the story. If the abs() is a macro, it may mess up a little if written improperly.
You beat me to it on "macro messes things up", Rob.
I never use macro defs like that. It's just a poor way to construct things with unpredictable outcomes. Always use a function so its parameters get evaluated before the call.
@liudr
Robustness is one thing speed another, it is difficult to optimize both. A function takes the calling overhead and has a parameter and return type.
That said - why not just code the abs() directly as it takes minimal lines
// y = abs(a++);
a++;
if (a > = 0) y = a;
else y = -a;
I think in my case it will be the best if I use the version with the temporary variable - even though this looks ugly to me Coding the abs manually would not help here since I want the original variable "var" untouched and not modify it like in the a++ example.