掘金搬來思否
浮點數的存儲格式:IEEE754-64bit
64位組成格式爲:S(1位符號位) E(11位階碼)M(52位尾數)
- 符號位:決定正負,0位正,1位負
- 階碼:指數位則爲階碼-1023,決定了數值的大小
- 尾數:有效數字,決定了精度
- 用科學計數法格式則爲:(-1^(符號位0/1)) 1.xxxxx(尾數位) 2^(指數位)
須要記住的IEEE754規範有:
- 尾數位:有效數字的第一位一定是1,因此這個1不會被儲存,也就是說實際上尾數位52+1,相似1.xxx第一位就是1。
- 階碼:不存在負值,那怎麼表示負指數呢?就是減去一個固定值;其值就是1023,也就是偏移量1023;除去全是1和全是0的狀況,那麼指數位的範圍則是[(1-1023),(2046-1023)] == [-1022,1023]。
- 當階碼全位0,尾數全爲0時,採起非規格化,二者不包含隱含的1,用來表示0。
- 最簡單的精度算法就是:2^53是16位十進制,因此15位確定能精確處理。
- 固然還有不少,有興趣能夠自行查閱一下。
知道了這些,就能更好的理解一些數值的由來:
Number.MAX_VALUE = 1.7976931348623157e+308;
尾數:1.xxx1,後面爲52個1,
要獲得最大值,咱們就須要把小數點日後移,就靠指數1023-52,剩餘971;
所以最大值等價於((Math.pow(2,53)-1)*Math.pow(2,971))
Number.MIN_VALUE =5e-324;
尾數:1.xxxx1,後面第52位爲1,其他爲0,這時首位的1須要隱藏,
這時候就是負了52位,在加上2^-1022,
等價於((Math.pow(2,-52))*Math.pow(2,-1022))
Number.MAX_SAFE_INTEGER = 9007199254740991;
安全數就是可以精確處理的,精度靠尾數決定,
那咱們來看當1.1111...1,小數點後接52個1,這是精度最大顯示,
要取其最大值那就是向指數借52位,因此最大安全數就等於Math.pow(2,53)-1
同理Number.MIN_SAFE_INTEGER = -9007199254740991;
對最大安全數添加負號便可
重點0.1 + 0.2 怎麼計算的呢?
首先,0.1轉二進制 :0.0 001100110011001100110011..0011 0011,
改寫爲科學計數法表示:1.100110011...0011(0011)*2^-4,
尾數位爲52爲須要取捨括號中最後一位捨去進1,指數爲-4,那個階碼就是-4+1023=1019,
最終浮點數格式:
0-01111111011-1001100110011001100110011001100110011001100110011010
同理0.2能夠表示爲:
0-01111111100-1001100110011001100110011001100110011001100110011010
最後二者相加結果爲:
0-01111111101-0011001100110011001100110011001100110011001100110100,
指數位爲-2,
1.00110011001100110011001100110011001100110011001101(00)*2^-2
因此二進制表示:
0.0100110011001100110011001100110011001100110011001101(00),
那麼轉爲十進制就是0.1 + 0.2 = 0.30000000000000004 != 0.3