本來只打算理解js中0.1 + 0.2 == 0.30000000000000004的原因,但發現自己對計算機的數字表示和運算十分陌生,於是只好惡補一下。
本篇我們一起來**一下基礎的基礎——無符號整數的表示方式和加減乘除運算。
無符號整數只能表示大於或等於零的整數值。其二進位制編碼方式十分直觀,僅包含真值域。
我們以8bit的儲存空間為例,真值域則佔8bit,因此可表示的數值範圍是,對應的二進位制編碼是。
從集合論的角度描述,我們可以將十進位制表示的數值範圍定義為集合a,將二進位制表示的數值範圍定義為集合b,他們之間的對映為f。f(a)=b,其中a屬於a、b屬於b。並且f為雙射函式。因此無符號整數表示方式具有如下特點:
可表示的數值範圍小;
十進位制表示的數值範圍與二進位制表示的數值範圍的元素是一一對應的,兩者可精確對映轉換。(相對浮點數而言,某些二進位制表示的數值只能對映為十進位制表示的數值的近似值而已)
零擴充套件運算用於在保持數值不變的前提下,不同字長的整數之間的轉換。
例如現在我們要將8bit的00000100擴充套件為16bit,那麼我們只要將高8bit設定為0即得到000000000000000100,而其數值並不產生變化。
截斷會減少位數,並對原始值取模。模為2^n,n為截斷後的位數。
例如現在將16bit的000000100000000100截斷為8bit,那麼結果為00000100,而模是2^8。
注意:位級運算均是模數運算,即加減乘除後均會對運算結果取模,並以取模後的結果作為終止返回。
無符號整數加法的運算順序:
算術加法;
執行截斷操作。
示例,兩個4bit的無符號數相加(11+6):
1011
+0110
10001,然後執行截斷得到0001
無符號整數減法的運算順序:
將減法轉換為加法(對減數取補碼);
算術加法;
執行截斷操作。
示例,兩個4bit的無符號數相減(11-6):
1011
-0110
對減數求補碼後,減法轉換為加法
1011
+1010
10101,然後執行截斷得到0101
對於乘法實質上就是通過移位操作和加、減法組合而成,且根據乘數是否為2的n次冪區別處理。
對於乘數為2的n次冪的情況,乘法公式為:a<4等價於6(2^2),則可轉換為移位操作6<<2即可。然後再對結果取模。
對於乘數不為2的n次冪的情況
2.1. 將乘數以二進位制形式表示,並以連續的1作為分組。如43的二進位制形式為00(1)0(1)0(11),從左至右可分成3組分別是(1)、(1)和(11)。
2.2. 以n表示每組的最高位的指數,以m表示每組最低位的指數。如第一組n=m=5,第二組n=m=3,第三組n=1而m=0。
2.3. 根據公式(x<2.4. 對結果取模。
對於除法實質上就是通過移位操作和加、減法組合而成,且根據除數是否為2的n次冪區別處理。
對於被除數為2的n次冪的情況,除法公式為:a>>n,如6/4等價於6/(2^2),則可轉換為移位操作6>>2即可。然後再對結果取模。
對於被除數不為2的n次冪的情況,則情況複雜不少。運算步驟如下:(實質上我們就是按這個步驟做十進位制除法的)
2.1. 高位對齊,在除數值小於被除數值的前提下,讓除數的位數等於被除數;若執行高位對齊後,除數值大於被除數時,則除數右移一位。得到位移數。
2.2. 試商,除數-被除數n = 餘數中間值 ,其中n被除數 <= 除數 && (n+1)被除數 > 除數。商 = 商 + n 基數^位移數。
2.3. 迴圈執行上述步驟,直到無需再執行高位對齊,那麼2.2中得到的餘數中間值將作為除法運算的最終餘數,否則餘數中間值則作為一下輪高位對齊的被除數處理。
以下是c的實現:
#include // 前置條件
const unsigned short lowest_bit_weight = 1; // 二進位制最低位的位權重
int main()
if (high_alignment > 0)
// 當無需執行高位對齊時,則將下一輪的被除數作為餘數,並且結束運算
if (0 == high_alignment)
// 上一輪運算的商加上最高位權重得到當前運算的商值
quotients = quotients | highest_bit_weight;
// 被除數減除數的差值作下一輪的被除數
tmp_dividend = tmp_dividend - divisor_aligned;
} printf("%u/%u=%u(rem:%u)\n", dividend, divisor, quotients, rem);
return 0;
}
《深入理解計算機系統》 無符號整數
計算機裡的數是用 二進位制表示的,最左邊的這一位一般用來表示這個數是正數還是負數,這樣的話這個數就是有符號整數。如果最左邊這一位不用來表示正負,而是和後面的連在一起表示整數,那麼就不能區分這個數是正還是負,就只能是正數,這就是無符號整數。中文名 無符號整數 學 科 數學 屬 性 整數詞 性 名詞 1...
無符號整數的bitmap
include include include using namespacestd 0000 0000 八個bit 位,每一位標誌乙個數是否存在 unsigned char bit table 8 unsigned char c 0 c bit table 3 將c 的第3個 右 7左0 bit ...
無符號整數 拼數字
題目 c語言 拼數字 描述 對於給定的字串行,從左至右將所有數字字元取出拼接成乙個無符號整數 字串行長度小於100,拼接出的整數小於2 31 計算並輸出該整數的最大因子 如果是素數或0,則其最大因子為自身 輸入說明 有多組資料 每組資料為一行字串行,當輸入乙個空行時表示輸入結束.輸出說明 對每個字串...