0.1+0.2!=0.3,這不是語言的錯

小汪大汪旺旺發表於2018-02-27

最近又一次看到這個問題,想起那句話,鐵打的營盤流水的兵,程式界也是一樣,當年c語言的題目問了java,再問js,老的一輩知道了再問小年輕。可是基礎就是這種你不能不會的東西,希望今天的文章能夠將這個問題講的能讓年輕的人知道原因。

在偵錯程式中,我們寫出0.1+0.2的詩句,按下回車,偵錯程式告訴你,答案是0.30000000000000004,“你錯了”,你對偵錯程式說,“沒有”,偵錯程式理直氣壯的回答你。“你就是錯了”,“沒有沒有!”,你氣的開啟電腦終端,詢問他是誰錯了,“是你錯了,而且,這就是你沒有物件的原因”,你還是不服,“你們都是js,我要問問python,於是你又在python環境下打下這行詩句,他任然告訴你,js沒錯”。

“這就是你沒有物件的原因?”,你驚呆了,你一定要弄清楚這原因是什麼,畢竟已經鬧這一出了。

帶著些許惱怒些許擔憂,你找到了大師。大師說:你先和js幹起來的,我們們就先說說js吧,如果你寫下的詩句不是0.1+0.2,而是1+2,那麼誰都不會反對你讓它等於3。錯就錯在你寫的是小數,因為在js中,Number型別的標準是ECMA的標準,也就是IEEE 754的雙精度數值,這一類數值就是通常java中所說的double型別,而這一標準就是通用的一個對實數進行計算機編碼的標準。所以,不光是js,python,java等程式語言大家都是這樣認為。

回到標準上來,不管是人還是計算機,我們需要知道“1是1”,就要對“1”編碼,我們用“1”去描述“1”,是因為我們知道“1”就是代表“1”。就是因為這一點,我們和計算機溝通上就有了一些隔閡了,因為他天生不懂“1”代表“1”,就像老外不懂漢語一樣。我們以為告訴了計算機一個十進位制的數字,實際上計算機把它轉換成二進位制存起來了,保留的時候會進行位數限定。浮點數和浮點數相加的時候就存在誤差了。就像外國人翻譯古詩之後再翻譯成中文就不好聽了一樣,十進位制小數轉換成二進位制存在計算機中只能無限近似,在涉及到運算,就更加會有誤差了。因此,對於小數的運算,一般是轉換成整數運算,然後在轉換回去。

所以,有一些用心的前輩整理了一些浮點數原則:

1.儘量不用小數,貨幣使用最小單位,避免使用除法,用了,也要儘可能轉換成整數。

2.引入多於計算要求的小數位,在計算時多增加幾位小數。

3.使用isFinite()和isNaN()保證合法性。

4.計算越少越好。

現在你懂了?

懂了,可是,這和找不到物件也沒關係吧。

“說語言錯誤那是你不懂語言,你不懂語言你就不懂計算機。說女人錯誤說明你不懂女人。”

“我沒說女人錯誤呀。”


相關文章