It'll work right if you make a "short" instead of "int", I think. Seems broken in 4.3.x, 4.8.x, and 4.9.x (all versions that Arduino has ever used!)
Investigating...
/**********************************************************************************/
void setup() {
Serial.begin(9600);
}
/**********************************************************************************/
void loop() {
for (int a = 32500; a >= 0; a++) {
Serial.print ("counter = ");
Serial.println (a);
}
}
I may be missing something...but...
set a to 32500.
"if" a is bigger than or equal to 0 (it always will be in this case...as it started as being defined as 32500!) and keep adding 1.
Int = 16 bits = -(2^16)/2 to (2^16)/2 = -32768 to 32768
counter = 32762
counter = 32763
counter = 32764
counter = 32765
counter = 32766
counter = 32767
counter = -32768 <------ why does it not stop here a is <= 0?
counter = -32767
counter = -32766
counter = -32765
counter = -32764
counter = -32763
counter = -32762
counter = -32761
It has rolled over the max value of a signed int.
try declaring an unsigned int, max value = 0-2^16 = 0 to 65536.
It is like a buffer overflow. You want a 17th bit as a carry over...but only 16 are available for int_16. Causes panic. The carry is placed in the sign bit (17th bit) and you end up with the -11111111 as you'd expect.
The unsigned int has actually got the 16 bits + 1 (the "unused" sign bit). The 17th is not used as a sign bit so it can be rolled over and give the representation of the full 16bit range...
Or am I chatting rubbish?
Is the short somehow being used as ushort by the compiler...?
ArdLab_Gent:
What is the difference between short and integer, they look more or less the same?
You're confusing "int" with "integer" in your question - A "char" is an integer, but it is not an "int".
Likewise, a "long" is an integer, but not an "int".
A "short" is an integer and, depending on platform, may be exactly the same as an "int", but often won't be.
aarg:
Indeed you are.
Exactly. As it has become negative, the test a >= 0 should fail.
That just hides the problem. Generally, there is a need for signed numbers. We can't just eliminate them.
This makes sense to me now. I see what the problem is.
So I got a pretty good answer over at AVRfreaks: http://www.avrfreaks.net/comment/1767746#comment-1767746
As you might have expected, if you've ever dealt with compiler folk, it's essentially "The behavior on integer overflow is defined to be undefined, so the compiler is free to do whatever it wants."
You can change the behavior with -fno-strict-overflow