3

是否有可能对于两个正整数 i 和 j, (-i)/j 不等于 -(i/j) ?我不知道这是否可能......我认为这可能是关于位的问题,或者是 char 类型的溢出或其他问题,但我找不到它。有任何想法吗?

4

2 回答 2

12

在 C99 之前,这是可能的,因为负操作数的除法是实现定义的;它可以是代数除法或向零舍入。C99 将其定义为向零舍入。

例如,C89 允许(-1)/2 == -1,而 C99 要求(-1)/2 == 0. 在所有情况下,-(1/2) == 0

于 2013-02-14T06:35:32.360 回答
3

使用无符号整数表示 i 和 j 时确实有可能(你说的是正整数,对吧?:P)。

例如,以下程序的输出(-i)/j 2147483647 -(i/j) 0在我的 Intel 64 位 OSX 机器中(无符号整数是 32 位长)

#include <stdio.h>


int main()
{
  unsigned int i = 1;
  unsigned int j = 2;
  printf("(-i)/j %u -(i/j) %u\n", (-i)/j, -(i/j));

  return 0;
}

查看汇编程序,neglintel 指令用于计算否定。negl执行二进制补码。二进制补码结果在解释为无符号值时会导致不匹配。但不要简单地相信我的话,这里有一个例子:

例如,假设 8 位字,对于 i=1 和 j=2

二进制形式: i=00000001 j=00000010

-(i/j) = twos_complement(00000001/00000010) = twos_complement(00000000) = 00000000

-(i)/j = twos_complement(00000001)/00000010 = 11111111 / 00000001 = 1111111(十进制为 127)

由无符号表示触发的不匹配甚至在使用 C99 编译器时也会发生。正如@R 所说,在 c99 之前的编译器中也可能发生另一个不匹配,因为除以负数是实现定义的

于 2013-02-14T06:36:52.813 回答