-
-
Notifications
You must be signed in to change notification settings - Fork 7k
Erratic INT Roll Over #2207
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
Comments
Weird. I can't explain why the incrementing doesn't work... What Arduino version are you using? Could you try 1.5.7 (which has a newer compiler). As for the extra binary digits, I think it is because the print function that actually does the printing work takes a https://github.com/arduino/Arduino/blob/master/hardware/arduino/cores/arduino/Print.cpp#L76 The cast to long triggers sign-extension, which copies the topmost (sign) bit into the new bits introduced by the cast. |
I'm still using the official 1.0.5 release. The 1.5.7 release is still in Beta, but I'll give it a shot. |
I've tried to download the installer three times and each time the "Installer integrity check" failed. I downloaded the .zip file but there was no setup file in it and no instructions on where the files should be placed. |
Using nightly build + UNO. □□□□32765 111111111111101 0 For some reason it can't break the loop... |
In further testing last night I also ran into the issue where the "for" loop did not terminate as expected. As these are two different variables, I wonder if the compiler is causing the value of the loop iterator to be overwritten by the issue we are seeing in the roll over failures. |
I modified the code a little to check not only the ABS function but the comparison operator as I was having problems with it as well:
void loop() { When incrementing a negative number to a positive number the roll over works as expected: -4 4 Neg 11111111111111111111111111111100 As does decrementing from a positive number to a negative number: 5 5 Pos 101 However, when incrementing from a positive number to a negative number the roll over appears to work but the ability of both the ABS function and the Less Than operator appear to be unable to ascertain the sign of the variable: 32763 32763 Pos 111111111111011 Furthermore, when decrementing from a negative number to a positive number, again the ABS function and the Less Than operator appear to be unable to ascertain the sign of the variable. What's worse is that it also appears to interfere with the FOR loop as the FOR loop does not end after the 10 iterations programmed: -32764 32764 Neg 11111111111111111000000000000100 Letting the program run until it rolls over again it appears that the ABS function and the Less Than operator are again working: ..... It appears that this issue not only affects the x variable but it also corrupts something in the FOR loop. Is there anyone who can dig into this a little deeper than I can? |
Add the following into your loop: Serial.print("\t"); Maybe it will add clarity. Possibly abs() returns a 32bit value and On Thu, Jul 24, 2014 at 12:26 PM, HowardParr notifications@github.com
Jacob Christ |
Thanks for the input. In a previous response it was shown that the print function casts the value passed as a long. And when printing, the leading zeros are always omitted. So when any negative 16 bit number is cast as long, 16 1 bits are added. So i now understand why the print(x, BIN) displays as it does. The issue remaining is why the ABS and Less Than operator can not distinguish the fact that in this particular roll over scenario the value has changed from positive to a negative (or vice versa). |
Yeah, that is wierd. What if you cast 0 as an int? If (x <(int) 0) Jacob
|
I know that if you want a literal to be cast as a float you would use "0.0", and I believe that using just "0" the literal is automatically cast as an integer. Other than that I don't believe you can actually "cast" a literal. |
Sure you can. (char)0 and (int)0 are different things (though the latter is the same as just 0). But literals are not always int, they can be bigger. E.g 66000 is a long, so it's different from (int)66000 (which overflows, btw). Note sure what the point of the casting is - just responding to the last comment. |
My thought on adding the cast is just to test if there is a problem with Jacob
|
Ah! I figured it out. Overflow is not defined for signed integers, so once you overflow a signed int, the behaviour is undefined. In this case, aggressive loop optimization, combined with the overflow, causes things to go haywire. In particular, the loop never terminates when I tried the example here, which is weird. I reduces this to a smaller source file:
I guess the problem here really is that warnings are disabled in the IDE, which is the subject of #1728. |
I've added a new preference "show all compiler warnings" that turns warnings on |
* upstream/master: (239 commits) Fix for issue arduino#292 Windows: build_pull_request needed to be upgraded as well Update revisions.txt Windows: JRE is chosen at build time via WINDOWS_BUNDLED_JVM property Update Tone.cpp Update revisions.txt Block discovery threads until packages is not null, otherwise boards discovered during startup will miss model name Also SerialDiscovery was affected by bug found at 40535df. Fixes arduino#2892 NetworkDiscovery was silently failing because packages werenìt ready yet. Fixes arduino#2837 Better preference for setting warnings level. See arduino@61592d7#commitcomment-10668365 SAM boards stop compiling due to way of handling params with spaces on different OSs. Fixed Update Tone.cpp Restored error messages. Got rid of MessageSyphon as ther were losing some error messages. Fixes arduino#2737 Windows: added listComPorts test case New preference: enable all compiler warnings, off by default. Fixes arduino#1728 and arduino#2415. Also affects arduino#2634 and arduino#2207 build.xml: spreading failonerror on all exec tasks, it's better to crash early Lib/Board Manager CRC check is now case insensitive. Fixes arduino#2953 License fix to audio library License fix Library Manager: better error message ...
Seems this issue is figured out, and warnings can be re-enabled now, so I'm closing this issue. |
While trying to troubleshoot a problem I was having with INT roll over I ran across the following erratic behavior that I can not explain. Can anyone shed sone light on what's happening here?
I tried the following code on the Arduino Mega 2560:
void setup() {
int x = 32766;
Serial.begin(19200);
for (int a = 0; a < 5; a++) {
Serial.print(x);
Serial.print("\t");
Serial.println(x, BIN);
x += 1;
}
}
void loop() {
}
and received the following output:
32766 111111111111110
32767 111111111111111
32767 111111111111111
32767 111111111111111
32767 111111111111111
I was expecting the following:
32766 111111111111110
32767 111111111111111
-32768 1000000000000000
-32767 1000000000000001
-32766 1000000000000010
When I changed the initial value of x from 32766 to 32765 (one less) I got the following output:
32765 111111111111101
32766 111111111111110
32767 111111111111111
-32768 11111111111111111000000000000000
-32767 11111111111111111000000000000001
The decimal representation was now correct however, the binary representation has 16 additional significant bits.
Can anyone explain why I'm getting these results?
The text was updated successfully, but these errors were encountered: