对于两个正整数i和j,( - i)/ j是否可能不等于 - (i / j)?我无法弄清楚这是否可能......我认为这将是关于比特,或溢出的char类型或其他东西,但我无法找到它。有什么想法吗?
答案 0 :(得分:10)
前C99,这是可能的,因为负操作数的划分是实现定义的;它可以是代数除法或圆向零。 C99将其定义为向零舍入。
例如,C89允许(-1)/2 == -1
,而C99需要(-1)/2 == 0
。在所有情况下,-(1/2) == 0
。
答案 1 :(得分:3)
使用无符号整数来表示i和j 时确实(你说正整数,对吗?:P)。
例如,我的Intel 64位OSX机器中的以下程序的输出为(-i)/j 2147483647 -(i/j) 0
(无符号整数为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;
}
查看汇编程序,negl
intel指令用于计算否定。 negl
执行twos complement。当二进制补码结果被解释为无符号值时,会导致不匹配。但是,不要简单地接受我的话,这是一个例子:
例如,假设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所述,自division by a negative number was implementation defined以来,在c99之前的编译器中也可能发生另一次不匹配。