Executing the following code always gives -511 as a result, I performed many tests, and it seems that results are correct from 0 * 0 to 181 * 181, beyond that, results are abnormal, I tried many types for the z variable (int, long, float) without success, any idea? I'm using the Arduino Uno.
long z = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
z = 255 * 255;
Serial.println(z);
delay(200);
}
2 Answers 2
No, this is not a bug. You are using a compile time constant expression which is signed int
unless told otherwise. Therefore you can only represent numbers between -32768 and 32767. Your computation of 255 * 255 = 65025
exceeds the range. Thus you see an overflow. In the C/C++ standard the overflow of signed types is actually undefined behavior. That means that the compiler is allowed to do anything from showing the correct answer to halt and catch fire. Only unsigned types with a known size like uint16_t
have a well-defined overflow behaviour. You should promote your right hand side computation to unsigned type like this:
z = 255U * 255U;
This way you tell the compiler your intention and don't land in "Undefined-Behaviour-Land".
-
@Juraj Right, I thought it was signed 16 bit just as
int
. But the latter is still true. Compile time constants aresigned int
, which is 16 bit. So the right side of the assignement is the problem.Kwasmich– Kwasmich2019年02月05日 10:39:09 +00:00Commented Feb 5, 2019 at 10:39 -
wrap around
doesn't sound right - but I know what you're sayingJaromanda X– Jaromanda X2019年02月05日 11:37:43 +00:00Commented Feb 5, 2019 at 11:37
Assuming long is 4 bytes, it should work.
However, if somehow a long type is only 2 bytes, or (more likely) you used another type or there is some wrong define/typedef, and it is a signed long (default if you do not used the unsigned keyword), the value range is -32,768 to 32,767 and 255 * 255 = 65,025 which is out of range.
So you can first try to use unsigned long
.
-
long is -2,147,483,648 to 2,147,483,6472019年02月05日 10:30:34 +00:00Commented Feb 5, 2019 at 10:30
-
With unsigned long the result becomes :4294966785.Huskarnov– Huskarnov2019年02月05日 10:40:02 +00:00Commented Feb 5, 2019 at 10:40
-
Kwasmich's answer is correct2019年02月05日 10:44:40 +00:00Commented Feb 5, 2019 at 10:44
-
@Juraj - one short there :pJaromanda X– Jaromanda X2019年02月05日 11:36:25 +00:00Commented Feb 5, 2019 at 11:36
-
2it is not. Kwasmich explains2019年02月05日 13:42:53 +00:00Commented Feb 5, 2019 at 13:42
float z = 1 / 5
result will be0
because integer division results with integer that is later casted to float.