-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update Arduino.h - abs() macros #406
base: master
Are you sure you want to change the base?
Conversation
Do not flip x, if x is zero (macros abc(x) )
I guess this is relevant for floating point numbers? For integers, it should not matter, right? |
Yes, you`re right. But that looks relevant to some pointers my friend has troubles with, and '>=' helps. |
Curious, why is your friend performing an I was curious to find out if the compiler would optimize the 2 versions to be identical, because they are semantically the same for integer types. So I disassembled the binary. It looks like on the AVR compiler, the Using >
Using >=
For vast majority of people, this isn't a difference worth worrying about. The bigger problem with Anyway, if these subtle edge cases matter in an app, I would just roll my own versions, and move on. [Edit: fix typo] |
@jenyaza01 Right, some examples with pointers that show that this change helps would be useful, then. @bxparks Nice, thanks for digging in, I'm actually a bit surprised to see this difference. I guess the compiler could optimize this, but needs a fairly specific optimization pattern to realize that it actually helps to change it. Still, optimization could be a reason to make this change in itself.
IIRC this horse was killed and buried (i.e. the problem fixed) in https://github.com/arduino/ArduinoCore-API, so that fix will migrate to to the different cores once they start using the code from -API (AVR does not yet). This also means that any change to these macros will no longer be accepted in this repo directly, but should go through the -API repo instead. And then I suspect that a small optimization on AVR is no longer a reason to change this macro, unless it would also have a similar effect on ARM. |
Thanks for THAT detail explanation) now I understand it |
I see only The This means that the side-effect problem of I think we can summarize the problems with the current
I am curious to know what the ARM compiler does.. but this is not something I have time to do right now, maybe in the future. I donno, I think this fix might be worth making, but totally up to you guys. But I don't have a strong opinion on this matter, since |
[Ignore this post. I don't think I'm thinking straight right now.] Heh, I just realized that for negative-zero, both the So ignore item (1) above about negative-zero, it's fine, or at least as fine as it can be using normal |
Right, so the multiple evaluation / macro issue is indeed not fixed in -API yet, but it is being tracked here: arduino/ArduinoCore-API#85 The handling of floating point and negative zero is indeed an open point, but as you say, it seems that 0.0 and -0.0 behave the same. So we cannot get it really right without explicitly checking for negative zero somehow (which probably fails when using an integer, or causes float operations at runtime when called with an int). However, I expect the current version will have Looking at this stackoverflow post, adding 0.0 might actually force the -0 into 0. This seems to work, even with adding 0, which ensures that (I expect) it gets optimized away when called with an integer. Here's a quick test I wrote: matthijs@grubby:~$ cat foo.c
#include <stdio.h>
#define oldabs(x) ((x)>0?(x):-(x))
#define newabs(x) ((x)>=0?(x):-(x))
#define pluszeroabs(x) ((x)>=0?(x)+0:-(x))
int main() {
float zero = 0.0, negzero = -0.0;
printf("0.0: %f, -0.0: %f\n", zero, negzero);
printf("0.0 > 0.0: %d\n", zero > zero);
printf("0.0 >= 0.0: %d\n", zero >= zero);
printf("0.0 < 0.0: %d\n", zero < zero);
printf("0.0 <= 0.0: %d\n", zero <= zero);
printf("0.0 > -0.0: %d\n", zero > negzero);
printf("0.0 >= -0.0: %d\n", zero >= negzero);
printf("0.0 < -0.0: %d\n", zero < negzero);
printf("0.0 <= -0.0: %d\n", zero <= negzero);
printf("-0.0 > 0.0: %d\n", negzero > zero);
printf("-0.0 >= 0.0: %d\n", negzero >= zero);
printf("-0.0 < 0.0: %d\n", negzero < zero);
printf("-0.0 <= 0.0: %d\n", negzero <= zero);
printf("oldabs(0.0): %f\n", oldabs(zero));
printf("oldabs(-0.0): %f\n", oldabs(negzero));
printf("newabs(0.0): %f\n", newabs(zero));
printf("newabs(-0.0): %f\n", newabs(negzero));
printf("pluszeroabs(0.0): %f\n", pluszeroabs(zero));
printf("pluszeroabs(-0.0): %f\n", pluszeroabs(negzero));
return 0;
}
matthijs@grubby:~$ gcc foo.c && ./a.out .
0.0: 0.000000, -0.0: -0.000000
0.0 > 0.0: 0
0.0 >= 0.0: 1
0.0 < 0.0: 0
0.0 <= 0.0: 1
0.0 > -0.0: 0
0.0 >= -0.0: 1
0.0 < -0.0: 0
0.0 <= -0.0: 1
-0.0 > 0.0: 0
-0.0 >= 0.0: 1
-0.0 < 0.0: 0
-0.0 <= 0.0: 1
oldabs(0.0): -0.000000
oldabs(-0.0): 0.000000
newabs(0.0): 0.000000
newabs(-0.0): -0.000000
pluszeroabs(0.0): 0.000000
pluszeroabs(-0.0): 0.000000 So, it seems that using the expression
However, unless |
If this is indeed going to be fixed via -API, I think this PR can be closed. However, @jenyaza01, I'm still curious to see an example of your (friend's) usecase of pointers with abs that was fixed by this change. Right now I have no idea what you mean there, so I cannot comment on whether that particular usecase is something to support or fix at all... |
Sorry, don't know either, what he was actually doing, all i saw - |
Right, I can imagine that a pointer argument would trigger that error (since |
Please take a look at the
|
@dok-net: How will you prevent |
@bxparks If |
The MCVE in esp8266/Arduino#8115 builds for Arduino AVR, I haven't run it just yet, will possibly do so later today. |
@dok-net : Sorry I got my signs reversed, which is really easy to do with
I believe this is why @matthijskooijman added the extra The following was executed on an ESP8266 (NodeMCU 1.0/v2):
|
@bxparks Unfortunately, this minor fix isn't going forward either for AVR or ESP8266. Anyway, we should definitely not talk about other HW like ESP's in this AVR PR. |
Do not flip x, if x is zero (macros abc(x) )