簡體   English   中英

為什么最大負整數-2147483648的絕對值仍然是-2147483648?

[英]Why the absolute value of the max negative integer -2147483648 is still -2147483648?

abs(-2147483648) 的結果是-2147483648,不是嗎? 這似乎是不可接受的。

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

輸出:

abs(-2147483648): -2147483648

標准說的是abs()

abslabsllabs函數計算整數j的絕對值。 如果結果無法表示,則行為未定義。

結果確實無法表示,因為有符號整數的 2 的補碼表示不是對稱的。 想想看......如果你在int有 32 位,那會給你從INT_MININT_MAX 2 32 個不同的值。 這是偶數個值。 因此,如果只有一個 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)未定義。

這是 GNU glibc 源代碼中 abs.c 中的代碼。

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

所以,abs(-2147483648) 返回 -(-2147483648) 。 在x86中,就是通過這兩條指令實現的

movl    $-2147483648, %eax
negl    %eax

negl指令是這樣實現的:num=0-num; sbb 通過這種方式實現:從目標中減去源,如果設置了進位標志,則額外減去 1。 所以 abs(-2147483648) (hex 是 0x80000000 ) --> -(-2147483648) --> 0-(-2147483648) 最終變成 (0x80000000)。

negl 指令的詳細信息,請訪問http://zsmith.co/intel_n.html#neg

sbb指令詳情,請訪問http://web.itu.edu.tr/kesgin/mul06/intel/instr/sbb.html

試試這個

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM