Floating Point 浮點數
文章目錄
- Floating Point 浮點數
- 分數二進制示例
- 能代表的數
- 浮點數的表示方式
- 浮點數編碼
- 規格化值
- 規格化值編碼示例
- 非規格化的值
- 特殊值
- 示例
- IEEE 編碼的一些特殊屬性
- 四舍五入,相加,相乘
- 四舍五入
- 四舍五入的模式
- 二進制數的四舍五入
- 浮點數乘積
- 浮點數加法
- 浮點數的一些數學性質
- 浮點數在C中
- 類型轉換的比較
- 《深入理解計算機系統》書籍學習筆記
浮點主要通過移動二進制小數點來表示盡可能大的取值范圍,兼顧盡可能高的精度,同時還要受到位數有限的限制。
分數二進制示例
值 二進制表示 十進制
5 3/4 101.11 2^2 + 2^0 + 1/2^1 + 1/2^2
2 7/8 10.111 2^1 + 1/2^1 + 1/2^2 + 1/2^3
1 7/16 1.0111 2^0 + 1/2^2 + 1/2^3 + 1/2^4
- 分數除以2,就是小數點二進制右移1位。
- 乘以2, 就是小數點左移1位
- 數字0.111111111… 小于 1,無限接近于1
- 1/2 + 1/4 + 1/8 + … + 1/2^i + … -> 1.0
- 記為 1.0 - ε
能代表的數
-
只能精確地表示x/2k形式的數字
-
其他有理數有重復的位表示
值 二進制表達 十進制
1/3 0.01010101010101[01]... 1/2^2 + 1/2^4 + 1/2^6 + 1/2^8 + ...
1/5 0.001100110011[0011]... 1/2^3 + 1/2^4 + 1/2^7 + 1/2^8 + ...
1/10 0.0001100110011[0011]... 1/2^4 + 1/2^5 + 1/2^8 + 1/2^9 + ...
浮點數的表示方式
同一標準:
(–1)^s*M*2^E
看著是不是像二進制科學計數法。
- 符號位s: 決定了數是正數還是負數
- 顯著值M(mantissa,小數部分): 通常是在[1.0,2.0]范圍內的分數值。
- 指數E(exponent): 以2的冪表示值的權重
浮點數編碼
- s 符號位
- exp 字段編碼E(但是不等于E)
- frac 字段編碼M (但是不等于M)
不同精度:
-
單精度:32 位(bits)
字段所占位數: s:exp:frac -> 1:8:23 -
雙精度: 64 位(bits)
字段所占位數: s:exp:frac -> 1:11:52
規格化值
當exp != 000…0 , 并且exp != 111…1
指數編碼有一個偏置值:E = Exp - Bias
Exp : exp字段,無符號值
Bias = 2^(k-1) -1
k 表示指數的位數
-
取值范圍
單精度:k=8, Bias = 2^(8-1) - 1 = 127 (1 <= Exp <= 254, -126 <= E <= 127)
雙精度: k=11,Bias = 2^(11-1) - 1 = 1023 (1 <= Exp <= 2046, -1022 <= E <= 1023) -
用隱含前導編碼的有效數 1: M = 1.xxxxxx 二進制
xxxxx: 表示frac 字段編碼
最小值:frac = 000…0(M=1.0)
最大值:frac = 111…1(M=2.0-ε)
注意: M 是固定前面有一個1,所以最小值才是1開始。
規格化值編碼示例
-
值
Float F = 15213.0
15213 十進制 = 11101101101101 二進制
= 1.1101101101101 * 2^13 科學計數法 -
有效數
M(小數) = 1.1101101101101 二進制
frac(小數部分編碼) = 1101101101101 0000000000 二進制 -
指數
E = 13
Bias = 127
Exp = 140 = 10001100 二進制 -
結果
非規格化的值
非規格化條件:exp = 000…0
指數值:E = 1 - Bias(注意:不是E = 0 - Bias)
以隱含前導0編碼的有效數:M = 0.xxx…x
案例:
- exp = 000…0, frac = 000…0
代表0值 - exp = 000…0, frac != 000…0
最接近0.0的數字。
平均間隔。
特殊值
特殊值條件:exp = 111…1
案例:
-
exp = 111…1, frac = 000…0
代表無窮大。
操作溢出。
例如:正無窮大:1.0/0.0 = -1.0/-0.0 , 負無窮大:1.0/-0.0 -
exp = 111…1, frac != 000…0
Not-a-Number(NaN)
表示無法確定數值時的情況。
例如:sqrt(-1), 無窮大*0
示例
我們用簡單的8位浮點數表示法,來理解浮點數。
s: 1位符號位
exp: 4位指數位, 偏置位bias=2^(4-1)-1=7
frac: 3位小數位
s exp frac E Value 計算 備注
0 0000 000 -6 0 (-1)^0 * 0 * 2^(-6)
0 0000 001 -6 1/8*1/64 = 1/512 (-1)^0 * 2^(-3) * 2^(-6) // 最接近0值
0 0000 010 -6 2/8*1/64 = 2/512 (-1)^0 * 2^(-2) * 2^(-6)
…
0 0000 110 -6 6/8*1/64 = 6/512 (-1)^0 * 2^(-1)*2^(-2) * 2^(-6)
0 0000 111 -6 7/8*1/64 = 7/512 (-1)^0 * 2^(-1)*2^(-2)* 2^(-3) * 2^(-6) // 最大的非規格化值
0 0001 000 -6 8/8*1/64 = 8/512 (-1)^0 * 1 * 2^(-6) // 最小的規格化值
0 0001 001 -6 9/8*1/64 = 9/512 (-1)^0 * (1 + 2^(-3)) * 2^(-6)
…
0 0110 110 -1 14/8*1/2 = 14/16 (-1)^0 * (1 + 2^(-1)*2^(-2)) * 2^(-1)
0 0110 111 -1 15/8*1/2 = 15/16 (-1)^0 * (1 + 2^(-1)*2^(-2)* 2^(-3)) * 2^(-1) // 最接近1的(小于1的數)
0 0111 000 0 8/8*1 = 1 (-1)^0 * 1 * 2^0
0 0111 001 0 9/8*1 = 9/8 (-1)^0 * (1 + 2^(-3)) * 2^0 // 最接近1的(大于1的數)
0 0111 010 0 10/8*1 = 10/8 (-1)^0 * (1 + 2^(-2)) * 2^0
…
0 1110 110 7 14/8*128 = 224 (-1)^0 * (1 + 2^(-1)*2^(-2)) * 2^7
0 1110 111 7 15/8*128 = 240 (-1)^0 * (1 + 2^(-1)*2^(-2)* 2^(-3)) * 2^7 // 最大的規格化數
0 1111 000 7 inf
值的計算公式:v = (–1)^s * M * 2^E
規格化數: E = Exp – Bias
非規格化數: E = 1 – Bias
IEEE 編碼的一些特殊屬性
-
浮點數(FP)的0值和整型0值一樣
所有的位都是0 -
除了非數字(NaN)之外,你可以比較任何浮點數。
當作無符號數來比較。
四舍五入,相加,相乘
四舍五入
基本思想:
- 先計算得到一個準確的值
- 然后根據你期望的精度進行處理
- 如果指數太大的化,可能會溢出
- 可能需要四舍五入來滿足小數位數(frac)
四舍五入的模式
$1.40 $1.60 $1.50 $2.50 –$1.50
向0舍入 $1 $1 $1 $2 –$1
向下舍入 $1 $1 $1 $2 –$2
向上舍入 $2 $2 $2 $3 –$1
向偶數舍入 $1 $2 $2 $2 –$2
向0舍入:向0的方向舍去小數。
向下舍入:類似向下取整
向上舍入:類似向上取整
向偶數舍入:在四舍五入的基礎上,考慮向偶數靠近,主要是在中位數時的處理方式和四舍五入不同。
二進制數的四舍五入
奇數是1,0是偶數。
二進制中間數100…,十進制中間數是500…
精度時小數后兩位:
Value Binary Rounded Action Rounded Value
2 3/32 10.000112 10.002 (<1/2—down) 2
2 3/16 10.001102 10.012 (>1/2—up) 2 1/4
2 7/8 10.111002 11.002 ( 1/2—up) 3
2 5/8 10.101002 10.102 ( 1/2—down) 2 1/2
浮點數乘積
相乘:((–1)^s1 * M1 * 2^E1) x ((–1)^s2 * M2 * 2^E2)
準確值:: (–1)^s * M * 2^E
符號位 s: s1 ^ s2
有效位 M: M1 x M2
指數位 E: E1 + E2
修正:
- 如果 M >= 2, M 右移,增加E
- 如果E 超出范圍,溢出
- 四舍五入 M 來符合精度要求。
浮點數加法
相加:((–1)^s1 * M1 * 2^E1) + ((–1)^s2 * M2 * 2^E2)
假設:E1 > E2
準確值:: (–1)^s * M * 2^E
符號位 s, 有效位 M: 對齊相加
指數位E: E1
修正:
- 如果 M >= 2, 右移M, 增加E。(小數點右移)
- 如果 M < 1, 左移 M 的 k 個位置, 減少 E 的 k。(小數點左移)
- 如果E超出范圍溢出
- 將 M 適應小數(frac)精度
浮點數的一些數學性質
浮點數加法的數學性質:
- 與阿貝爾群的比較
- 加法封閉: 滿足
- 但是可能產生 無窮大和NaN
- 結合律:滿足
- 交換律:不滿足
- 進行四舍五入時,可能溢出和不精確
- (3.14+1e10)-1e10 = 0, 3.14+(1e10-1e10) = 3.14
- 每個元素都有可加逆:幾乎滿足
- 除了無窮大和NaN
- 加法封閉: 滿足
- 單調性
- a ≥ b ? a+c ≥ b+c : 幾乎滿足
- 除了無窮大和NaN
- a ≥ b ? a+c ≥ b+c : 幾乎滿足
浮點數乘法的數學性質和加法是類似的。
浮點數在C中
無符號和有符號的轉換,從未改變過位的表示(位上的實際值),只是改變了某些位的解釋方式。
整數,單精度浮點數,雙進度浮點數的轉換,位的表示發生了變化(實際值改變了),會對位的值產生實際影響。
- double/float -> int
- 截取小數部分
- 就像向0舍入
- int -> double
精確的轉換,只要int(32) <= 53 位大小。 - int -> float
將會進行四舍五入操作。
類型轉換的比較
三個不同類型的變量:
int x = …;
float f = …;
double d = …;
一些特性的比較:
* x == (int)(float) x // false
? x == (int)(double) x // true
? f == (float)(double) f // true
? d == (double)(float) d // false
? f == -(-f); // true
? 2/3 == 2/3.0 // false. 2/3=0 整數, 2/3.0 是浮點數。
? d < 0.0 ? ((d*2) < 0.0) // true, 浮點數即使溢出也是負無窮大數
? d > f ? -f > -d // true, 單調性
? d * d >= 0.0 // true
? (d+f)-d == f // false, 不滿足結合律
《深入理解計算機系統》書籍學習筆記
《深入理解計算機系統》學習筆記 - 第一課 - 課程簡介
《深入理解計算機系統》學習筆記 - 第二課 - 位,字節和整型
《深入理解計算機系統》學習筆記 - 第三課 - 位,字節和整型
《深入理解計算機系統》學習筆記 - 第四課 - 浮點數
《深入理解計算機系統》學習筆記 - 第四課 - 機器級別的程序