看板 dinos
作者 dinos(守護神)
標題 [轉錄] Re: [請益] 請問(int) ((0.1 + 0.7) * 10)為什麼是7
時間 2012年05月21日 Mon. PM 05:27:56


※ 本文轉錄自看板 amyhuang

看板 PHP
作者 dio833 (Dio)
標題 Re: [請益] 請問(int) ((0.1 + 0.7) * 10)為什麼是7
時間 Fri May 18 01:16:05 2012


你把十進位改成二進位之後再轉回來就可以明白了
為方便計算,我假設記憶體只能存儲小數點後13位
0.1     = 0.0001100110011   (0.0之後的0011為無限循環,超出記憶體範圍者被截掉)
0.7     = 0.1011001100110   (0.1011之後的0011為無限循環...)
相加和  = 0.1100110011001
由上述再反轉回10進位,過程如下
  0.5
  0.25                         (0.75)
  0.03125                      (0.78125)
  0.015625                     (0.796875)
  0.001953125                  (0.798828125)
  0.0009765625                 (0.7998046875)
+ 0.0001220703125              (0.7999267578125)
-------------------------
  0.7999267578125

由右方可以觀察到,計算位數愈多,愈逼近某個數
而0.8轉成二進位應該是什麼呢?下面我拿0.8的二進位跟計算出來的13位比較一下
相加和  = 0.1100110011001
0.8     = 0.11001100110011001100....(無窮無盡的0011)

因此可以看出,計算位數如果愈多,愈逼近0.8的二進位
精確度取決於記憶體中存放的位數,但無論如何就是到不了0.8了
除非能保證使用的十進位小數可以轉換成二進位的有限小數
不然就算記憶體存放的位數再大,都會喪失一部分的精確度
這就是浮點數運算的弊端



※ 引述《BloodyDawn (血色曙光)》之銘言:
: 大家好~今天看書上寫了這個範例讓我滿納悶的
: PHP Code :
: echo (int) ((0.1 + 0.7) * 10);
: 正常情況下看到應該會印出8,但書上寫的答案是7
: 我也用http://writecodeonline.com/php/這個網站試了一下確實是印出7
Test run php code online, right here - WriteCodeOnline.com/PHP
[圖]
Design and test run your php code online, right here. It doesn't get cleaner or simpler than this. ...
 
: 書上的說法是在這邊最後計算的結果是7.999999再轉換成8
: 但遇到將型態轉成整數就會變成了7
: 那這邊有兩個問題:
: 1.我把0.7換成0.1~0.9但就只有0.7會有這個問題,請問是為什麼呢?
: 2.為什麼在這裡的計算結果會變成了7.999999呢?

--
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 114.34.13.174
※ 編輯: dio833          來自: 114.34.13.174        (05/18 01:17)
kusoayan:推1F 05/18 01:56
eye2468:長知識~推~2F 05/18 10:08
kerash:push3F 05/18 10:20

--
Knuckles:轉錯地方了吧 o_O
※ 看板: amyhuang  文章位址: http://disp.cc/b/96-3DyA

--
※ 作者: dinos  時間: 2012-05-21 17:27:56
dinos: [轉錄] Re: [請益] 請問(int) ((0.1 + 0.7) * 10)為什麼是7 - dinos板