簡體   English   中英

C 在內部使用哪個補碼?

[英]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。

(當然,在普通的二進制補碼機器上,有符號整數算法也以明顯的方式悄悄地環繞,因為二進制補碼的全部意義在於環繞溢出使其工作。)

由於intfloat等數據類型的大小取決於您使用的機器,如果 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.

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