-
-
Notifications
You must be signed in to change notification settings - Fork 7k
Arithmetic Error on Arduino Nano #8580
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
@jmsmdy would you mind testing the same sketch using the beta toolchain (instructions here #7949 (comment)) ? |
I'm having trouble compiling the staging branch of toolchain-avr on github (there was some python error). I'll give it another try when I have free time. If anyone who has the staging toolchain can test the code I provided on a Nano, that would be much appreciated. |
There's no need to compile the staging branch to test the beta toolchain. You only need to install it via the Arduino IDE's Boards Manager:
I just tried your code with Arduino AVR Boards 1.6.209 and I still get the unexpected result:
|
Ok, the bug is not a bug but a side effect of wrapping arithmetics. Simple POC #include <stdint.h>
uint8_t i = 0;
uint8_t j = 0;
uint8_t k = 0;
void main() {
while (1) {
j = (i - 1);
k = (i - 1) % 32;
printf("i: %d\n", i);
printf("j: %d\n", j);
printf("k: %d\n", k);
i++;
if (i == 0)
exit(0);
}
} (you can compile it on your desktop pc and just behaves as the nano). The problem here is that Using the formula here https://stackoverflow.com/a/11720975 with 0xFFFF as input returns the "expected" result. |
Bug Description
For unsigned 8-bit integers on Arduino Nano compiled with the Arduino DE, nesting operators leads to an unexpected result inconsistent with using intermediary variables.
The code:
sets k to value 255 (a seemingly incorrect value) if i=0.
Meanwhile, the code:
sets k to 31 (the correct value) if i=0.
All of these variables are type uint8_t.
I'm aware that arithmetic operations can sometimes have unexpected results (like sometimes % can return negative remainders rather than positive remainders on negative inputs). However, in this case the only difference between these two pieces of code is that in the latter we are using an intermediary variable to store the result of (i-1), and in the former we are just nesting the operators. But nesting operators versus using intermediate variables should always return the same result!
And in any case, the result of a
x % 32
operation should always be a number with absolute value < 32.Code example: (Tested on Arduino Nano with the old bootloader)
The output from the Serial port is:
Now replace these lines:
With these lines:
Then we get, as expected:
Possible Explanations?
One explanation is that this is some kind of hardware bug.
Another explanation is that there is some compiler optimization which is incorrectly replacing
(i - 1) % 32
with another operation which returns the wrong value.The text was updated successfully, but these errors were encountered: