浮點數,真的很難學
- 什么是浮點數
- 浮點數的存盤標準:IEEE754
- 浮點數的數學表示:Sign,Exponent和Significand
- 浮點數的資料型別:float與double
- 浮點數的數值范圍
- float的取值范圍
- double的取值范圍
- 浮點數的特殊取值
- 浮點數與其他數制的轉換
- 浮點數運算
- 五種例外情況
- 浮點數加法
- 1.對階
- 2.尾數加減
- 3.尾數規格化
- 4.舍入
- 5.校驗
因為我上課沒好好聽
什么是浮點數
浮點數,是與定點數相對的概念,指小數點位置約定在固定位置的數,
浮點數的存盤標準:IEEE754
浮點數在計算機中以遵循IEEE754浮點數計數標準的方式存盤,
IEEE 754規定了四種表示浮點數值的方式:單精確度(32位)、雙精確度(64位)、延伸單精確度(43位元以上,很少使用)與延伸雙精確度(79位元以上,通常以80位實作),
浮點數的數學表示:Sign,Exponent和Significand
X = ( ? 1 ) S × M × R E X=(-1)^{S}\times M\times R^{E} X=(?1)S×M×RE
S,Sign:符號位,決定該浮點數的正負
M,Mantissa/Significand:尾數,取值為[1,2)的二進制小數,
R,Radix base:基數,對浮點數加權,權重為2的E次冪,
E,Exponent:階/指數,二進制定點(無符號)整數,
考試的時候問你尾數是什么,你要回答小數點后那部分
在基數R一定的情況下:
尾數M的位數反映數X的有效位數,它決定了數的表示精度,有效位數越多,表示精度越高,
階E的位數決定數X的表示范圍,值確定了小數點的位置,
M位數越多,X越精確,
E越大,X越大
浮點數的資料型別:float與double
IEEE754規定浮點數有單精確度、雙精確度、延伸單精確度與延伸雙精確度四種型別,但是本文只對單精確度float與雙精確度double型別作分析學習,

在科學計數法中指數是可以取負數的,所以IEEE754規定計算機存盤浮點數時,階E需要在真實值基礎上再減去一個偏移值bias,即127(for float)或1023(for double)
M的取值為[1,2),即M可寫為1.xxxx的形式,xxxx越長浮點數越精確,
規格化尾數M的小數點后第一位總是1,故規定第一位默認的1被省略,由此用23個數表示24位尾數,
浮點數的數值范圍
絕對值范圍為:
2
?
(
2
e
?
1
)
×
2
?
m
≤
∣
X
∣
≤
(
1
?
2
?
m
)
×
2
(
2
m
?
1
)
2^{-(2^{e}-1)} \times 2^{-m} \leq \left | X \right |\leq (1-2^{-m}) \times 2^{(2^{m}-1)}
2?(2e?1)×2?m≤∣X∣≤(1?2?m)×2(2m?1)
其中e和m分別表示階數與尾數的位數
float的取值范圍

在32位浮點數中,符號位占1位,尾數占23位,階數占8位,
不考慮階數全為0或全為1的情況下,8位二進制數取值范圍即[1,254]減去其偏移量127,得到階數的規格化范圍為 [-126,127],
在正常情況下,階數不包括全為0或全為1的情況
實際的指數值 -127(保存為全0)以及 +128(保存為全 1)保留用作特殊值(見下文)
正數最小值為
| Sign | Exponent | Mantissa |
|---|---|---|
| 0 | 00000001 | 00000000000000000000000 |
1.00...0 × 2 00...1 = 1 × 2 ? 126 = 2 ? 126 1.00...0 \times 2^{00...1}=1 \times 2^{-126}=2^{-126} 1.00...0×200...1=1×2?126=2?126
正數最大值為
| Sign | Exponent | Mantissa |
|---|---|---|
| 0 | 11111110 | 11111111111111111111111 |
1.11...1 × 2 11111110 = ( 2 ? 2 ? 23 ) × 2 127 ≈ 3.4028234664 × 1 0 38 1.11...1 \times 2^{11111110}=(2-2^{-23}) \times 2^{127} \approx 3.4028234664 \times 10^{38} 1.11...1×211111110=(2?2?23)×2127≈3.4028234664×1038
于是對于正浮點數有:
1.0
×
2
?
126
≈
1.1755
×
1
0
?
38
≤
F
l
o
a
t
N
u
m
≤
(
2
?
2
?
23
)
×
2
127
≈
3.4028
×
1
0
38
1.0 \times 2^{-126} \approx 1.1755 \times 10^{-38} \leq FloatNum \leq (2-2^{-23}) \times 2^{127} \approx 3.4028 \times 10^{38}
1.0×2?126≈1.1755×10?38≤FloatNum≤(2?2?23)×2127≈3.4028×1038
同理對于負浮點數有
?
(
2
?
2
?
23
)
×
2
127
≈
?
3.4028
×
1
0
38
≤
F
l
o
a
t
N
u
m
≤
?
1.0
×
2
?
126
≈
?
1.1755
×
1
0
?
38
≈
3.4028
×
1
0
?
38
-(2-2^{-23}) \times 2^{127} \approx -3.4028 \times 10^{38} \leq FloatNum \leq -1.0 \times 2^{-126} \approx -1.1755 \times 10^{-38} \approx 3.4028 \times 10^{-38}
?(2?2?23)×2127≈?3.4028×1038≤FloatNum≤?1.0×2?126≈?1.1755×10?38≈3.4028×10?38
double的取值范圍

在64位浮點數中,符號位占1位,尾數占52位,階數占11位,
不考慮階數全為0或全為1的情況下,11位二進制數取值范圍即[1,2046]減去其偏移量1023,得到階數的規格化范圍為 [-1022,1023],
實際的指數值 -1023(保存為全0)以及 +1024(保存為全 1)保留用作特殊值
正數最小值為
| Sign | Exponent | Mantissa |
|---|---|---|
| 0 | 00000000001 | 0000000000000000000000000000000000000000000000000000 |
1.00...0 × 2 00...1 = 1 × 2 ? 1022 = 2 ? 1022 1.00...0 \times 2^{00...1}=1 \times 2^{-1022}=2^{-1022} 1.00...0×200...1=1×2?1022=2?1022
正數最大值為
| Sign | Exponent | Mantissa |
|---|---|---|
| 0 | 11111111110 | 1111111111111111111111111111111111111111111111111111 |
1.11...1 × 2 11...10 = ( 2 ? 2 ? 52 ) × 2 1023 ≈ 1.7976931348623157 × 1 0 308 1.11...1 \times 2^{11...10}=(2-2^{-52}) \times 2^{1023} \approx 1.7976931348623157 \times 10^{308} 1.11...1×211...10=(2?2?52)×21023≈1.7976931348623157×10308
于是對于正浮點數有:
1.0
×
2
?
1022
≈
2.2251
×
1
0
?
308
≤
D
o
u
b
l
e
N
u
m
≤
(
2
?
2
?
52
)
×
2
1023
≈
1.7977
×
1
0
308
1.0 \times 2^{-1022} \approx 2.2251 \times 10^{-308} \leq DoubleNum \leq (2-2^{-52}) \times 2^{1023} \approx 1.7977 \times 10^{308}
1.0×2?1022≈2.2251×10?308≤DoubleNum≤(2?2?52)×21023≈1.7977×10308
同理對于負浮點數有
?
(
2
?
2
?
52
)
×
2
1023
≈
?
1.7977
×
1
0
308
≤
D
o
u
b
l
e
N
u
m
≤
?
1.0
×
2
?
1022
≈
?
2.2251
×
1
0
?
308
-(2-2^{-52}) \times 2^{1023} \approx -1.7977 \times 10^{308} \leq DoubleNum \leq -1.0 \times 2^{-1022} \approx -2.2251 \times 10^{-308}
?(2?2?52)×21023≈?1.7977×10308≤DoubleNum≤?1.0×2?1022≈?2.2251×10?308
浮點數的特殊取值
Single-precision floating-point format:
https://en.wikipedia.org/wiki/Single-precision_floating-point_format
Double-precision floating-point format:
https://en.wikipedia.org/wiki/Double-precision_floating-point_format
這里貼一個小工具,在IEEE754的標準下手動控制輸入Sign,Exponent和Mantissa的值,輸出對應的十進制值,二進制值,十六進制值,非常簡單直觀
https://www.h-schmidt.net/FloatConverter/IEEE754.html

常見浮點數特殊值取值如下表
| Sign | Exponent | Mantissa | |
|---|---|---|---|
| 0 | Both cases valid | all zeros | all zeros |
| + ∞ +\infty +∞ | zero | all ones | all zeros |
| ? ∞ -\infty ?∞ | one | all ones | all zeros |
| NaN | Both cases valid | all ones | nonzero |
| Denorms | Both cases valid | all zeros | nonzero |
更多特殊值見上floating-point format from Wikipedia
浮點數與其他數制的轉換
將十進制數-0.75轉換為IEEE754的單精度浮點數格式表示
(-0.75) 10 = (-0.11) 2 = (-1.1) 2 × 2-1 = (-1)s × 1.f × 2e-127
s = 1,f = 0.100…0,e = (127-1) 10 = ( 01111 1110 ) 2 ,表示為單精度浮點數格式為 1 0111 1110 1000 0000…0000 000,用十六進制表示為BF40 0000H
求IEEE754單精度浮點數C0A0 0000H的值是多少
將C0A0 0000H展開為一個32位單精度浮點數:1 10000001 010 0000…0000.
s = 1,f = (0.01) 2 = (0.25) 10 ,階碼e = (10000001) 2 = (129)10
所以其值為( -1 )s × 1.f × 2e-127 = (-1)1 × 1.25 × 2129-127 = -1.25 × 22 = -5.0
浮點數運算
五種例外情況
1.無效運算(無意義)
-運算時有一個數是非有限數,如:
加/減 ∞,0 × ∞,∞ / ∞等
-結果無效,如:
源運算元是NaN、0 / 0、x REM 0、∞ REM y等
2.除以0
結果即無限大
3.階上溢
對于float,指階碼exponent > 1111 1110,即大于127
4.階下溢
對于float,指階碼exponent < 0000 0001,即小于-126
5.結果不精確
舍入時引起的例外,如1/3、1/10等不能精確表示為浮點數
浮點數加法
設Xm、Ym分別是X和Y的尾數,Xe、Ye分別是X和Y的階碼
1.對階
對階的目的是使兩數階碼相等
小階向大階看齊,階碼小的數的尾數向右移,右移位數等于兩個階碼差的絕對值Δe = Ye - Xe,
IEEE754尾數右移時,要將隱藏的“1”移到小數部分,高位補0,移出的低位保留到特定的“附加位”上
2.尾數加減
Xm × 2^(Xe-Ye) ± Ym
3.尾數規格化
當尾數高位為0,則需左規:尾數左移一次,階碼減一,直到MSB(階碼最高位)為1
每次階碼減一后要判斷階碼是否下溢,階碼下溢則結果為0
當尾數最高位有進位,則需右規:尾數右移一次,階碼加一,直到MSB為1
每次階碼加一后要判斷階碼是否上溢,階碼上溢則結果溢位
右規最多只需要一次,因為即使是最大的兩個尾數相加(1.11…1+1.11…1),其結果也不會達到4,故尾數的整數部分最多有2位,保留一個隱含的"1"后,最多只有一位被右移到小數部分
4.舍入
如果尾數比規定數位長(有附加位),則需考慮舍入(舍入的方式有多種)
沒寫完,等我考完試
5.校驗
若運算結果尾數為0,則說明結果為0,即階碼和尾數均應為0,需要將階碼也置0.
用二進制浮點數形式計算0.5 +(-0.4375)的值
(0.5)10 = 1.000 × 2-1(大階),(-0.4375) = -1.110 × 2-2(小階)
對階: -1.110 × 2-2 → 0.111 × 2-1
加減: 1.000 × 2-1 + (-0.111 × 2-1) = 0.001 × 2-1
左規: 0.001 × 2-1 → 1.000 × 2-4
判斷溢位:否
所以結果為1.000 × 2-4 = 0.0001000 = 1/16 = 0.0625
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/246169.html
標籤:其他
