javascript浮點數計算精度問題介紹
大多數程式語言都有幾種數值型資料型別,但是javascript卻只有一種。你可以使用typeof 運算子檢視數字的型別。
不管是整數還是浮點數,javascript都將它們簡單地歸類為數字。
[JavaScript] 純文字檢視 複製程式碼typeof 17; //number typeof 98.6; //number typeof -21.3; //number
事實上,javascript中所有的數字都是雙精度浮點數。這是由IEEE754標準制定的64位編碼數字——即“doubles”。
如果這一事實使你疑惑javascript是如何表示整數的,記住,雙精度浮點數能完美地表示高達53位精度的整數。
從–9 007 199 254 740 992(–253)到9 007 199 254 740 992(253)的所有整數都是有效的雙精度浮點數。
因此,儘管JavaScript中缺少明顯的整數型別,但是完全可以進行整數運算。
大多數的算術運算子可以使用整數、實數或兩者的組合進行計算。
[JavaScript] 純文字檢視 複製程式碼0.1 * 0.9; //0.19 -99 + 100; //1 21- 12.3; //8.7 2.5 /5; //0.5 21%8; //5
然而位算術運算子比較特殊。javascript不會直接將運算元作為浮點數進行運算,而是會將其隱式地轉換為32位整數後進行運算。(確切地說,它們被轉換為32位大端(big-endian)的2的補碼錶示的整數。)以按位或運算表示式為例:
[JavaScript] 純文字檢視 複製程式碼8|1; //9
看似簡單的表示式實際上需要幾個步驟來完成運算。如前所述,javascript中的數字8和1都是雙精度浮點數。但是它們也可以表示成32位整數,即32位0、1的序列。整數8表示為32位二進位制序列如下所示:
[JavaScript] 純文字檢視 複製程式碼00000000000000000000000000001000
自己也可以使用數字型別的toString方法來檢視:
[JavaScript] 純文字檢視 複製程式碼(8).toString(2) //"1000"
toString方法的引數指定了其轉換基數,此例子以基數2(即二進位制)表示。結果值省略了左端多餘的0(位),因為它們並不影響最終值。
整數1表示為32位二進位制如下所示:
[JavaScript] 純文字檢視 複製程式碼00000000000000000000000000000001
按位或運算表示式合併兩個位元序列。只要參與運算的兩位位元中任意一位為1,運算結果的該位就為1。以位模式表示的結果如下:
[JavaScript] 純文字檢視 複製程式碼00000000000000000000000000001001
這個序列表示整數9。你可以使用標準的庫函式parseInt驗證,同樣以2作為基數:
[JavaScript] 純文字檢視 複製程式碼parseInt("1000", 2); //9
(同樣,前導0位是不必要的,因為它們並不影響運算結果。)
所有位運算子的工作方式都是相同的。它們將運算元轉換為整數,然後使用整數位模式進行運算,最後將結果轉換為標準的javascript浮點數。一般情況下,javascript引擎需要做些額外的工作來進行這些轉換。因為數字是以浮點數儲存的,必須將其轉換為整數,然後再轉換回浮點數。然而,在某些情況下,算術表示式甚至變數只能使用整數參與運算,優化編譯器有時候可以推斷出這些情形而在內部將數字以整數的方式儲存以避免多餘的轉換。
關於浮點數的最後警示是,你應該對它們保持時刻警惕。浮點數看似熟悉,但是它們是出了名的不精確。甚至一些看起來最簡單的算術運算都會產生不正確的結果。
[JavaScript] 純文字檢視 複製程式碼0.1+0.2; 0.300000000000004
儘管64位的精度已經相當高了,但是雙精度浮點數也只能表示一組有限的數字,而不能表示所有的實數集。浮點運算只能產生近似的結果,四捨五入到最接近的可表示的實數。當你執行一系列的運算,隨著舍入誤差的積累,運算結果會越來越不精確。舍入也會使我們通常所期望的算術運算定律產生一些出人意料的偏差。例如,實數滿足結合律,這意味著,對於任意的實數x,y,z,總是滿足(x + y) + z = x + (y + z)。
然而,對於浮點數來說,卻並不總是這樣。
[JavaScript] 純文字檢視 複製程式碼(0.1+0.2)+0.3; //0.60000000000000001 0.1+(0.2+ 0.3); //0.6
浮點數權衡了精度和效能。當我們關心精度時,要小心浮點數的侷限性。一個有效的解決方法是儘可能地採用整數值運算,因為整數在表示時不需要舍入。當進行貨幣相關的計算時,程式設計師通常會按比例將數值轉換為最小的貨幣單位來表示再進行計算,這樣就可以以整數進行計算。例如,如果上面的計算是以美元為單位,那麼,我們可以將其轉換為整數表示的美分進行計算。
[JavaScript] 純文字檢視 複製程式碼(10+20)+30; //60 10+ (20+30); //60
對於整數運算,你不必擔心舍入誤差,但是你還是要當心所有的計算只適用於–253~253的整數。
特別說明:
[JavaScript] 純文字檢視 複製程式碼JavaScript的數字都是雙精度的浮點數。 JavaScript中的整數僅僅是雙精度浮點數的一個子集,而不是一個單獨的資料型別 位運算子將數字視為32位的有符號整數。
相關文章
- JavaScript解決浮點數算數運算精度問題JavaScript
- iOS浮點數精度問題iOS
- JS中浮點數精度問題JS
- 關於JS的浮點數計算精度問題解決方案JS
- JavaScript 浮點數及運算精度調整總結JavaScript
- [Java] 浮點數的精度丟失問題與精度控制方法Java
- 一個浮點數計算的問題
- 【求教:如何解決 java 浮點數精度問題】Java
- JavaScript 小數乘法運算精度問題JavaScript
- javascript將浮點數數變為整數簡單介紹JavaScript
- Java浮點數float,bigdecimal和double精確計算的精度誤差問題總結JavaDecimal
- WebGL著色器32位浮點數精度損失問題Web
- 精度計算問題
- javascript浮點數精確計算程式碼JavaScript
- javascript小數乘法運算導致的精度問題JavaScript
- JavaScript浮點數加減乘除精確計算JavaScript
- Java浮點數計算Java
- php 處理 浮點數 精度運算 數字處理等PHP
- JavaScript中解決計算精度丟失的問題JavaScript
- 你不知道的JavaScript--Item2 浮點數精度JavaScript
- Golang浮點數精度丟失問題擴充套件包解決方案Golang套件
- 全面總結 JS 中浮點數運算問題JS
- js算數運算精度問題解決方案JS
- js浮點數丟失問題JS
- js浮點數儲存精度丟失原理JS
- js中浮點數計算常用方法JS
- js精確計算浮點數相加JS
- 浮點數線上轉hex計算工具
- javascript如何解決浮點數相乘出現誤差問題JavaScript
- 浮點運算簡介 (轉)
- js處理浮點數計算誤差JS
- PHP浮點數的精確計算BCMathPHP
- java浮點型別案例介紹Java型別
- JavaScript 浮點數陷阱及解法JavaScript
- LibBF——處理任意精度浮點數的小型庫
- 計算機組成原理浮點數加減計算機
- JavaScript浮點數保留兩位小數JavaScript
- 關於javascript中對浮點加,減,乘,除的精度分析JavaScript