成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

深度剖析0.1 +0.2===0.30000000000000004的原因

haobowd / 605人閱讀

摘要:吐槽一句,大二的專業(yè)課數(shù)字邏輯電路終于用在工作上了。,整數(shù)位為,且精度只到十分位,因此是。如果是不限精度的話,轉(zhuǎn)換后的二進(jìn)制數(shù)應(yīng)該是無(wú)限循環(huán)。再看一下百科給出的標(biāo)準(zhǔn)因此,的類型,最高的位是符號(hào)位,接著的位是指數(shù),剩下的位為有效數(shù)字。

用一句話概括就是:
EcmaScrpt規(guī)范定義Number的類型遵循了IEEE754-2008中的64位浮點(diǎn)數(shù)規(guī)則定義的小數(shù)后的有效位數(shù)至多為52位導(dǎo)致計(jì)算出現(xiàn)精度丟失問題!

如果你看不懂這句話,仔細(xì)閱讀本篇博客就對(duì)了!

首先看下10進(jìn)制轉(zhuǎn)換為2進(jìn)制的方法。

數(shù)字邏輯電路上的算法是 (0.1)10 = (0.0)2。

吐槽一句,大二的專業(yè)課數(shù)字邏輯電路終于用在工作上了。

0.1*2 = 0.2 ,整數(shù)位為0,且精度只到十分位,因此是0.0。

如果是不限精度的話,轉(zhuǎn)換后的二進(jìn)制數(shù)應(yīng)該是:0.000110011001100110011(0011)無(wú)限循環(huán)。

如果表示成一個(gè)奇怪的形式,則是 (-1)^0*1.100110011(0011)* 2^-4

上述式子可類比十進(jìn)制科學(xué)計(jì)數(shù)法公式。

0.0001234567 = 1.234567 * 10^-4?

為什么要這樣表示?

-1的0次冪又是什么意思?

這是國(guó)際標(biāo)準(zhǔn)組織IEEE754對(duì)于浮點(diǎn)數(shù)表示方式的一種定義。

格式為;

(-1)^S x Mx 2^E

各符號(hào)的意思如下:
S,是符號(hào)位,決定正負(fù),0時(shí)為正數(shù),1時(shí)為負(fù)數(shù)。
M,是指有效位數(shù),大于1小于2?!?br>E,是指數(shù)位。

因此才有了下面的形式:

(-1)^0*1.100110011(無(wú)限循環(huán)0011) * 2^-4
S = 0,M = 1.100110011(無(wú)限循環(huán)0011),E =-4

對(duì)應(yīng)的0.2為:

(-1)^0*1.100110011(無(wú)限循環(huán)0011) * 2^-3
S = 0 ,M = 1.100110011(無(wú)限循環(huán)0011),E =-3

那么這和javascript有什么關(guān)系呢?

因?yàn)镮EEE754標(biāo)準(zhǔn)里,還有兩種特殊的定義。

IEEE 754規(guī)定,對(duì)于32位的浮點(diǎn)數(shù),最高的1位是符號(hào)位S,接著的8位是指數(shù)E,剩下的23位為有效數(shù)字M。

對(duì)于64位的浮點(diǎn)數(shù),最高的1位是符號(hào)位S,接著的11位是指數(shù)E,剩下的52位為有效數(shù)字M。

問題還是一樣,這和我們的javascript有什么關(guān)系呢?

因?yàn)閖avascript中Number類型,就是嚴(yán)格按照IEEE754標(biāo)準(zhǔn)來定義的。下面給出了最新版的ecma-262版本中關(guān)于Number類型的定義。

*6.1.6
The Number Type**
The Number type has exactly 18437736874454810627 (that is,?) values, representing the double-precision 64-bit format IEEE 754-2008 values as specified in the IEEE Standard for Binary Floating-Point Arithmetic, except that the 9007199254740990 (that is,?) distinct “Not-a-Number” values of the IEEE Standard are represented in ECMAScript as a single special??value.

再看一下wiki百科給出的IEEE754標(biāo)準(zhǔn):

因此,javascript的Number類型, 最高的1位是符號(hào)位S,接著的11位是指數(shù)E,剩下的52位為有效數(shù)字M。

拿0.1舉例來說:

(-1)^01.100110011(無(wú)限循環(huán)0011) 2^-4

= 0,M = 1.100110011(無(wú)限循環(huán)0011),E =-4

這里的無(wú)限循環(huán)就有限了,循環(huán)位數(shù)最多只能有52位.

JS中的0.1,在引擎中運(yùn)算時(shí),實(shí)質(zhì)上會(huì)編譯成:

1.1001100110011001100110011001100110011001100110011001*2^-4

0.2同理,會(huì)編譯成:

1.1001100110011001100110011001100110011001100110011001*2^- 3

拿出關(guān)鍵的指數(shù)部分和有效位部分:

-4??0.1001100110011001100110011001100110011001100110011001 ①

-3 ?0.1001100110011001100110011001100110011001100110011001 ②·

①式轉(zhuǎn)化為純小數(shù),小數(shù)最低位的1001被高位的0000擠出有效范圍,得到③式

②式轉(zhuǎn)化為純小數(shù),小數(shù)最低位的001被高位的000擠出有效范圍,得到④式

原因是什么?

原因就是JS中的Number類型,二進(jìn)制小數(shù)的有效位數(shù)只有52位,從0到51位(包括邊界)。

在chrome控制臺(tái)輸入(0.1).toString("2")并打印結(jié)果為:"0.0001100110011001100110011001100110011001100110011001101"

不多不少,小數(shù)部分剛好52位,與規(guī)范以及我們的猜想完全契合。

回到0.1+0.2===0.30000000000000004這個(gè)經(jīng)典問題。

在EcmaScript中,無(wú)關(guān)Browser環(huán)境,還是Nodejs環(huán)境,0.1+0.2的實(shí)際計(jì)算過程如下:

? ?? 0.0000100110011001100110011001100110011001100110011001 ③

? ? +0.0001001100110011001100110011001100110011001100110011 ④

---------------------------------------------------------------------------------------------------

? ? =0.0100110011001100110011001100110011001100110011001100 ⑤

最后得到的⑤式其實(shí)0.300000000000000004(17位十進(jìn)制數(shù))的二進(jìn)制形式。

這就是0.1+0.2 ===0.300000000000000004的原因。

雖然我們期望的理想結(jié)果是返回0.3,恰恰印證了現(xiàn)實(shí)往往很骨感的說法。

有沒有讓0.1+02返回為0.3的辦法呢?

因?yàn)椴恢皇沁@一個(gè)精度丟失特例,還有很多情況都會(huì)造成精度丟失,比如:

0.3 / 0.1===2.9999999999999996以及0.7 * 180==125.99999999998等等。

那么有沒有辦法解決這個(gè)問題呢?

移步下一篇博客:如何解決0.1 +0.2===0.30000000000000004類問題

鳴謝單位:

https://segmentfault.com/a/1190000005022170

http://demon.tw/copy-paste/javascript-precision.html

http://www.ruanyifeng.com/blog/2010/06/ieee_floating-point_representation.html

http://www.css88.com/archives/7340#more-7340

http://www.ecma-international.org/ecma-262/8.0/index.html

https://en.wikipedia.org/wiki/Floating-point_arithmetic#Internal_representation

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/89591.html

相關(guān)文章

  • 如何解決0.1 +0.2===0.30000000000000004類問題

    摘要:方法使用定點(diǎn)表示法來格式化一個(gè)數(shù),會(huì)對(duì)結(jié)果進(jìn)行四舍五入。該數(shù)值在必要時(shí)進(jìn)行四舍五入,另外在必要時(shí)會(huì)用來填充小數(shù)部分,以便小數(shù)部分有指定的位數(shù)。如果數(shù)值大于,該方法會(huì)簡(jiǎn)單調(diào)用并返回一個(gè)指數(shù)記數(shù)法格式的字符串。在環(huán)境中,只能是之間,測(cè)試版本為。 showImg(https://segmentfault.com/img/remote/1460000011913134?w=768&h=521)...

    yuanzhanghu 評(píng)論0 收藏0
  • JavasScript重難點(diǎn)知識(shí)

    摘要:忍者級(jí)別的函數(shù)操作對(duì)于什么是匿名函數(shù),這里就不做過多介紹了。我們需要知道的是,對(duì)于而言,匿名函數(shù)是一個(gè)很重要且具有邏輯性的特性。通常,匿名函數(shù)的使用情況是創(chuàng)建一個(gè)供以后使用的函數(shù)。 JS 中的遞歸 遞歸, 遞歸基礎(chǔ), 斐波那契數(shù)列, 使用遞歸方式深拷貝, 自定義事件添加 這一次,徹底弄懂 JavaScript 執(zhí)行機(jī)制 本文的目的就是要保證你徹底弄懂javascript的執(zhí)行機(jī)制,如果...

    forsigner 評(píng)論0 收藏0
  • 利用babel(AST)優(yōu)雅地解決0.1+0.2!=0.3問題

    摘要:因此利用以及語(yǔ)法樹在代碼構(gòu)建過程中重寫等符號(hào),開發(fā)時(shí)直接以這樣的形式編寫代碼,在構(gòu)建過程中編譯成,從而在開發(fā)人員無(wú)感知的情況下解決計(jì)算失精的問題,提升代碼的可讀性。 前言 你了解過0.1+0.2到底等于多少嗎?那0.1+0.7,0.8-0.2呢? 類似于這種問題現(xiàn)在已經(jīng)有了很多的解決方案,無(wú)論引入外部庫(kù)或者是自己定義計(jì)算函數(shù)最終的目的都是利用函數(shù)去代替計(jì)算。例如一個(gè)漲跌幅百分比的一個(gè)...

    張巨偉 評(píng)論0 收藏0
  • TensorFlow入門教程

    摘要:簡(jiǎn)介是目前最流行的深度學(xué)習(xí)框架。代表一個(gè)數(shù)學(xué)運(yùn)算,簡(jiǎn)稱,這里面包括了深度學(xué)習(xí)模型經(jīng)常需要使用的。這也是名字的由來,表示多維數(shù)組在中流動(dòng)。這一步指定求解器,并設(shè)定求解器的最小化目標(biāo)為損失。 簡(jiǎn)介 TensorFlow是目前最流行的深度學(xué)習(xí)框架。我們先引用一段官網(wǎng)對(duì)于TensorFlow的介紹,來看一下Google對(duì)于它這個(gè)產(chǎn)品的定位。 TensorFlow? is an open sou...

    XUI 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<