日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

为什么 0.1 + 0.2 = 0.300000004

發布時間:2025/3/16 编程问答 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 为什么 0.1 + 0.2 = 0.300000004 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

JavaScript 作為一門誕生自上個世紀 90 年代的編程語言[^1],從誕生之初就因為詭異的隱式類型轉換等原因被黑,很多 JavaScript 的開發者還會吐槽浮點數加法的『奇葩』問題 — 為什么 0.1 + 0.2 在 JavaScript 中不等于 0.3,相信很多人都對這個問題的答案有一個大概的認識,但是都沒有深入研究過,這個問題的答案讓 William Kahan 在 1989 年獲得圖靈獎[^2]。

> 0.1 + 0.20.30000000000000004

其實有上述問題的不止 JavaScript 一門編程語言,幾乎所有現代的編程語言都會遇到上述問題,包括 Java、Ruby、Python、Swift 和 Go 等等,你可以在 https://0.30000000000000004.com/ 中找到常見的編程語言在計算上述表達式的結果[^3]。這不是因為它們在計算時出現了錯誤,而是因為浮點數計算標準的要求。

floating-point-math?圖 1 - 常見的浮點數『錯誤』

從最開始接觸 C 語言編程,作者就接觸到了浮點數 float,然而在很長一段時間中,作者都將編程中的浮點數和數學中的小數看做同一個東西,不過當我們重新審視它們時,會發現這兩個概念的不同之處。

  • 編程中的浮點數的精度往往都是有限的,單精度的浮點數使用 32 位表示,而雙精度的浮點數使用 64 位表示;

  • 數學中的小數系統可以通過引入無限序列 ... 可以任意的實數[^4];

在數學上我們總有辦法通過額外的符號表示更復雜的數字,但是從工程的角度來看,表示無限精度的數字是不經濟的,我們期望通過更小和更快的系統表示范圍更大和精度更高的實數。浮點數系統是在工程上面做的權衡,IEEE 754 就是在 1985 年建立的浮點數計算標準,它定義了浮點數的算術格式、交換格式、舍入規則、操作和異常處理[^5]。討論浮點數也無法脫離該標準,為了回答今天的問題,我們將從以下的兩個角度觸發:

[^5]: 754-2019 - IEEE Standard for Floating-Point Arithmetic https://standards.ieee.org/content/ieee-standards/en/standard/754-2019.html

  • 二進制無法在有限的長度中精確地表示十進制中 0.1 和 0.2;

  • 單精度浮點數、雙精度浮點數的位數決定了它們能夠表示的精度上限;


二進制與十進制

我們日常生活中使用的數字基本都是 10 進制的,然而計算機使用二進制的 0 和 1 表示整數和小數,所有有限的十進制整數都可以無損的轉換成有限長度的二進制數字,但是要在二進制的計算機中表示十進制的小數相對就很麻煩了,我們以 0.375 為例介紹它在二進制下的表示[^6]:

[^6]: Decimal to Binary converter https://www.rapidtables.com/convert/number/decimal-to-binary.html

小數點后面的位數依次表示十進制中的 0.5、0.25、0.125 和 0.0625 等等,這個表示方法非常好理解,每一位都是前一位的一半。0.375 在二進制表示看來確實是『整數』。然而如下圖所示,想要使用二進制表示十進制中的 0.1 和 0.2 是比較復雜的:

decimals-binary-representation圖 2 - 二進制表示的十進制小數

無論是 0.1 還是 0.2,這兩個數字都不是二進制中的『整數』,我們沒有辦法精確地表示它們,只能通過無限循環小數嘗試接近它們的真實值;與之相似的是,它們相加的結果 0.3 也無法用有限長度的二進制表示:

dot-three-binary-representation圖 3 - 二進制表示的 0.3

這三個不同的數字都會在最后的小數部分無限循環 1100 來趨近于真實值,如果計算機中的浮點數可以表示無限循環小數就有可能解決這個問題,但是事實的真相是浮點數只會表示有限小數,所有超過特定精度的數字都會做舍入處理。


精度上限

編程語言中的浮點數一般都是 32 位的單精度浮點數 float 和 64 位的雙精度浮點數 double,部分語言會使用 float32 或者 float64 區分這兩種不同精度的浮點數。想要使用有限的位數表示全部的實數是不可能的,不用說無限長度的小數和無理數,因為長度的限制,有限小數在浮點數中都無法精確的表示。

float-and-double圖 4 - 單精度與雙精度浮點數

  • 單精度浮點數 float 總共包含 32 位,其中 1 位表示符號、8 位表示指數,最后 23 位表示小數;

  • 雙精度浮點數 double 總共包含 64 位,其中 1 位表示符號,11 位表示指數,最后 52 位表示小數;

我們以單精度浮點數 0.15625 為例,介紹該浮點數在計算機二進制中的表示方法,如下圖所示,符號位 0 表示該浮點數為正數,中間的 8 位指數總共可以表示 256 個數字,其中從 [0, 126] 表示 [-127, -1],而 [127, 255] 表示 [0, 128],二進制的 01111100 是十進制的 124,表示 ,最后的 23 位是二進制的小數 0.25:

floating-number-example圖 5 - 0.15625 的單精度浮點數表示

通過上圖中的公式 可以將浮點數的二進制表示轉換成十進制的小數。0.15625 雖然還可以用單精度的浮點數精確表示,但是 0.1 和 0.2 只能使用浮點數表示近似的值:

dot-one-dot-two-floating-number圖 6 - 0.1 和 0.2 的單精度浮點數表示

因為 0.2 和 0.1 只是指數稍有不同,所以上圖中只展示了 0.1 對應的單精度浮點數,從上圖的結果我們可以看出,0.1 和 0.2 在浮點數中只能用近似值來代替,精度十分有限,因為單精度浮點數的小數位為 23,雙精度的小數位為 52,同時都隱式地包含首位的 1,所以它們的精度在十進制中分別是 和 位。

因為 0.1 和 0.2 使用單精度浮點數表示的實際值為 0.100000001490116119384765625 和 0.20000000298023223876953125[^7],所以它們在相加后就得到的結果與我們在一開始看到的非常相似:

dot-three-floating-number圖 7 - 0.1 加 0.2 的結果

上圖只是使用單精度浮點數表示的數字,如果使用雙精度浮點數,最終結果中的 3 和 4 之間會有更多的 0,但是小數出現的順序是非常相似的。浮點數的運算法則相對來說比較復雜,感興趣的讀者可以自行搜索相關的資料,我們在這里不展開介紹了。


總結

當我們在不同編程語言中看到 0.300000004 或者 0.30000000000000004 時不應該感到驚訝,這其實說明編程語言正確實現了 IEEE 754 標準中描述的浮點數系統,在使用單精度和雙精度浮點數時也應該牢記它們只有 7 位和 15 位的有效位數。

在交易系統或者科學計算的場景中,如果需要更高的精度小數,可以使用具有 28 個有效位數的 decimal 或者直接使用分數,不過這些表示方法的開銷也隨著有效位數的增加而提高,我們應該按照需要選擇最合適的方法。重新回到今天的問題 — 0.1 和 0.2 相加不等于 0.3 的原因包括以下兩個:

  • 使用二進制表達十進制的小數時,某些數字無法被有限位的二進制小數表示;

  • 單精度和雙精度的浮點數只包括 7 位或者 15 位的有效小數位,存儲需要無限位表示的小數時只能存儲近似值;

浮點數系統的設計是一個比較有趣的工程問題,因為操作系統一般都是 32 位或者 64 位的,浮點數充分利用了 32/64 位的比特,將每一位的作用都發揮到極致,使用最緊湊和簡潔的方式實現了盡可能高的精度。到最后,我們還是來看一些比較開放的相關問題,有興趣的讀者可以仔細思考一下下面的問題:

  • 有哪些編程語言內置了高精度的浮點數或者小數?

  • 如何實現一個可以精確表示所有實數(包括有理數和無理數)的系統?

有道無術,術可成;有術無道,止于術

歡迎大家關注Java之道公眾號

好文章,我在看??

總結

以上是生活随笔為你收集整理的为什么 0.1 + 0.2 = 0.300000004的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 免费成人深夜 | 亚洲精品乱码久久久久久蜜桃欧美 | 欧美成年人视频在线观看 | 欧美一级激情 | 亚洲专区第一页 | 一本色道久久88亚洲精品综合 | 国产欧美一区二区三区在线老狼 | 射美女| 亚洲精品欧美日韩 | 国产美女自慰在线观看 | 国产卡一卡二卡三无线乱码新区 | 久久精品国产av一区二区三区 | 91久久综合| 操操日日 | 国产在线视频一区 | 看欧美一级片 | 国产夫妇交换聚会群4p | a一级免费视频 | 黄色小视频免费网站 | 精品国产乱码久久久久夜深人妻 | 天天骑夜夜操 | 国产人伦精品一区二区三区 | 日韩在线色 | 国产午夜手机精彩视频 | 性感美女被草 | 波多野吉衣在线观看视频 | 日本久久中文字幕 | 欧美午夜精品久久久久久孕妇 | 美女的诞生免费观看在线高清 | 那里可以看毛片 | 亚洲a黄| 性感美女黄色片 | 91在线精品入口 | 性色av免费观看 | 越南少妇做受xxx片 亚洲av综合色区无码一二三区 | 久久人人爽天天玩人人妻精品 | 噜噜噜av| 亚洲视频一二三四 | 2022av视频 | 亚洲精品tv| 久久久久这里只有精品 | 美女屁股网站 | 婷婷亚洲五月色综合 | 狂躁美女大bbbbbb黑人 | 一区二区三区在线播放 | 日日精 | 国产精品美乳在线观看 | 好吊妞无缓冲视频观看 | 亚洲成人网络 | 精品人妻av一区二区三区 | 在线看成人片 | 国产99久一区二区三区a片 | 欧美成人精品一区二区三区在线观看 | 美女性高潮视频 | ass亚洲肉体欣赏pics | 欧美亚洲韩国 | 中文字幕在线第一页 | 99久久精品免费看国产免费软件 | 国产对白videos麻豆高潮 | 伊人久久久久久久久久久 | 久久偷看各类wc女厕嘘嘘偷窃 | 日韩一区二区免费在线观看 | 国产精品欧美一区二区 | 蜜桃传媒 | 玖玖国产精品视频 | 亚洲国产精品久久久久婷蜜芽 | 国产精品成人久久久 | 日本在线不卡一区 | 精品人妻一区二区三区换脸明星 | 精品视频一区二区三区四区 | 精品视频在线观看免费 | 91婷婷色 | 国产黑丝一区 | 手机在线看片国产 | 亚洲国产aⅴ成人精品无吗 日韩乱论 | 男人操女人视频网站 | 国产91熟女高潮一区二区 | a级黄色一级片 | 亚洲一区中文字幕在线观看 | www.操操操 | 国产无套粉嫩白浆内谢 | 91黑人精品一区二区三区 | 国产激情无码一区二区 | 精品黄色在线观看 | 91免费福利 | 蜜桃导航-精品导航 | 人妻体内射精一区二区 | 韩国主播青草55部完整 | 免费成人黄色 | 69av视频在线观看 | h网址在线观看 | 欧美黑人xxx | 久久涩| 欧洲做受高潮免费看 | 献给魔王伊伏洛基亚吧动漫在线观看 | 国产一区二区精品久久 | 小柔的淫辱日记(1~7) | h片免费网站 | 天天狠天天插 |