二進位制補碼計算工具(有符號整數二進位制轉換)

將有符號十進位制整數轉換為8/16/32/64位的二進位制補碼錶示,或進行反向轉換。同時顯示無符號整數解釋、十六進位制表示,並檢測超出範圍的輸入。

什麼是二進位制補碼

二進位制補碼是電腦用來表示有符號整數(可正可負)的編碼方式。正數直接以普通二進位制儲存,而負數則是將其絕對值的每一位取反再加1得到的。最高位(MSB)同時扮演符號標誌的角色:為1表示負數,為0表示正數,具體能表示的範圍取決於所選的位寬(8、16、32或64位)。

本工具可以將有符號十進位制整數轉換為你所選位寬下的二進位制補碼模式,也可以反向將二進位制字串轉換回十進位制。除主要結果外,還會同時顯示同一位元序列作為無符號數的解釋、十六進位制表示,以及與原碼錶示的對照,幫助你直觀理解同一組位元在不同解讀方式下代表的不同含義。

二進位制補碼計算工具的使用方法

  1. 選擇位寬 從8、16、32、64位中選擇你想確認的整數型別對應的位寬。
  2. 選擇轉換方向 在「十進位制→二進位制」與「二進位制→十進位制」之間切換所需的轉換方向。
  3. 輸入數值 輸入有符號十進位制整數(如-5),或輸入二進位制位元串(如11111011)。
  4. 檢視轉換結果 有符號/無符號十進位制值、補碼位元模式與十六進位制表示會同時顯示出來。
  5. 確認範圍/溢位提示 輸入超出該位寬表示範圍的值會觸發錯誤提示,藉此確認溢位邊界的位置。

用好本工具的小技巧

  • 8位有符號整數的範圍是-128到127。可以嘗試先輸入127再輸入128,觀察溢位邊界——128無法容納並會觸發範圍錯誤,而這正是原本會迴繞到-128的邊界點。
  • 「無符號十進位制」這一行是將同一位元序列不作為符號位處理而直接解讀得到的值。與有符號那一行對比,能立刻看出有符號與無符號解釋之間的差異。
  • 二進位制輸入的位數必須與所選位寬完全一致——8位輸入8位數字,16位輸入16位數字,以此類推。
  • 64位的計算在內部使用BigInt而非JavaScript的Number型別,因此接近2^63的數值也能無精度損失地轉換。
  • 本工具也可用於理解C語言、Java等語言中整數溢位的行為,它們的int(32位)、long(64位)型別都會在同樣的邊界處發生迴繞。

二進位制補碼計算的應用場景

資訊科系課程與考試複習

親手演算幾乎所有資訊科系課程都會出現的二進位制轉換習題,驗證自己的答案。

排查C語言或嵌入式開發中的整數溢位問題

依實際位寬重現int或uint8_t變數出現的異常值,找出問題根源。

理解CPU暫存器的內部表示

在除錯工具中看到暫存器的十六進位制值時,立即確認它作為有符號數實際代表多少。

驗證位元運算結果

在撰寫AND、OR、位移等程式碼前後,手動核對得到的位元模式是否與預期一致。

二進位制補碼術語表

二進位制補碼(Two's Complement)
將絕對值的每一位取反再加1來表示負數的方式。它使零只有一種位元模式,並能讓同一套加法器電路兼顧加減法,因此幾乎所有現代CPU都採用它表示有符號整數。
符號位(Sign Bit)
位元序列的最高位(MSB)。在補碼錶示中,該位為1表示負數,為0表示正數。
溢位(Overflow)
運算結果超出該位寬可表示範圍時發生的現象。高位被截斷會改變符號位的含義,使數值看起來跳到了範圍的另一端。
有符號整數與無符號整數(Signed / Unsigned Integer)
同一位元序列,依是否將符號位當作負數標誌(有符號)還是當作普通數值位(無符號),會得到不同的解釋結果。
位寬(Bit Width)
表示一個整數所使用的位元數量。常見的位寬有8、16、32、64位,位寬越大,能表示的數值範圍就越廣。
反碼(One's Complement)
一種較早的方式,僅將正數的每一位取反即可得到負數,不再加1。其缺點是零會產生「+0」和「-0」兩種不同的模式,這正是補碼要解決的問題。

常見問題

原碼錶示和反碼錶示都會產生兩種不同的零的位元模式(「+0」和「-0」),這會使比較和運算電路變得複雜。補碼錶示的零隻有一種位元模式,而且同樣重要的是,用於加法的加法器電路也可以直接用於減法。這兩個特性讓CPU設計者能夠簡化算術邏輯單元,這正是幾乎所有現代處理器內部都使用補碼來表示有符號整數的原因。

-128到127。由於最高位被保留作為符號位,正數一側只能表示128種不同的模式(0到127),而負數一側可以表示128種不同的值(-1到-128),因為補碼的零隻佔用一種位元模式,多出的一種模式被分配給了負數一側,這就是範圍不對稱的原因。

反碼只需將正數的每一位取反即可得到負數。補碼則在取反的基礎上再加1。這多出的一步消除了反碼固有的「雙零問題」(00000000表示「+0」,11111111表示「-0」),這也是補碼成為標準表示方式的原因。

因為位寬是固定的,任何超出可表示範圍的運算結果都會導致高位被截斷,從而改變了符號位的含義。例如,對8位有符號最大值127加1會得到位元模式10000000,按有符號規則解讀為-128。超過上限就會迴繞到下限,這種違反直覺的跳變正是溢位的本質。

位元模式本身不會改變,但由於不再將最高位當作符號位,每一位都只貢獻其常規的位權值。例如8位位元模式11111011,按有符號解讀為-5,但按無符號解讀則為251。當你把一個原本按有符號處理的值用於像C語言unsigned int這樣的「無符號」型別時,實際上就會發生這種重新解釋。
工具君

閒話 ― 為什麼計算機使用二進位制補碼

二進位制補碼並不是表示負數的唯一方式。歷史上還使用過原碼錶示(僅將最高位當作符號標誌)和反碼錶示(簡單地將正數的每一位取反)。這兩種方式都有一個共同的缺陷:會出現兩種不同的零的位元模式,即「+0」和「-0」,這使得比較邏輯和電路設計變得複雜。而二進位制補碼完全避免了這個「雙零問題」——每一種位元模式都唯一對應一個整數值。

補碼更大的優勢在於,用於加法的同一套加法器電路也可以直接用於減法,因為減去一個數等價於加上它的補碼。CPU無需判斷某個值是正數還是負數,只需將位元模式相加即可得到正確結果。這使得算術邏輯單元(ALU)可以省去專門的減法電路,這也是幾乎所有現代CPU架構都採用補碼來表示有符號整數的原因。

整數溢位正是這種表示方式的直接結果。8位有符號最大值127(01111111)加1後,位元模式簡單地進位為10000000——若按有符號方式解讀,這就是-128。在C語言中,有符號整數溢位在技術上屬於「未定義行為」,編譯器最佳化可能在這個邊界附近產生出人意料的結果,因此在實際生產程式碼中需要格外謹慎。相比之下,Java明確規定溢位會靜默地迴繞,這也是一個有趣的例子,說明即使底層位元表示完全相同,不同語言之間的行為保證也可能大相逕庭。