First, defining two constant expressions without parentheses is my fault:
#define BIG_INTERVAL 60 * 60 * 1000
#define SMALL_INTERVAL 1 * 1000
int i = 1;
if (i >= BIG_INTERVAL / SMALL_INTERVAL - 1)
{
printf("Oops!\n");
}
The if
statement after the macro expansion is if(i >= 60 * 60 * 1000 / 1 * 1000 - 1)
.
That is not my intention. But I find something strange if I write if (i >= 3600000000 - 1)
. It is false.
What type is 60 * 60 * 1000 / 1 * 1000 - 1
? int
?
All operators on int
s return int
. So yes, 60 * 60 * 1000 / 1 * 1000 - 1
is an int
. But the expected result of 3599999999 is too big for an int
, so the expression actually evaluates to -694967297 (assuming 32-bit int
and two's complement).
This doesn't happen with a literal 3600000000
because integer literals larger than INT_MAX
are of a type that can hold the full value.
60 * 60 * 1000 / 1 * 1000 - 1 = 3600000 * 1000 - 1, which overflows the int type, so the result can be anything (in your case it's negative, but it doesn't have to be).
To achieve what you want put ( ):
#define BIG_INTERVAL (60 * 60 * 1000)
#define SMALL_INTERVAL (1 * 1000)
Here's my test results:
60 * 60 * 1000 / 1 * 1000 will result to -694967296
(60 * 60 * 1000) / (1*1000) will result to 3600
There's a problem with your operation, the precedence of computations.
You might want to consider looking at the C++ operator precedence http://msdn.microsoft.com/en-us/library/126fe14k%28v=vs.80%29.aspx. You'll find the reason why the result became -694967296 which I think effect of overflow.
If you use a compiler where int is 64 bits, you will find that the result of your expression is false. If you use a compiler where int is 32 bits or 16 bits, your expression has undefined behaviour because overflow of signed ints doesn't have to wrap around. Probably yours did just wrap around, but it doesn't have to.
3600000000 is a constant visible at compile time, so if int is only 32 bits then your compiler will have to choose long long (or just long if long is 64 bits). So your other expression is evaluated with enough bits to avoid overflowing, and the result is correct.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With