abs(-2147483648)的结果是-2147483648,不是吗?似乎无法接受。
abs(-2147483648)
-2147483648
printf("abs(-2147483648): %d\n", abs(-2147483648));
字符串产出:
abs(-2147483648): -2147483648
型
jgzswidk1#
关于abs():abs、labs和llabs函数计算整数j的绝对值。如果结果无法表示,则行为未定义。结果确实不能被表示,因为有符号整数的2的补码表示不是对称的。想想看.如果你在int中有32位,那就给了你从INT_MIN到INT_MAX的232个不同的值。这是偶数个值。所以,如果只有一个0,大于0的值的个数不能和小于0的值的个数相同,所以INT_MIN的值不存在对应的正数-INT_MIN因此,在您的平台上调用abs(INT_MIN)是不可接受的。
abs()
abs
labs
llabs
j
int
INT_MIN
INT_MAX
abs(INT_MIN)
uurity8g2#
负数通常用二进制补码表示.要将正转换为负,需要使用逻辑
x -> not(x)+1
字符串对于8位算术0111111 b是127,-127变成10000000b + 1 = 10000001b而相反方向-127 10000001 b变为01111110b + 1 = 01111111b-128呢?-128是10000000 b,没有它的正对应,因为在8位有符号算术中没有128。10000000 -> 01111111 + 1 = 10000000和-128同样适用于原始问题
nhjlsmyf3#
由于2147483648在您的实现中大于INT_MAX,因此abs(-2147483648)未定义。
ecfsfe2w4#
这是GNU glibc源代码中的abs.c代码。
/* Return the absolute value of I. */intDEFUN(abs, (i), int i){ return(i < 0 ? -i : i);}
/* Return the absolute value of I. */
DEFUN(abs, (i), int i)
{
return(i < 0 ? -i : i);
}
字符串因此,abs(-2147483648)返回-(-2147483648)。在x86中,它由这两条指令实现
movl $-2147483648, %eaxnegl %eax
movl $-2147483648, %eax
negl %eax
型numl指令是这样实现的:num=0-num; sbb是这样实现的:从目标中减去源,如果设置了进位标志,则减去1。因此,(-2147483648)(十六进制为0x 80000000)--> -(-2147483648)--> 0-(-2147483648)最终变为(0x 80000000)。详细的教程,请访问http://zsmith.co/intel_n.html#negsbb指令详情,请浏览http://web.itu.edu.tr/kesgin/mul06/intel/instr/sbb.html
ia2d9nvy5#
我记得这是一个溢出错误。在S2 C中,有符号整数的最大值是-(2^(total bits - 1))。然而,最大正值实际上是(2^(total bits - 1))-1。按位,函数产生正确的值。然而,“正确”的按位值超过最大正值1,滚动到负值集合。
izkcnapc6#
试试这个
printf("abs(-2147483648): %u\n", abs(-2147483648));
字符串
6条答案
按热度按时间jgzswidk1#
关于
abs()
:abs
、labs
和llabs
函数计算整数j
的绝对值。如果结果无法表示,则行为未定义。结果确实不能被表示,因为有符号整数的2的补码表示不是对称的。想想看.如果你在
int
中有32位,那就给了你从INT_MIN
到INT_MAX
的232个不同的值。这是偶数个值。所以,如果只有一个0,大于0的值的个数不能和小于0的值的个数相同,所以INT_MIN
的值不存在对应的正数-INT_MIN
因此,在您的平台上调用
abs(INT_MIN)
是不可接受的。uurity8g2#
负数通常用二进制补码表示.
要将正转换为负,需要使用逻辑
字符串
对于8位算术
0111111 b是127,-127变成
10000000b + 1 = 10000001b
而相反方向-127 10000001 b变为
01111110b + 1 = 01111111b
-128呢?
-128是10000000 b,没有它的正对应,因为在8位有符号算术中没有128。
10000000 -> 01111111 + 1 = 10000000和-128
同样适用于原始问题
nhjlsmyf3#
由于2147483648在您的实现中大于
INT_MAX
,因此abs(-2147483648)
未定义。ecfsfe2w4#
这是GNU glibc源代码中的abs.c代码。
字符串
因此,abs(-2147483648)返回-(-2147483648)。在x86中,它由这两条指令实现
型
numl指令是这样实现的:num=0-num; sbb是这样实现的:从目标中减去源,如果设置了进位标志,则减去1。因此,(-2147483648)(十六进制为0x 80000000)--> -(-2147483648)--> 0-(-2147483648)最终变为(0x 80000000)。
详细的教程,请访问http://zsmith.co/intel_n.html#neg
sbb指令详情,请浏览http://web.itu.edu.tr/kesgin/mul06/intel/instr/sbb.html
ia2d9nvy5#
我记得这是一个溢出错误。在S2 C中,有符号整数的最大值是-(2^(total bits - 1))。然而,最大正值实际上是(2^(total bits - 1))-1。按位,函数产生正确的值。然而,“正确”的按位值超过最大正值1,滚动到负值集合。
izkcnapc6#
试试这个
字符串