摘要:標(biāo)準(zhǔn)是浮點數(shù)算術(shù)標(biāo)準(zhǔn)的標(biāo)準(zhǔn)編號,等同于國際標(biāo)準(zhǔn)。標(biāo)準(zhǔn)規(guī)定了計算機程序設(shè)計環(huán)境中的二進制和十進制的浮點數(shù)之間的交換算術(shù)格式以及方法。
初學(xué)JavaScript,在進行小數(shù)(浮點數(shù))運算時,經(jīng)常會碰到這樣的情況:0.1 + 0.2=0.30000000000000004,記得當(dāng)時,教程告訴我們說,0.1 + 0.2在JavaScript運算中,它的值是不固定的,可以在后面學(xué)習(xí)和試驗中,漸漸發(fā)現(xiàn),這個值似乎每次都是0.30000000000000004,于是漸漸懷疑當(dāng)時學(xué)習(xí)過程中關(guān)于它的和值是不固定的說法。
其實有一定編程基礎(chǔ)的同學(xué)們應(yīng)該都知道,計算機是采用二進制來表示十進制的,規(guī)則是:整數(shù)除以2,商繼續(xù)除以2,得到0為止,將余數(shù)逆序排列;小數(shù)乘以2,取整,小數(shù)部分繼續(xù)乘以2,取整,得到小數(shù)部分0為止,將整數(shù)順序排列。例如:
其實不管是十進制轉(zhuǎn)二進制還是八進制、十六進制,原理都是一樣的,即,基數(shù)連連除(整數(shù))或者連乘(小數(shù))
再回到我們最初的問題, JS 采用 IEEE 754 雙精度版本(64位),并且只要采用 IEEE 754 的語言都有前面的問題。
IEEE 754 標(biāo)準(zhǔn)是IEEE浮點數(shù)算術(shù)標(biāo)準(zhǔn)(IEEE Standard for Floating-Point Arithmetic)的標(biāo)準(zhǔn)編號 ,等同于國際標(biāo)準(zhǔn)ISO/IEC/IEEE 60559 。IEEE 754 標(biāo)準(zhǔn)規(guī)定了計算機程序設(shè)計環(huán)境中的二進制和十進制的浮點數(shù)之間的交換、算術(shù)格式以及方法 。
根據(jù)前面介紹的知識,0.1 的二進制表示為:
0.1 = 2^-4 * 1.10011(0011)// (0011) 表示循環(huán)
0.2 的二進制表示為:
0.2 = 2^-3 * 1.10011(0011)// (0011) 表示循環(huán)
前面說了,JS 采用 IEEE 754 雙精度版本(64位),六十四位中符號位占一位,整數(shù)位占十一位,其余五十二位都為小數(shù)位。因為 0.1 和 0.2 都是無限循環(huán)的二進制,所以在小數(shù)位末尾處需要判斷是否進位(規(guī)則和十進制里的四舍五入一樣)。
所以 0.1的二進制表示(0.1 = 2^-4 * 1.10011(0011)) 進位后就變成了 2^-4 * 1.10011(0011 * 12次)010,同理可得0.2的二進制表示 。把這兩個二進制加起來得到 2^-2 * 1.0011(0011 * 11次)0100 , 這個值再換算成十進制就是 0.30000000000000004。
所以說,0.1 + 0.2=0.30000000000000004,在JavaScript中,它的結(jié)果并非不固定的。
那么,如果需要比較0.1 + 0.2和0.3的關(guān)系,我們又該如何進行呢?
其實對于在大學(xué)學(xué)過數(shù)學(xué)分析、數(shù)值逼近或者高中課程代數(shù)方面證明知識的同學(xué)來說,自然可以想到讓0.1 + 0.2的和減去0.3小于一個任意小的數(shù),比如說我們可以通過他們差值是否小于0.0000000001來判斷他們是否相等。JavaScript也提供了一些原生的方法,比如toFixed() 方法可把 Number 四舍五入為指定小數(shù)位數(shù)的數(shù)字,語法:NumberObject.toFixed(num)
參數(shù)描述:num,必需。規(guī)定小數(shù)的位數(shù),是 0 ~ 20 之間的值,包括 0 和 20,有些實現(xiàn)可以支持更大的數(shù)值范圍。如果省略了該參數(shù),將用 0 代替。
參考內(nèi)容:JavaScript toFixed() 方法
幾道高級前端面試題解析
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/95315.html
摘要:又如,對于,結(jié)果其實并不是,但是最接近真實結(jié)果的數(shù),比其它任何浮點數(shù)都更接近。許多語言也就直接顯示結(jié)果為了,而不展示一個浮點數(shù)的真實結(jié)果了。小結(jié)本文主要介紹了浮點數(shù)計算問題,簡單回答了為什么以及怎么辦兩個問題為什么不等于。 原文地址:為什么0.1+0.2不等于0.3 先看兩個簡單但詭異的代碼: 0.1 + 0.2 > 0.3 // true 0.1 * 0.1 = 0.01000000...
摘要:按照的數(shù)字格式,整數(shù)有的范圍是,而且只能表示有限個浮點數(shù),能表示的個數(shù)為個。 0.1+0.2 等于0.3嗎?相信拿著這條題目隨便問一個高年級的小學(xué)生,他們都會毫不猶豫都回答:相等。是的,相等是正常的,這是常識。但是都說實踐是檢驗真理的唯一標(biāo)準(zhǔn),拿這道簡單的算術(shù)題用javascript在chrome控制臺試驗一下: 結(jié)果令人大跌眼鏡,在控制臺輸入0.1+0.2 == 0.3返回的結(jié)果竟然...
摘要:因此利用以及語法樹在代碼構(gòu)建過程中重寫等符號,開發(fā)時直接以這樣的形式編寫代碼,在構(gòu)建過程中編譯成,從而在開發(fā)人員無感知的情況下解決計算失精的問題,提升代碼的可讀性。 前言 你了解過0.1+0.2到底等于多少嗎?那0.1+0.7,0.8-0.2呢? 類似于這種問題現(xiàn)在已經(jīng)有了很多的解決方案,無論引入外部庫或者是自己定義計算函數(shù)最終的目的都是利用函數(shù)去代替計算。例如一個漲跌幅百分比的一個...
摘要:也就是說不僅是會產(chǎn)生這種問題,只要是采用的浮點數(shù)編碼方式來表示浮點數(shù)時,則會產(chǎn)生這類問題。到這里我們都理解只要采取的浮點數(shù)編碼的語言均會出現(xiàn)上述問題,只是它們的標(biāo)準(zhǔn)類庫已經(jīng)為我們提供了解決方案而已。 Brief 一天有個朋友問我JS中計算0.7 * 180怎么會等于125.99999999998,坑也太多了吧!那時我猜測是二進制表示數(shù)值時發(fā)生round-off error所導(dǎo)致,但并不...
閱讀 3295·2021-11-22 15:25
閱讀 4050·2021-11-17 09:33
閱讀 3496·2021-11-08 13:15
閱讀 3190·2021-09-22 10:56
閱讀 687·2021-08-31 09:45
閱讀 2912·2019-08-30 13:49
閱讀 3273·2019-08-30 12:52
閱讀 1268·2019-08-29 17:05