Reputation: 8201
Why is the following code printing 255
?
#include <stdint.h>
#include <stdio.h>
int main(void) {
uint8_t i = 0;
i = (i - 1) % 16;
printf("i: %d\n", i);
return 0;
}
I assumed 15
, although i - 1
evaluates to an integer.
Upvotes: 16
Views: 2416
Reputation: 12262
Because of integer promotions in the C standard. Briefly: any type "smaller" than int
is converted to int
before usage. You cannot avoid this in general.
So what goes on: i
is promoted to int
. The expression is evaluated as int
(the constants you use are int
, too). The modulus is -1
. This is then converted to uint8_t
: 255
by the assignment.
For printf
then i
is integer-promoted to int
(again): (int)255
. However, this does no harm.
Note that in C89, for a < 0
, a % b
is not necessarily negative. It was implementation-defined and could have been 15
. However, since C99, -1 % 16
is guaranteed to be -1
as the division has to yield the algebraic quotient.
If you want to make sure the modulus gives a positive result, you have to evaluate the whole expression unsigned
by casting i
:
i = ((unsigned)i - 1) % 16;
Recommendation: Enable compiler warnings. At least the conversion for the assignment should give a truncation warning.
Upvotes: 16
Reputation: 28808
This works (displays 15) with Microsoft C compiler (no stdint.h, so I used a typedef):
#include <stdio.h>
typedef unsigned char uint8_t;
int main(void) {
uint8_t i = 0;
i = (uint8_t)(i - 1) % 16;
printf("i: %d\n", i);
return 0;
}
The reason for the 255 is because (i - 1) is promoted to integer, and the integer division used for % in C rounds towards zero instead of negative infinity (rounding towards negative infinity is the way it's done in math, science, and other programming languages). So for C % is zero or has the same sign as the dividend (in this case -1%16 == -1), while in math modulo is zero or has the same sign as the divisor.
Upvotes: 2
Reputation: 10618
This is because -1 % n
would return -1
and NOT n - 1
1. Since i
in this case is unsigned 8 bit int, it becomes 255.
1 See this question for more details on how modulo for negative integers works in C/C++.
Upvotes: 13