Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is a modulo operation returning an unexpected value

Tags:

c

gcc

modulo

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.

like image 864
Razer Avatar asked Aug 14 '15 21:08

Razer


People also ask

What does the modulo operator return?

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).

How does the modulo operation work?

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.

What does mod return in C++?

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.

What is modulus operation in Python?

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.


1 Answers

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.

like image 86
too honest for this site Avatar answered Jan 06 '23 07:01

too honest for this site