C语言 为什么最大负整数-2147483648的绝对值仍然是-2147483648?

vdgimpew  于 2023-11-16  发布在  其他
关注(0)|答案(6)|浏览(269)

abs(-2147483648)的结果是-2147483648,不是吗?似乎无法接受。

  1. printf("abs(-2147483648): %d\n", abs(-2147483648));

字符串
产出:

  1. abs(-2147483648): -2147483648

jgzswidk

jgzswidk1#

关于abs()
abslabsllabs函数计算整数j的绝对值。如果结果无法表示,则行为未定义。
结果确实不能被表示,因为有符号整数的2的补码表示不是对称的。想想看.如果你在int中有32位,那就给了你从INT_MININT_MAX的232个不同的值。这是偶数个值。所以,如果只有一个0,大于0的值的个数不能和小于0的值的个数相同,所以INT_MIN的值不存在对应的正数-INT_MIN
因此,在您的平台上调用abs(INT_MIN)是不可接受的。

uurity8g

uurity8g2#

负数通常用二进制补码表示.
要将正转换为负,需要使用逻辑

  1. 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
同样适用于原始问题

展开查看全部
nhjlsmyf

nhjlsmyf3#

由于2147483648在您的实现中大于INT_MAX,因此abs(-2147483648)未定义。

ecfsfe2w

ecfsfe2w4#

这是GNU glibc源代码中的abs.c代码。

  1. /* Return the absolute value of I. */
  2. int
  3. DEFUN(abs, (i), int i)
  4. {
  5. return(i < 0 ? -i : i);
  6. }

字符串
因此,abs(-2147483648)返回-(-2147483648)。在x86中,它由这两条指令实现

  1. movl $-2147483648, %eax
  2. negl %eax


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

展开查看全部
ia2d9nvy

ia2d9nvy5#

我记得这是一个溢出错误。在S2 C中,有符号整数的最大值是-(2^(total bits - 1))。然而,最大正值实际上是(2^(total bits - 1))-1。按位,函数产生正确的值。然而,“正确”的按位值超过最大正值1,滚动到负值集合。

izkcnapc

izkcnapc6#

试试这个

  1. printf("abs(-2147483648): %u\n", abs(-2147483648));

字符串

相关问题