資料表示法:位元、位元組與數值

無號整數與模算術

在固定數量的位元裡儲存一個整數,最簡單的方法也最直接:就照你在紙上寫的方式把它寫成二進位。無號整數正是如此——一個非負整數,以它樸素的二進位位值模式儲存,沒有容納或處理負號的空間或規則。「無號」字面意思就是「沒有符號」;這些是用來計數的數,從零開始往上走。

用 n 個位元,你能表示 0 到 2^n 減 1 的值,其他都不行。8 位元的無號整數範圍是 0 到 255;16 位元的是 0 到 65535;32 位元的是 0 到 4294967295。位元模式的讀法是把為 1 的位元的位值加起來,就跟普通二進位一樣:1111 1111 是 128+64+32+16+8+4+2+1 = 255。因為寬度固定,所以有個硬上限,而那個上限正是有趣行為開始的地方。

當一個無號結果會超過範圍頂端時,它不會報錯,也不會變成負數——它會「環繞」,這是定義使然,彷彿數字活在時鐘上。形式上,C 的無號算術是模算術:每個結果都對 2^n 取模。在 8 位元上,255 + 1 得到 0(255 + 1 = 256,而 256 mod 256 = 0),0 - 1 得到 255。這不是錯誤也不是意外;C 標準「明定」了它,這正是為什麼無號型別是雜湊、檢查碼、位元操作,以及任何你想要乾淨、可預測環繞之處的正確工具。(這與有號溢位形成鮮明對比,後者是未定義行為——千萬別以為有號型別會以同樣友善的方式環繞。)

一個值為 255 的 8 位元無號計數器,加一之後變成 0——就像里程表翻轉歸零。在 C 裡:unsigned char c = 255; c++; 現在 c == 0,這是保證的。

無號算術依定義對 2^n 取模環繞。

用較小的無號值減去較大的,不會得到負數——它會環繞成一個極大的正數,所以像「for (unsigned i = n; i >= 0; i--)」這樣的迴圈永遠不會結束,因為 i 永遠不可能是負的。

又稱
unsigned int無號數natural-number representation