常常使用JavaScript用來處理數字的程序員都知道,JavaScript的Number.toFixed
,這一函數,在格式化數字時,會自動進行四捨五入,例如:javascript
10.125.toFixed(2) ---> "10.13"
可是在某些狀況下,其四捨五入的結果,每每都不盡人意,例如:java
10.145.toFixed(2) ---> "10.14"
那爲什麼爲出現上述這種狀況,須要從進制談起。git
衆所周知,計算機在設計之初,出於各方面角度考慮,最終採用二進制的格式來存儲數據。而咱們平時對於數字所慣用的進制是十進制。用二進制的格式來存儲十進制的數據,必然會面臨進制的轉換,進制的轉換就會面臨精度的丟失。程序員
例如,對於⅓,對於三進制的數來講是0.1,而對於十進制來講,是0.333(3循環)。那對於三個⅓相加,對於三進制來講,就是一(逢三進一),而對於十進制來講,就是0.999(9循環)。github
一樣的狀況,也會出如今十進制和二進制的轉換中。當咱們在計算機中,聲明一個變量爲10.145,其實該數字做爲二進制保存在計算機中,並不真的是10.145。能夠經過Number.prototype.toPrecision
方法來一探究竟。函數
Number.prototype.toPrecision
方法以指定的精度返回該數值對象的字符串表示。spa
10.145.toPrecision(21) ---> "10.1449999999999995737"
所以就能夠解釋,爲何toFixed()
方法返回的四捨五入的值,在某些狀況不符合預料。prototype
一樣,也告訴你們,浮點數的全部計算,加減乘除無一例外,在某些狀況下,都會出現不符合預料的狀況,最多見的如0.1+0.2
,等等。設計
針對上述狀況,我寫了一個簡單的庫,能夠知足數字的四捨五入需求。round-jscode
和大部分語言不一樣,JavaScript目前對於數字的表示,只有一種類型,即Number,採用64位雙精度浮點數來表示一個數,其標準與大多數語言同樣,採用IEEE-754標準。IEEE-754下64位雙精度浮點數的標準,能夠用一張圖來表示,以下:
sign:表明符號,用1位來表示,即正數負數,1表明正數,0表明負數;
exponent:表明指數,底數爲2,用11位來表述;
fraction:真正的有效數字,用52位來表示。
最終,任何一個數,對於該標準,都使用以下公式來表示得出:
其中:
V:結果
S:上面的sign
M:有效數字fraction
E:上面的exponent
能夠看出,這個表示方法,相似十進制中的科學計數法。
對於這些概念,IEEE-754標準中還有許多規定,例如<1M<2
,等等,更多細節就不展開了。
完。