abs(-2147483648)
的结果是 -2147483648
,不是吗?看起来有些不可接受。printf("abs(-2147483648): %d\n", abs(-2147483648));
输出:
abs(-2147483648): -2147483648
abs()
的说明如下:
abs
、labs
和llabs
函数计算整数j
的绝对值。如果结果无法表示,则行为是未定义的。
事实上,结果确实无法表示,因为带符号整数的2's补码表示不对称。想一想... 如果一个int
有32位,那么就会得到从INT_MIN
到INT_MAX
的232个不同的值。这是偶数个值。因此,如果只有一个0,则大于0的值的数量不能与小于0的值的数量相同。因此,没有一个正数可以与值为-INT_MIN
的INT_MIN
相对应。
所以,在您的平台上调用abs(INT_MIN)
是不可接受的。
负数通常使用二进制补码表示。
将正数转换为负数时,使用逻辑运算。
x -> not(x)+1
对于8位算术
01111111b等于127,-127变成
10000000b + 1 = 10000001b
相反的方向-127
10000001b变成
01111110b + 1 = 01111111b
-128怎么办?
-128是10000000b,没有正数对应它,因为在8位有符号算术中没有128。
10000000 -> 01111111 + 1 = 10000000,又变成-128了
原问题同样适用
由于在您的实现中2147483648大于INT_MAX
,因此abs(-2147483648)
未定义。
/* Return the absolute value of I. */
int
DEFUN(abs, (i), int i)
{
return(i < 0 ? -i : i);
}
movl $-2147483648, %eax
negl %eax
abs(INT_MIN)
仍然是未定义行为。 - undefined试试这个
printf("abs(-2147483648): %u\n", abs(-2147483648));
abs(int)
返回的是一个int
,你期待它会是什么类型? - Philip Kendall