1、概述
如何使用8個字節表示特定的數字(整數或小數),其中要滿足精度足夠高,和表示的數字儘可能的大。聰明的你肯定想到使用科學計數法來表示,其中64位中,需要包含確定正負的符號位(1比特),確定數字大小的指數位(11比特)和確定數字精度的尾數位(52比特)。這就是IEEE-754雙精度浮點數的基本內容,但在規範實現上有更多的定義。
1、符號位使用s(sign)表示,0是正數、1爲負數;
2、指數位 E(Exponent)爲11位,指數可以爲正數,也可以爲負數。爲了處理負指數的情況,實際的指數值按規範需要加上一個偏置(Bias)值(1023)作爲保存在指數段中的值;
3、有效數字位 M(Significand)是二進制小數,共52位。表示小數點後的部分,整數部分永遠爲 1,計算機不存儲,但是運算的時候會加上1。
2、數字表示
2.1、十進制1024的表示:
(1024).toString(2) //1024 使用二進制表示爲: '10000000000'
進一步可寫爲:1 * 2^10。由於尾數位不存儲1,所以尾部位全爲0,指數爲 10 + 1023, 爲1033,二進制爲'10000001001',符號位爲0,因此整體格式爲:
2.2、浮點數3.141592654的表示:
(3.141592654).toString(2) // 轉換直接使用JavaScript提供的api
'11.00100100001111110110101010001010010010001010101'
小數點往前挪一位,寫成科學計數法,尾數位爲: 100100100001111110110101010001010010010001010101 (1不儲存)指數位爲1 + 1023 = 1024 符號位爲0
3、特殊值:
JavaScript的Number 類型擁有幾種特殊類型,+-Infinity、NaN、Number.MAX_VALUE、Number.MAX_SAFE_INTEGER。
3.1、Infinity 表示無窮大小,在IEEE754中的表示爲:即指數位全爲1,尾數位全爲0,符號位爲1 表示 -Infinity
3.2、NaN 當指數位全爲 1 時,尾數位爲非零時,結果值就被稱爲“NaN”(Not any Number)
3.3、 Number.MAX_VALUE 爲 IEEE -754規範中能表示的最大值,很顯然尾數爲最大,且避開Infinity 定義(比Infinity小1)和NaN的定義,即能表示的最大值。
在JavaScript中:
Number.MAX_VALUE
1.7976931348623157e+308
3.4、Number.MAX_SAFE_INTEGER 爲最大能安全表示的值,超過該數會丟失精度,無法進行安全計算。數值爲 2^53 -1;
由於儲存精度的位數是固定的,比最大值大1時,指數位進位,尾數位歸0,比最大值大2時,尾數位還是全部爲0,向偶舍入的規則導致尾數位不會進位。
4、問題:
最大值與Number.MAX_VALUE 與 Infinity 差多少?
由於Infinity 無法參與計算,直接減是不可以的。而且之間的差值顯然不是1 。還是由於計算精度的問題,看一下MAX_VALUE 、Infinity 兩個數字之間的表示,順序如下:
顯然尾數位再進一位,即達到INfinity值。但這個值是多少呢?
要讓 Number.MAX_VALUE 變成 Infinity , 至少要加上一個被 IEEE754四捨五入爲 2**970 的數。
參考鏈接:
JS 中的 MAX_VALUE 和 MAX_SAFE_INTEGER 是怎麼來的
爲什麼在js中Number.MAX_VALUE + 1不是Infinity?
http://bartaz.github.io/ieee754-visualization/
http://c.biancheng.net/view/314.html