為什麼0.1+0.2不等於0.3?原來程式語言是這麼算的……

2021-01-08 機器之心Pro

選自Medium

作者:Parul Malhotra

機器之心編譯

參與:高璇、張倩

打開你的 Python,輸入「0.1+0.2=」,結果是多少?0.30000000000000004 對不對?為什麼結果不是 0.3?本文作者給出了詳細的解釋。

從小我們就知道 0.1 + 0.2=0.3。但是,在光怪陸離的計算世界中,運算方式卻大相逕庭。

我最近開始用 JavaScript 進行編碼,在閱讀數據類型時,我注意到 0.1 + 0.2 不等於 0.3 的奇怪行為。我向 Stack Overflow 尋求幫助,在上面找到了一些有用的帖子。如下圖所示:

Stack Overflow 界面圖像。

經過大量的研究和數學運算後,我得出結論,這不是錯誤。這是數學運算中的浮點運算。讓我們進一步了解內在機制。

問題描述: 為什麼 0.1 + 0.2 = 0.30000000000000004?

如果你用 Java 或 C 語言編過程,那你一定知道用於存儲值的不同數據類型。我們在前面的討論中將考慮兩種數據類型:整數型和浮點型。

整數型存儲整數,而浮點型存儲小數。

在這之前,我們先來了解一個小概念:為了實現計算,數字是如何表示的?極小數和極大數通常用科學計數法表示,即:

同樣,如果一個用科學計數法書寫的數字小數點前有一個非零的十進位數,則該數字是標準化寫法。例如,0.0005606 用科學計數法的標準化寫法為:

Significant 是指不包含零的有效數字,base 表示所使用的進位——此處為十進位(10)。Exponent(指數)表示小數點需要向左或向右移動的步數。

現在,有兩種顯示浮點數的方法:單精度和雙精度。在進行浮點運算時,單精度使用 32 位,而雙精度使用 64 位。

與許多其他程式語言不同,JavaScript 並未定義不同類型的數字數據類型,而是始終遵循國際 IEEE 754 標準,將數字存儲為雙精度浮點數。

這種格式以 64 位存儲數字,其中數字(分數)存儲在位 0 到 51 中,指數存儲在位 52 到 62 中,符號存儲在位 63 中。

IEEE754 雙精度標準。

我們按 IEEE754 標準用 64 位表示 0.1。第一步是將十進位的 0.1 轉換為二進位的 0.1。首先將 0.1 乘以 2,然後將小數點前的數字分離出來,得到其相應的二進位數。

重複此操作至 64 位。然後把它們按升序排列,獲取尾數,再根據雙精度標準,我們將把其四捨五入到 52 位。

尾數

用科學計數法表示二進位 0.1 並只保留前 52 位:

尾數部分處理好後。現在我們用下面的方式處理指數:

這裡,11 代表我們要使用的 64 位表示的指數位數,-4 代表科學計數中的指數。

所以最終數字 0.1 的表示形式是:

同理,0.2 表示為:

將兩個數相加,得到:

轉換為浮點數,它變成:

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

原文連結:https://medium.com/better-programming/why-is-0-1-0-2-not-equal-to-0-3-in-most-programming-languages-99432310d476

相關焦點

  • 為什麼計算機時間和眾多程式語言要從1970年1月1日開始算起
    為什麼計算機時間和眾多程式語言要從1970年1月1日開始算起 今天我們來討論一個非常有意思的事,那就是你知道為什麼計算機時間和眾多的程式語言的時間都要從1970年1月1日開始算起呢,時間計時起點到底為什麼是 1970年1月1號呢?
  • UFS 3.0和UFS 2.1真的那麼重要嗎?為什麼無UFS 3.0不5G?
    最近在網上看到很多關於「沒有UFS 3.0 就不配說是5G手機!」「UFS 3.0 是5G手機的標配」等文章,而現在有很多行動裝置上都搭載了UFS 3.0 ,那麼UFS 3.0究竟是什麼呢?有什麼作用,相比它的前一代UFS 2.1究竟有什麼區別呢?為什麼說沒有UFS 3.0就不配叫5G手機?
  • 1+9+0等於幾是什麼梗啥意思?1+9+0等於多少正確問題答案
    1+9+0=是什麼意思?1+9+0=是什麼梗?最近群裡有個小夥伴在問小編,1+9+0=?是什麼意思?小孩子年輕不懂事。還不快上車?  果然就知道是女孩子問他的。。。。  1+9+0等於多少?哪個女孩子會蠢到問你一個學前班的小朋友都會的算數題?如果你真的告訴她等於十,那孩子以後吃狗糧的時候別怪老司機沒開車!
  • 在編程中,為什麼要把小數叫做浮點數?
    小數為什麼會被成為浮點數?有不少程式設計師雖然能夠很熟練的使用某種程式語言,但是對於小數為什麼會被稱為浮點數卻是不太理解。雖然這些程式設計師對於小數被稱作浮點數的問題並不理解,但是這並不影響程式設計師編程,或者可以說這種問題對於一個程式設計師的編程能力絲毫沒有影響。一個小數的組成:在我國,小數表示由三部分組成,分別是整數+小數點(分隔符)+小數。以上概念看似很簡單,卻是理解浮點數的重要基礎。理解了小數的重要組成部分的話,非常有利於快速的理解浮點數一詞的由來。
  • 讓人疑惑不解的 "0=偶數"
    我國古算著作中,最早出現用 圓圈表示 " 〇 " 號的是南宋秦韶九《數書九章》(1247年),書中大量使用 " 〇 "。印度的扁圓 " 0 " 與我國的圓 " 〇 " 是不同的,我國的 " 〇 "是自己發明的。印度的 " 0 "大約是 13 世紀傳入我國,那時,我國的 " 〇 "已使用 100 多年。
  • 1月2日0—24時重慶疫情通報:0+0+6+63
    1月2日0—24時重慶疫情通報:0+0+6+63 2021-01-03 08:28 來源:澎湃新聞·澎湃號·政務
  • 對於5G手機來說,UFS 3.0重要嗎?
    日前,小米發布了自家國內首款商用5G手機小米9 Pro 5G,機身整體語言延續了上代小米9的設計,雖然售價沒有當初小米9那麼香,但在5G市場上還是具有一定的性價比。不過許多網友在看完發布會後提到小米9 Pro 5G全程沒有公布快閃記憶體規格,會不會搭載的依舊是UFS 2.1?
  • 閣下可知文言編程之精妙?
    此外,程式語言數量眾多,如同《天官書》記錄的星宿一般多,又比《山海經》中記錄的飛禽走獸還要奇特。Go、Rust、Ruby、Fishshell因速度而出名。Python、Php、Perl和 JavaScript則各有獨特之處。我這才理解到,為什麼鬼會夜哭,天上會下粟雨。但以往從未有人使用過文言文進行編程。
  • 同樣是5G手機,為何UFS 2.1快閃記憶體與UFS 3.0快閃記憶體差距這麼大?
    小瑕疵,也是大問題小米9 Pro 5G採用的是UFS 2.1快閃記憶體。據悉,其他5G手機幾乎都採用最新UFS 3.0快閃記憶體。UFS 2.1快閃記憶體在4G手機中可以說是非常頂級的配置,但是對於5G手機而言則有些不足。UFS 3.0的讀取速度為1567MB/s,相較於UFS 2.1提升85%之多。
  • xk-time 2.2.0 發布,Java 時間工具包,支持解析自然語言時間,明天...
    2.支持解析自然語言時間,今天,明天,下周,下月,明年,昨天,上周,上月,去年等,支持自定義解析自然語言時間。3.日期計算工具類優化,提高性能。4.完善注釋文檔,生成javadoc的API在線文檔: https://apidoc.gitee.com/xkzhangsan/xk-time/ 。5.代碼優化。
  • 解密神秘的黃金分割比例,為什麼非得是0.618?
    2000多年前,古希臘的數學家和哲學家畢達哥拉斯有一天走在街上,在經過鐵匠鋪的時候,他聽見鐵匠打鐵的聲音,一長一短,非常悅耳動聽,就像音樂一樣,於是就停下來,聽了好一會他發現鐵匠打鐵的節奏非常有規律,由於天生的數學敏感性,這個聲音比例就被畢達哥拉斯用數學的方式表達了出來,他把一根繩子分成一長一短的兩段,如果較短的一段和較長的一段的比例,正好等於較長一段和整根繩子的比例就是約0.618,
  • 解名大師 v1.0.2 名師解答名字的含義
    姓名測算應用通過姓名的筆劃,聲調、音律、部首這幾個方面來對你的命理進行詳盡的分析,為你算出你想要了解的運勢。從iTunes下載解名大師  高速下載  解名大師相關參數  價格:$9.99  類別:商品指南  更新:2012年06月11日  當前版本:1.0.2
  • 5G時代的重要參數,UFS 3.0的兩款vivo手機成績突出
    早期使用的是eMMC,其中以eMMC 5.1最為著名,當時千元機幾乎都使用這個標準。隨著智慧型手機性能越來越高,安卓陣營普遍更新到了新的UFS技術,到了2016年,國產手機率先使用了UFS 2.0/2.1,在三年前算得上一次技術革新。經過兩年的不斷打磨,UFS 2.1能夠達到700+MB/s的速度,不隱諱的說,在這兩年智能機發展起到了重要的作用。
  • 12月CPI同比上漲0.2%,豬肉價格下降1.3%
    非食品中,交通和通信價格下降3.1%,其中汽油和柴油價格分別下降14.8%和16.2%;醫療保健價格上漲1.3%;教育文化和娛樂價格上漲0.9%。扣除食品和能源價格的核心CPI同比上漲0.4%,漲幅比上月回落0.1個百分點。二、PPI環比漲幅有所擴大,同比降幅收窄12月份,國內需求穩定恢復,加之部分國際大宗商品價格持續攀升,帶動工業品價格繼續上行。
  • 小學數學一年級認識數字0詳解
    在小學一年級數學的學習中,最大的變化當屬引入了「0」這個概念了。'0'在不同地方可以表示不同的意思,對於一年級的孩子來講,確實不太容易理解,在這小編特意整理了關於數字「0」的一些知識,供各位家長朋友在輔導孩子時作為參考。
  • 0-2!0-1!刷3恥辱!西班牙人「3線倒塌」,終結4年歷史+12年紀錄
    北京時間1月4日凌晨,西乙聯賽結束了一場關鍵的比賽,武磊所在的西班牙人在第20輪西乙比賽中以0-1輸給了已經淪為魚腩球隊的拉斯帕爾馬斯,而且是輸球又輸人,在比賽中早早被直接紅牌罰下一人,羅伯託-岡薩雷斯在比賽第26分鐘的進球成為了全場比賽唯一的進球,西班牙人的梅拉梅德雖然在比賽第67分鐘打進1
  • UFS 3.0測試首曝光:速度竟是UFS 2.1的3倍
    日前,網絡上曝光了一張1TB UFS 3.0快閃記憶體的Androbench讀寫測試記錄截圖。從這份記錄中,我們可以明顯的看到UFS 3.0的順序讀取速度達到了2279.8MB/s,順序寫入速度達到了1801.1MB/s。按照目前UFS 2.1普遍的700-800MB/s順序讀取速度來看,基本是2-3倍了。
  • 紅米K30至尊紀念版的快閃記憶體不是UFS 2.1而是UFS 3.0?
    紅米K30至尊紀念版能夠這麼受歡迎,和其同價位的產品都不是其對手,說到底還是靠性價比取勝,那麼其在性能部分又有哪些改變呢?網友總結主要有四點變化,第一點是屏幕的變化,刷新率提升到120Hz,E3材質的三星AMOLED屏,這款屏幕在3000元以下的手機裡面無敵手。第二點就是揚聲器升級到雙揚聲器,但是3.5mm耳機插孔取消了。第三點就是主攝和超廣角的CMOS進行了調整。
  • UFS 3.0快閃記憶體與UFS 2.1快閃記憶體究竟有什麼區別
    目前市面上的多數手機都採用UFS 2.1和UFS 3.0兩種同規格但不同版本的快閃記憶體,而不久前發布的OPPO Reno Ace,採用了最新一代是UFS 3.0快閃記憶體。Reno Ace搭載的UFS 3.0快閃記憶體與其他手機的UFS 2.1快閃記憶體究竟有什麼區別呢?用實際測試來兩者的區別。
  • eMMC5.1是什麼?UFS2.0又是什麼?
    2016年,安卓手機配置再次提升到了一個新的檔次,驍龍820、4GB大內存,存儲也飆到了128GB,而在這裡,有一個很小的細節,那就是採用了UFS2.0快閃記憶體,而不是之前比較流行的eMMC5.1,說到這裡,UFS 2.0快閃記憶體到底是什麼鬼?為何三星、樂視、聯想以及小米手機都在用?eMMC5.1又有什麼劣勢,最終被UFS2.0取代呢?