2011-07-12 40 views
2

據我所知浮動可以精確表示14號。浮動點,當它出現,它是如何工作

所以我們可以說,我們有

a = 564214623154 
b = 54252 

,我們乘這 C = A * B,它應該是30609771735350808,但在編譯時它顯示我3.0609771735351E + 16 所以,按照我的理解應該失去一些精確,但是當我通過一個 C/A除以三我得到沒有任何精度564214623154確切的結果失去

另一個例子,假設我們已經

c = 30609771735350808 
d = 30609761111111111 

E = C-d應該是10624239697,但在編譯時它顯示我10624239696所以精度丟失

所以是精度只有當我加上或減去兩個數字失去了什麼?

如果很重要我使用php

回答

1

也有可能因乘法和除法而失去精度。 PHP和JavaScript以IEEE-754格式存儲數字,包含52位尾數和11位指數。一些整數是完全表示的,有些則不是。

讓我們試試這些:

在真實數學(使用Ruby生成):

45345657434523 * 9347287748322342/74387422372 = 5697991604786167788 

在PHP和JavaScript

45345657434523 * 9347287748322342/74387422372 = 5697991604786168000 

所以我們失去精度乘法和除法也。

編輯:在重新審視業務方案的問題,好像這是不是一個偉大的答案,因爲結果包含了精度15張十進制數。如果這個問題的意圖是否乘以將一堆每一個在精度以下15位代表的是數字的,那麼最終的結果往往會保持精度好對付(只要你不溢出或下溢) 。所以,你可以乘1.25E35 * 2.5E7,並得到準確3.125e+42因爲PHP和JavaScript將主要繁殖的顯著數字組,並添加了指數。但是,如果您添加這兩個值,您會得到1.25E35 + 2.5E7 = 1.25E35。這是正確的,你增加了2500萬到一個數字,它不會改變!這是因爲,正如OP所說,你只能得到14或15位精度的十進制數字。嘗試通過書寫120000000000000000000000000000000000 + 25000000手動添加這兩個值。 14-15個數字從左邊開始計數,你不能全部選中它們。

底線是精度的問題更可能與加減產生。很好意識到。

+1

不要忘記IEEE754中的隱藏位。你實際上有53個可用位的尾數。 –

+1

@Kerrek - 謝謝,是的53可用。 @Templar - http://en.wikipedia.org/wiki/IEEE_754-1985是一個很好的開始任何地方,或谷歌「ieee 754」的其他網頁。 –

1

在你的第一個情況下,你沒有失去精度,PHP只是格式化較大數量爲float。 (內部數保持爲浮動。)試試這個去拿「精確的」輸出:

$a = 564214623154; 
$b = 54252; 
$c = $a * $b; 
printf("%u, %u\n", $c, $c/$a); 

接下來,在c * d的情況下,你的兩個數字已經分別超過標準的IEEE-能力64位浮點數(53位,而你至少需要55位),所以當你存儲這些數字時,精度已經丟失。

在加法/減法過程中失去精度的問題稱爲「取消」:您將所有存儲器花費在其上的所有最重要的位都取消了,最終沒有足夠的精確位來填充manitssa。這就是生活。

想象一下,你坐在月球上,並在英國伍斯特(Worcester)對兩兄弟鬍鬚的頭髮長度進行測量。比較這兩種測量結果會讓您需要存儲大量的精度。

+0

@Templar:我確實如此:它將'$ c'視爲一個整數並將其打印爲一個整數。但是,如果數字在內部存儲爲雙打,則必須使用平常的鹽量,即您的值可能沒有您打印的有效數字。 –

相關問題