2011-03-10 77 views

回答

6

其實,這一切合理。

由於0.8不能準確地由各種x的任何系列的1/2 ** x表示,它必須被近似地表示,它發生,這是略小於10015.8。

所以,當你只是打印它,它是合理的四捨五入。

當你將其轉換爲整數,未添加0.5,它截斷0.79999999 ...0.7

當您在10001580.0型,那麼,那有一個確切代表所有格式,包括浮動和雙。所以你不會看到一個值的截斷,比下一個整數步驟稍微少一點。

浮點不是不準確的,它只是對可以表示的內容有限制。是的,FP是完全準確但不一定能代表每個數字,我們可以很容易地用鹼10.(更新/澄清輸入:很好,諷刺的是,它可以代表正好每一個整數,因爲每一個整數具有2 ** x組合物,但「每級分」是另一回事。只有某些小數可以準確地使用1/2**x系列組成。)

事實上,JavaScript實現使用浮動點存儲和算術的所有數值。這是因爲FP硬件能夠爲整數產生精確的結果,所以這使得JS傢伙使用現有硬件(當時)幾乎完全是32位機器的52位數學運算。

+0

謝謝!我從來沒有想過我會在這麼小的數字上遇到任何精度問題。 – Hitosu 2011-03-10 05:22:40

+0

@Hitosu與小數字無關。這是計算機處理浮點數的方式。 – 2011-03-10 05:45:07

+1

@Hitosu:這不是一個準確性問題,因爲它是一個*表示*問題。源代碼中的浮點數用十進制表示,但在RAM中用二進制表示。這意味着*看起來像*的數字應該有一個有限的表示形式(即在你的情況下是'4/5')實際上有一個*無限*表示(IOW:無論你如何精確地製作浮點數,你仍然會得到舍入錯誤)。問題在於你看到的和你得到的東西之間存在着認知上的分離:你不會感到驚訝,「1/3」具有無限的表示,但對於「1/10」卻不明顯。 – 2011-03-10 06:37:40

3

由於浮動計算截斷誤差,10015.8 * 100.0實際上是計算1001579.999999 ......所以,如果你簡單地套用to_i,它切斷小數部分並返回1001579

+1

我有同樣的問題,如果你有乘以100,並轉換爲整數的最後一位數字是錯誤的,(149.45×100).to_i給出14944,但(149.45 * 100)。是14945. – 0x4a6f4672 2013-02-20 17:42:55