IEEE-754 64位双精度浮点数存储详解
IEEE-754雙精度浮點數
IEEE二進制浮點數算術標準(IEEE 754)規定了四種表示浮點數值的方式:單精確度(32位)、雙精確度(64位)、延伸單精確度(43比特以上,很少使用)與延伸雙精確度(79比特以上,通常以80位實現),本文介紹64位雙精度浮點數。
存儲結構
IEEE-754雙精度浮點數(double floating-point)存儲為64bit,由符號位(s)、有偏指數(e)、小數部分(f)組成:
| sign | 符號,0表示正,1表示負 | 1bit | 63 |
| exponent | 指數部分 | 11bit | 52-62 |
| fraction | 小數部分 | 52bit | 0-51 |
類型劃分
11位的指數部分可存儲00000000000 ~ 11111111111(十進制范圍為0 ~ 2047),取值可分為3種情況:
- 當52位小數部分f全為0時,若符號位是0,則表示+Infinity(正無窮),若符號位是1,則表示-Infinity(負無窮)
- 當52位小數部分f不全為0時,表示NaN(Not a Number)
規格化
規格化下,浮點數的形式可表示為:
(?1)s×1.bbb?b?f(有效52位)(ccc??53位及以后)×2e?1023(0<e<2047)(-1)^s\times1.\underbrace{bbb\cdots b}_{f(有效52位)}(\underbrace{ccc\cdots}_{53位及以后})\times2^{e-1023} \quad (0< e < 2047)(?1)s×1.f(有效52位)bbb?b??(53位及以后ccc???)×2e?1023(0<e<2047)
其中:
- s為0或1,0表示正數,1表示負數,對應1bit的符號位
- f為52位有效位,其中的每一位b是0或1,對應52bit的小數部分(不足52位補0)
- c是超出52位的部分(如果有的話,需要舍入(精度會丟失),規則下述)
- e為十進制數值,其11位的二進制數值對應11bit的指數部分
- 1023為移碼,移碼值為 2n?1?12^{n-1}-12n?1?1,這里的n表示指數位數,對于64bit的雙精度存儲,n是11
十進制中,12345可表示為1.2345×1041.2345\times10^41.2345×104;二進制中,10011可表示為1.0011×241.0011\times2^41.0011×24
先看個簡單例子,計算2.25的雙精度浮點數:
2.25轉為二進制為10.01,10.01轉為上述表示法為 1.001?f×211.\underbrace{001}_{\scriptsize{f}}\times2^11.f001??×21,可得:
- 數值為正,因此符號位是0
- 小數為001,不足52位,補0,得到
0010000000000000000000000000000000000000000000000000?001后49個0共52位\underbrace{0010000000000000000000000000000000000000000000000000}_{001后49個0\quad共52位}001后49個0共52位0010000000000000000000000000000000000000000000000000?? - 指數e-1023 = 1,則 e = 1024,二進制值為10000000000?11位\underbrace{10000000000}_{11位}11位10000000000??
綜上,將1位符號、11位指數、52位小數整合可得到2.25的雙精度浮點數表示:
0?s10000000000?e0010000000000000000000000000000000000000000000000000?f\underbrace{0}_{s}\underbrace{10000000000}_{e}\underbrace{0010000000000000000000000000000000000000000000000000}_{f}s0??e10000000000??f0010000000000000000000000000000000000000000000000000??
上述步驟反向操作可得到十進制值
上面這個例子中,小數部分不存在舍入的問題(位數小于52位),那么如果小數超出了52位,如何處理呢?有以下幾種情況:
1、第53位是0,無需處理
2、第53位是1且53位之后全是0:
- 若第52位是0,無需處理;
- 若第52位是1,那么向上舍入
3、第53位是1,且之后不全是0:那么向上舍入
再看一個例子,計算23.3的雙精度浮點數:
23.3轉為二進制為
10111.0100110011001100110011001100110011001100110011001100??1100循環10111.0100110011001100110011001100110011001100110011001100\underbrace{\cdots}_{1100循環}10111.01001100110011001100110011001100110011001100110011001100循環???
改寫為
1.0111010011001100110011001100110011001100110011001100?52位1100??1100循環×241.\underbrace{0111010011001100110011001100110011001100110011001100}_{52位}\underbrace{1100 \cdots}_{1100循環}\times2^41.52位0111010011001100110011001100110011001100110011001100??1100循環1100???×24
數值為正,因此符號位是0;指數e -1023 = 4,e = 1027 = 10000000011,因此指數部分是10000000011;小數位無限循環,53位是1且之后不全是0,符合上述規則3,因此向上舍入,第52位由0變為1,最終小數部分為:
011101001100110011001100110011001100110011001100110101110100110011001100110011001100110011001100110011010111010011001100110011001100110011001100110011001101
整合后得到23.3的雙精度浮點數表示:
0?s10000000011?e0111010011001100110011001100110011001100110011001101?f\underbrace{0}_{s}\underbrace{10000000011}_{e}\underbrace{0111010011001100110011001100110011001100110011001101}_{f}s0??e10000000011??f0111010011001100110011001100110011001100110011001101??
非規格化
非規格化可用以下形式表示(小數點前面是0):
(?1)s×0.bbb?b?f(52位)×2e?1022(e=0)(-1)^s\times0.\underbrace{bbb\cdots b}_{f(52位)}\times2^{e-1022} \quad (e=0)(?1)s×0.f(52位)bbb?b??×2e?1022(e=0)
當f=0f=0f=0(52位小數全為0)時,表示的值是0:s=0s=0s=0表示-0,s=1s=1s=1表示+0
特殊值
當e=2047e=2047e=2047(11位指數全為1)時:
- 若f>0f>0f>0,表示NaN
- 若f=0,s=0f=0,s=0f=0,s=0,表示+Infinity
- 若f=0,s=1f=0,s=1f=0,s=1,表示-Infinity
數值范圍
1、在規格化中,當指數e最大(前10位為1,11位為0,即2046)且小數f最大(52位全為1)時,能表示出最大正值,為
1.111?11?52個1×22046?1023=111?11?53個1000?00?971個01.\underbrace{111\cdots11}_{52個1}\times2^{2046 - 1023} = \underbrace{111\cdots11}_{53個1}\underbrace{000\cdots00}_{971個0}1.52個1111?11??×22046?1023=53個1111?11??971個0000?00??
轉為十進制值為1.7976931348623157e+308,則能表示的最小負值為-1.7976931348623157e+308。
2、在規格化中,當指數e最小(前10位為0,11位為1,即1)且小數f最小(52位全為0)時,能表示出最小正值,為
1.000?00?52個0×21?1023=0.000?00?1021個011.\underbrace{000\cdots00}_{52個0}\times2^{1 - 1023} = 0.\underbrace{000\cdots00}_{1021個0}11.52個0000?00??×21?1023=0.1021個0000?00??1
轉為十進制值為2.2250738585072014e-308,則能表示的最大負值為-2.2250738585072014e-308。
在非規格化中,指數e為0
1、當小數f最大(52位全為1)時,能表示出最大正值,為
0.111?11?52個1×2?1022=0.000?00?1022個0111?11?52個10.\underbrace{111\cdots11}_{52個1}\times2^{-1022} = 0.\underbrace{000\cdots00}_{1022個0}\underbrace{111\cdots11}_{52個1}0.52個1111?11??×2?1022=0.1022個0000?00??52個1111?11??
轉為十進制值為2.225073858507201e-308,則最小負值為-2.225073858507201e-308
2、當小數f最小(前51位為0,52位為1)時,能表示出最小正值,為
0.000?01?第52位為1×2?1022=0.000?00?1073個010.\underbrace{000\cdots01}_{第52位為1}\times2^{-1022} = 0.\underbrace{000\cdots00}_{1073個0}10.第52位為1000?01??×2?1022=0.1073個0000?00??1
轉為十進制值為5e-324,則最大負值為-5e-324
整數范圍(精確整數,無精度丟失)
當 e - 1023 = 52,即e = 1075,小數f最大(52位全為1)時,能表示出最大安全正整數,為
1.111?11?52個1×252=111?11?53個11.\underbrace{111\cdots11}_{52個1}\times2^{52} = \underbrace{111\cdots11}_{53個1}1.52個1111?11??×252=53個1111?11??
轉為十進制值為253?12^{53}-1253?1 = 9007199254740991,則能表示的最小安全負整數為-9007199254740991
總結
1、javascript中的數值統一采用IEEE-754雙精度存儲,因此在計算時可能出現精度丟失,導致奇怪的結果,如 0.1 + 0.2 !== 0.3
2、下表列出了IEEE-754中的數值邊界值,其中某些值對應javascript中的數值常量
| 規格化 | -1.7976931348623157e+308 | -2.2250738585072014e-308 | 2.2250738585072014e-308 | 1.7976931348623157e+308(Number.MAX_VALUE) | -9007199254740991(Number.MIN_SAFE_INTEGER) | 9007199254740991(Number.MAX_SAFE_INTEGER) |
| 非規格化 | -2.225073858507201e-308 | -5e-324 | 5e-324(Number.MIN_VALUE) | 2.225073858507201e-308 | x | x |
IEEE 754可以表示的數值范圍是:
[?1.7976931348623157×10308,?5×10?324]∪[5×10?324,1.7976931348623157×10308][-1.7976931348623157\times10^{308},-5\times10^{-324}] \cup [5\times10^{-324},1.7976931348623157\times10^{308}][?1.7976931348623157×10308,?5×10?324]∪[5×10?324,1.7976931348623157×10308]
超過1.7976931348623157e+308為Infinity,小于-1.7976931348623157e+308為-Infinity,在(-5e-324,5e-324)之間的數顯示為0
總結
以上是生活随笔為你收集整理的IEEE-754 64位双精度浮点数存储详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 10bit色深灰度图彩色图加载显示
- 下一篇: wps高亮怎么取消_一组WPS表格小技巧