[英]Does C uses 2's complement internally to evaluate unsigned numbers arithmetic like 5-4?
[英]Which complement does C use internally?
我查找的所有內容只是告訴我如何在 C 中進行補充運算/計算。
我想知道 C 在內部使用什么表示以及它如何處理溢出。
C 允許有符號整數的 3 表示( https://port70.net/~nsz/c/c11/n1570.html#6.2.6.2p2 ):
- 符號位為 0 的對應值被取反(符號和大小);
- 符號位的值為 -(2M)(二進制補碼);
- 符號位的值為 -(2M- 1)(一個的補碼)。
補碼是最常見的。
無符號溢出環繞無符號的最大值。
有符號溢出會導致未定義的行為。 即,假定它不會發生,並且如果您確實做到了,則不能保證您的程序的行為。
簽名原子中的溢出是一個例外:它定義明確,並且在那里強制要求二進制補碼: https ://port70.net/~nsz/c/c11/n1570.html#7.17.7.5p3。
C 是否使用一的補碼、二的補碼或負整數的符號/大小表示是實現定義的。 也就是說,每個編譯器都可以選擇,通常基於它為其生成代碼的處理器。
所以當你寫
x = -x
編譯器可能會生成等價於
x = ~x; /* one's complement */
或者
x = ~x + 1; /* two's complement */
或者
x ^= 0x80000000; /* sign/magnitude, assuming 32 bits */
當然,大多數時候你不必擔心這個。 (而且在大多數情況下——如今可以肯定地說,一直都在說——你正在開發一台使用二進制補碼的機器,因為它是最受歡迎的機器。)
由於它是實現定義的,因此文檔應該會告訴您。 但我想你總是可以用一段代碼憑經驗確定它:
#include <stdio.h>
#include <limits.h>
int main()
{
int x = 1;
int negativex = -x;
if(negativex == ~x)
printf("one's complement\n");
else if(negativex == ~x + 1)
printf("two's complement\n");
else if(negativex == (x ^ (1 << (sizeof(x) * CHAR_BIT - 1))))
printf("sign/magnitude\n");
else
printf("what the heck kind of machine are you on??\n");
}
你問的是溢出。 對於無符號整數,溢出以明顯的方式定義為“環繞”(即,它以 2^N 為模執行,其中 N 是位數)。 但是對於有符號整數,溢出在形式上是未定義的:理論上可能存在有符號整數溢出會產生錯誤的機器,或多或少類似於除以 0。
(當然,在普通的二進制補碼機器上,有符號整數算法也以明顯的方式悄悄地環繞,因為二進制補碼的全部意義在於環繞溢出使其工作。)
由於int
和float
等數據類型的大小取決於您使用的機器,如果 C 標准規定了內部表示,我會感到驚訝。 所以我懷疑它是依賴於實現的。
簡而言之,我們可以說C中的2s 補碼定義為C中的 1 的補碼與 1 的和。
C 中的2s 補碼是從 C 中的 1s 補碼生成的。眾所周知,二進制數的 1s 補碼是通過將位 1 轉換為 0 和 0 轉換為 1 來創建的; 二進制數的 2s 補碼是通過在二進制數的 1s 補碼上加 1 生成的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.