日韩性视频-久久久蜜桃-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的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 深夜福利亚洲 | 一二三区在线播放 | 国产人伦精品一区二区三区 | 激情综合婷婷 | 美女被草出水 | 国产一卡二卡在线播放 | 亚洲欧洲视频在线观看 | 蜜芽在线视频 | 狼人av在线 | 91成人免费在线观看视频 | 一级欧美在线 | 天堂在线视频观看 | 亚洲天堂网站 | 播播成人网 | 韩日午夜在线资源一区二区 | 丁香综合网 | 人人干人人搞 | 亚洲欧美经典 | 麻豆av网| 色91在线| 精品日韩一区 | 久草视频免费看 | 草草影院欧美 | 黄色污污网站在线观看 | 黄片毛片在线看 | 91操操操| 国产精品2019 | 超碰不卡 | 免费在线观看你懂的 | 中国一区二区视频 | 91视频看| 亚洲欧美激情小说另类 | 国产午夜成人久久无码一区二区 | 在线观看欧美亚洲 | 人妻av中文系列 | 日本一区二区精品 | 男同av在线观看一区二区三区 | 男人av网 | 中文字幕人妻互换av久久 | 亚洲大色网 | 国产调教视频在线观看 | 成人做爰69片免费 | 黄色网久久 | 爱露出 | 黄色网页免费看 | 国产精品人成在线观看免费 | 伊人影院在线视频 | 成人免费一区二区 | 尤物综合网 | 婷婷激情成人 | 男人添女人下部高潮全视频 | xxxx国产片| www欧美精品 | 伊人蕉 | 99热这里精品 | 精品人妻一区二区免费 | 日本超碰在线 | 粉嫩在线| 日批视频免费看 | 欧美在线二区 | 国产午夜大片 | 国产又粗又长视频 | 亚洲操| 免费观看视频一区 | 久久久国产精品黄毛片 | 91偷拍富婆spa盗摄在线 | 亚洲偷偷| 国产精品三 | 美女扒开腿让男生捅 | 日韩xxx高潮hd | 一道本在线观看视频 | 色欲久久久天天天精品综合网 | 好吊操精品视频 | 无码人妻丰满熟妇区五十路百度 | 亚洲精品免费在线视频 | 香蕉视频官网 | 欧美一级精品 | 污污内射久久一区二区欧美日韩 | 国产综合精品一区二区三区 | 欧美大片视频在线观看 | 四虎精品一区 | 国产午夜亚洲精品午夜鲁丝片 | 国产老妇伦国产熟女老妇视频 | 国产精品成人aaaa在线 | 国产精品九 | 黄色片aaaa| 一区二区日本 | av免费网 | 白石茉莉奈番号 | 成人性生交大片免费看中文 | 国产精品啪 | 性综合网 | www国产精品视频 | 少妇激情偷人爽爽91嫩草 | 久久精品视频99 | 天天看天天做 | 亚洲综合视频网 | 亚洲在线一区二区 | 91精品国产色综合久久不卡电影 |