為什麼 PHP 和 JavaScript 取整 ((0.1+0.7)*10) 的結果不是 8?

來源:互聯網
上載者:User
關鍵字 intval 0.1 0.7 php 10
php 代碼

intval((0.7+0.1)*10) 

回複內容:

這和電腦的小數表示有關,

通常情況下,小數是用 浮點數 表示的:
電腦中的浮點數
浮點指的是帶有小數的數值,浮點運算即是小數的四則運算,常用來測量電腦運算速度。大部份電腦採用二進制(b=2)的表示方法。位 (bit)是衡量浮點數所需儲存空間的單位,通常為32位或64位,分別被叫作單精確度 和雙精確度

比如單精確度的浮點數,由32個bit位。按照IEEE 754 標準,32位中有
1位是符號位(sign)
8位是指數位(exponent)
23位是數值 (fraction)

如所示:
那麼這個數的數值就是

這樣比如對於0.5,就可以表示成sign = 0, exponent = -1, fraction = 1
但實際上IEEE 754 對錶示方法還做了一些最佳化,比如fraction必須是1-2之間的一個小數,這樣fraction就只用表示小數位,而exponent的實際值是exponent + offset.

這樣實際的計算公式是:
比如0.5的float表示為:
0 01111110 000 00000000 00000000 0000
其中0為符號位
01111110為指數位,十進位為126, 所以實際的exponent為126 - 127 = -1,
而 000 00000000 00000000 0000 為fraction,十進位為0,
所以0.5f =

這種表示方法帶來的問題就是很多浮點數不能精確表示,比如0.1的浮點數表示為:
0 0111101 110011001100110011001101
實際上值為

你自己看看 `0.1 + 0.7` 的結果是什嗎?這跟浮點運算的特性有關。當十進位浮點數轉換為二進位浮點數時,精度就可能丟失,運算結果肯定也是有誤差的。

--

如果不明白為什麼十進位浮點數轉換為二進位浮點數,首先你可以選擇回去看基礎書……假若你是讀電腦的話,並且還沒有把書扔掉,或者還記得如何搜尋。否則的話,大概就是這樣的:浮點數都是儲存為尾數乘以指數的形式的,例如 12345 會儲存為 1.2345 * 10 ^ 4(實際儲存 1.2345 和 10)。問題是,浮點數不是用十進位來儲存尾數的,因此 1.2345 必須轉化為對應的二進位形式,也就是類似於 1.01010011 這樣的東西。你可以考慮一下,這種形式的位元只能表示 1 +/- 1/2 +/- 1/4 +/- 1/8 +/-... 因此,很有可能你要表達的那個十進位數,是在有限位元的位元中表現不出來的,然後精度就會丟失。因為在這兩種語言中,0.7 + 0.1 的結果小於 0.8,因此,取整後的結果為 7。

為什麼 0.7 + 0.1 小於 0.8 ,可以看我在 在JS中,為什麼浮點型數值0.1+0.2=0.30000000000000004,而0.15+0.15=0.25+0.05=0.3?中的回答
  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.