-2

QUES:控制精度溢出和損失,同時乘以雙打

我有大量浮點數(〜萬數),小數點後各自具有6位數字。現在,所有這些數字的乘法將產生大約60,000個數字。但雙倍範圍僅適用於15位數字。輸出產品必須在小數點後有6位精度。

我的方法:

我想10^6這些數字相乘,然後將它們相乘,後來由10^12分他們。

我也想過用這些數字乘以數組來存儲它們的數字,然後把它們轉換成十進制數。但是這也看起來很麻煩並且可能不會產生正確的結果。

有沒有更容易的方法來做到這一點?

+0

我爲我的代碼使用C++。 :) – bnks452

+0

http://stackoverflow.com/q/2568446/327083 –

+0

http://www.google.com/search?q=c%2B%2B+arbitrary+precision –

回答

2

我想這些數字乘以10^6,然後乘以它們,然後再除以10^12。

這隻會進一步降低準確性。在浮點數中,大數表示大致與小數字一樣。只讓你的數字更大意味着你正在做19999乘法(和一個除法)而不是9999乘法;它不會神奇地給你更有意義的數字。

該操作只有在防止部分產品進入低於正常範圍的情況下才有用(在這種情況下,建議乘以2的冪數以避免由於乘法導致的準確度損失)。在你的問題中沒有跡象表明會發生這種情況,沒有示例數據集,也沒有代碼,所以只能提供下面的通用解釋:

浮點乘法在不下溢或溢出時表現非常好。在第一階中,你可以假設相對誤差加起來,所以乘以10000的值產生的結果是相對於(*)數學結果的9999個機器。

上述問題的解決方案(無代碼,無數據集)是對中間乘法使用更寬泛的浮點類型。這既解決了下溢或溢出的問題,又爲最終結果留下了相對的準確性,從而一旦舍入到原始浮點類型,該產品最多隻能有一個ULP出錯。

根據您的編程語言,這種更寬的浮點型may be available aslong double。對於10000次乘法,在x86處理器中廣泛使用的80位「擴展雙倍」格式將顯着改善事情,只要您的編譯器將此80位格式映射到浮點,您幾乎不會看到任何性能差異類型。否則,您將不得不使用軟件實現,例如MPFR'的任意精度浮點格式或double-double格式。 (*)實際上,相對誤差是複合的,因此相對誤差的實際界限更像(1 +ε),其中ε是機器的ε值。而且,實際上,相對誤差通常會相互抵消,因此您可以預期實際相對誤差會像理論最大誤差的平方根那樣增長。

+0

「這種操作只會有用,如果它防止部分產品進入低於正常範圍(在這種情況下,建議乘以2的冪數以避免由於乘法導致的精度損失)。「你能解釋一下這是什麼意思嗎? – bnks452

+0

@ bnks452如果你提供了一個示例數據集,我會更喜歡它,我可以告訴你,你不需要擔心子異常。否則,在這裏有一個定義(https://en.wikipedia.org/wiki/Denormal_number),與討論相關的句子是「它允許計算在結果很小時緩慢地失去精度」,含義儘管你沒有得到零,但當一個部分產品是一個低於正常的數字時,最終的結果可能不如預期的那麼準確。 –

+0

將數字乘以10^6我的意思是將它們存儲爲整數並相乘,因爲我的數據集由浮點數< 1 and > 0和小數點後6位數組成。例如:0.123456,0.986173等等。大約有10000個這樣的數字,我必須在小數點後得到6位數的輸出。 – bnks452