91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

為什么 JavaScript 中 0.1+0.2 不等于 0.3 ?

發布時間:2020-07-07 18:05:15 來源:網絡 閱讀:230 作者:vivo互聯網 欄目:web開發

本文首發于 vivo互聯網技×××鏈接:https://mp.weixin.qq.com/s/2kea7-jACCJmSYBQAwXyIg
作者:劉洋

在 js 中進行數學的運算時,會出現0.1+0.2=0.300000000000000004的結果,一開始認為是浮點數的二進制存儲導致的精度問題,但這似乎不能很好的解釋為什么在同樣的存儲方式下0.3+0.4=0.7可以得到正確的結果。本文主要通過浮點數的二進制存儲及運算,和IEEE754下的舍入規則,解釋為何會出現這種情況。

一、浮點數的二進制存儲

JavaScript遵循IEEE754標準,在64位中存儲一個數據的有效數字形式。

為什么 JavaScript 中 0.1+0.2 不等于 0.3 ?

其中,第0位為符號位,0表示正數1表示負數;第1到11位存儲指數部分;第12到63位存小數部分(尾數部分)(即有效數字)。由于二進制的有效數字總是表示為 1.xxx…的形式,尾數部分在規約形式下的第一位默認為1,故存儲時第一位省略不寫,尾數部分f存儲有效數字小數點后的xxx...,最長52位。因此,JavaScript提供的有效數字最長為53個二進制位(尾數部分52位+被省略的1位)。
以0.1、0.2、0.3、0.4和0.7的二進制形式為例:

0.1->0.0001100110011...(0011無限循環)->0-01111111011-(1 .)1001100110011001100110011001100110011001100110011010(入)
0.2->0.001100110011...(0011無限循環)->0-01111111100-(1 .)1001100110011001100110011001100110011001100110011010(入)
0.3->0.01001100110011...(0011無限循環)->0-01111111101-(1 .)0011001100110011001100110011001100110011001100110011(舍)
0.4->0.01100110011...(0011無限循環)->0-01111111101-(1 .)1001100110011001100110011001100110011001100110011010(入)
0.7->0.101100110011...(0011無限循環)->0-01111111110-(1 .)0110011001100110011001100110011001100110011001100110(舍)

對于52位之后進行舍入運算,此時可看作0舍1入(具體舍入規則在第三部分詳細說明),有精度損失。

二、對階運算

由于指數位數不同,運算時需要進行對階運算。對階過程略,0.1+0.2與0.3+0.4的尾數求和結果分別如下:

0.1+0.2->10.0110011001100110011001100110011001100110011001100111
0.3+0.4->10.1100110011001100110011001100110011001100110011001101

求和結果需規格化(有效數字表示),右規導致低位丟失,此時需對丟失的低位進行舍入操作:

0.1+0.2->1.00110011001100110011001100110011001100110011001100111->1.0011001100110011001100110011001100110011001100110100(入)
0.3+0.4->1.01100110011001100110011001100110011001100110011001101->1.0110011001100110011001100110011001100110011001100110(舍)

即:
00111->0100
01101->0110

此處同樣有精度損失。在這里我們可以發現,0.3+0.4對階階運算且規格化后的運算結果與0.7在二進制中的存儲尾數相同(可對照尾數后幾位),而0.1+0.2的運算結果與0.3的存儲尾數不同,且0.1+0.2轉化為十進制時結果為0.300000000000000004。
此時,雖然0.1+0.2與0.3+0.4進行舍入操作的近似位都為1,但一入一舍導致計算結果與“標準答案”的異同。

三、IEEE754標準下的舍入規則

維基百科對最近偶數舍入原則的解釋如下:舍入到最接近,在一樣接近的情況下偶數優先(Ties To Even,這是默認的舍入方式),即會將結果舍入為最接近(精度損失最小)且可以表示的值,但是當存在兩個數一樣接近的時候,則取其中的偶數(在二進制中是以0結尾的)。

首先要注意的是,保留小數不是只看后面一位或者兩位,而是看保留位后面的所有位。

為什么 JavaScript 中 0.1+0.2 不等于 0.3 ?

如圖,可以看到近似需要看三位,保留位(近似后的最低位)、近似位(保留位的后一位)、粘滯位(sticky bit 近似位后的所有位進行或運算后看作一位)。
當粘滯位為1時,舍入規則可以看作0舍1入,近似位為0舍,近似位為1入(即第一部分小數二進制存儲為52位尾數時所進行的舍入操作)。
當粘滯位為0時,若近似位為0則舍去。
當粘滯位為0時,若近似位為1,無論舍入精度損失都相同,故需取舍入兩種結果中的偶數:保留位為1時入,保留位為0時舍(即第二部分對階運算規格化時的舍入操作)。

四、總結思考

由于IEEE754標準,這樣的“bug”不止在JavaScript中會出現,在所有采用該標準的語言中都會存在,實際編程中可以通過設置精度保留位數等方式解決。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

乡宁县| 孟津县| 巢湖市| 朝阳市| 邵东县| 来宾市| 会昌县| 衡阳市| 满洲里市| 慈溪市| 丹阳市| 神木县| 安国市| 临夏县| 汤原县| 红安县| 班玛县| 宁武县| 德化县| 叙永县| 乐都县| 兴城市| 河津市| 海盐县| 徐州市| 沙洋县| 洛宁县| 大庆市| 锡林浩特市| 隆化县| 乌拉特中旗| 大洼县| 双江| 永仁县| 宁陵县| 西峡县| 扎鲁特旗| 靖宇县| 唐山市| 类乌齐县| 都江堰市|