首頁  >  文章  >  web前端  >  跟我學習javascript的浮點數精確度_javascript技巧

跟我學習javascript的浮點數精確度_javascript技巧

WBOY
WBOY原創
2016-05-16 15:32:19911瀏覽

大多數程式語言都有幾種數值型資料型別,但是JavaScript卻只有一種。你可以使用typeof 運算子查看數字的類型。不管是整數還是浮點數,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中缺少明顯的整數類型,但完全可以進行整數運算。
大多數的算術運算子可以使用整數、實數或兩者的組合來計算。

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的補碼表示的整數。)以位元或運算表達式為例:

8|1; //9

看似簡單的表達式其實需要幾個步驟來完成運算。如前所述,JavaScript中的數字8和1都是雙精確度浮點數。但是它們也可以表示成32位元整數,也就是32位元0、1的序列。整數8表示為32位元二進位序列如下所示:

0000000000000000000000000001000

你自己也可以使用數字類型的toString方法來查看:

(8).toString(2)  //"1000"

toString方法的參數指定了其轉換基數,此範例以基數2(即二進位)表示。結果值省略了左端多餘的0(位元),因為它們不會影響最終值。
整數1表示為32位元二進位如下所示:

0000000000000000000000000000001

以位元或運算表達式合併兩個位元序列。只要參與運算的兩位位元中任一位為1,運算結果的位元就為1。以位元模式表示的結果如下:

0000000000000000000000000001001

這個序列表示整數9。你可以使用標準的函式庫函數parseInt驗證,同樣以2作為基數:

parseInt("1000", 2); //9

(同樣,前導0位是不必要的,因為它們不會影響運算結果。)
所有位元運算子的工作方式都是相同的。它們將運算元轉換為整數,然後使用整數位元模式進行運算,最後將結果轉換為標準的JavaScript浮點數。一般情況下,JavaScript引擎需要做些額外的工作來進行這些轉換。因為數字是以浮點數儲存的,必須將其轉換為整數,然後再轉換回浮點數。然而,在某些情況下,算術表達式甚至變數只能使用整數參與運算,優化編譯器有時可以推斷出這些情況而在內部將數字以整數的方式儲存以避免多餘的轉換。

關於浮點數的最​​後警告是,你應該對它們保持時刻警惕。浮點數看似熟悉,但是它們是出了名的不精確。甚至一些看起來最簡單的算術運算都會產生不正確的結果。

0.1 0.2; 0.300000000000004

儘管64位的精度已經相當高了,但是雙精度浮點數也只能表示一組有限的數字,而不能表示所有的實數集。浮點運算只能產生近似的結果,四捨五入到最接近的可表示的實數。當你執行一連串的運算,隨著捨入誤差的積累,運算結果會越來越不精確。舍入也會使我們通常所期望的算術運算定律產生一些出人意料的偏差。例如,實數滿足結合律,這意味著,對於任意的實數x,y,z,總是滿足(x y) z = x (y z)。

然而,對於浮點數來說,卻並不總是這樣。

(0.1+0.2)+0.3; //0.60000000000000001
0.1+(0.2+ 0.3); //0.6

浮點數權衡了精度和性能。當我們關心精確度時,要小心浮點數的限制。一個有效的解決方法是盡可能地採用整數值運算,因為整數在表示時不需要捨去。當進行貨幣相關的計算時,程式設計師通常會按比例將數值轉換為最小的貨幣單位來表示再進行計算,這樣就可以以整數進行計算。例如,如果上面的計算是以美元為單位,那麼,我們可以將其轉換為整數表示的美分進行計算。

(10+20)+30; //60
10+ (20+30); //60

對於整數運算,你不必擔心捨入誤差,但是你還是要當心所有的計算只適用於–253~253的整數。

提示

  • JavaScript的數字都是雙精確度的浮點數。
  • JavaScript中的整數只是雙精確度浮點數的一個子集,而不是一個單獨的資料型別
  • 位元運算子將數字視為32位元的有符號整數。

以上就是介紹的javascript的浮點數,我們要時時注意浮點運算中的精確度陷阱,希望這篇文章對大家的學習有所幫助。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn