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.
In computing, the modulo operation returns the remainder or signed remainder of a division, after one number is divided by another (called the modulus of the operation).
The modulus operator, sometimes also called the remainder operator or integer remainder operator works on integers (and integer expressions) and yields the remainder when the first operand is divided by the second. In Python, the modulus operator is a percent sign ( % ). The syntax is the same as for other operators.
C++ provides the modulus operator, %, that yields the remainder after integer division. The modulus operator can be used only with integer operands. The expression x % y yields the remainder after x is divided by y. Thus, 7 % 4 yields 3 and 17 % 5 yields 2.
The % symbol in Python is called the Modulo Operator. It returns the remainder of dividing the left hand operand by right hand operand. It's used to get the remainder of a division problem. The modulo operator is considered an arithmetic operation, along with + , - , / , * , ** , // . The basic syntax is: a % b.
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.
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