为什么模运算返回意外值

时间:2015-08-14 21:39:37

标签: c gcc modulo

为什么以下代码打印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;
}

我假设15,尽管i - 1评估为整数。

2 个答案:

答案 0 :(得分:15)

由于C标准中的integer promotions。简而言之:任何类型&#34;较小的&#34;使用前将int转换为int。你无法避免这种情况。

所以发生了什么: i被提升为int。表达式计算为int(您使用的常量也是int)。模数为-1。然后通过作业将其转换为uint8_t255

对于printfi整数提升为int(再次):(int)255。但是,这没有任何害处。

请注意,在C89中,对于a < 0a % b不一定是否定的。它是实现定义的,可能是15。但是,自C99起,-1 % 16保证为-1,因为除法必须产生代数商

如果你想确保模数给出正结果,你必须通过施放unsigned来评估整个表达式i

i = ((unsigned)i - 1) % 16;

建议:启用编译器警告。至少分配的转换应该给出截断警告。

答案 1 :(得分:12)

这是因为-1 % n会返回-1而非n - 1 1 。由于i在这种情况下是无符号的8位int,因此它变为255。

1 See this question for more details关于负整数的模数如何在C / C ++中起作用。