2016-09-20 59 views
1

最近試圖解決程序中的錯誤,並意識到問題出現在下面的代碼中(類型不是字節,但是對於這個問題,假設它們不能大於這個值,因爲某些組合會導致溢出):如何在.NET中執行長時間的強大功能?

long GetValue(byte x, byte y, byte z) { 
    return (long)Math.Pow(x, y) * z; 
} 

的給定示例中的值:X = 27,Y = 12,Z = 7

然後:

a = 27^12 = 150,094,635,296,999,121 
r = a * 7 = 1,050,662,447,078,993,847 

然而,C#的.NET代碼將給出:

a = 27^12 = 150,094,635,296,999,136 
r = a * 7 = 1,050,662,447,078,993,952 

的線索是在Math.Pow功能,它體現了回報:

1.5009463529699914E+17 

這是因爲Math.Pow功能只存在於雙打,雙打有不精確的超過一個級別一定的分數值。由於結果越來越接近long.MaxValue,那麼不精確的浮點數學會影響由演員生成的長整型值。

長時間沒有等價的Math.Pow函數。有些東西告訴我這個藉口是因爲在引擎蓋下,無論你如何表達它們,longs和double都是64位數字。但是(在我看來)多頭不應該使用浮點數學。

這是否意味着CPU無法執行高於32位的非小數值的精確計算?這對我來說似乎不太可能,因爲Windows計算器可以正確地獲得這個數學。

這樣的問題應該如何在.NET中解決?我有點假設我錯過了某個地方的功能。

(原來的問題我已經改變了方案設計的做法不再需要此代碼解決了,但我想我反正發佈問題,因爲它很有趣。)

問候, 搶。

回答

0

您可以使用BigInteger類來處理任意精度整數。這是您的問題的典型解決方案。

如果你不需要大於long.MaxValue的數字,你也可以自己寫一個天真的電源功能。

CPU使用固定大小的整數。任意大小的整數是一個軟件解決方案。

+0

啊,謝謝,能夠重寫原來的代碼,以便它現在可以工作。最初的解決方案於2005年被寫回,顯然當時沒有BigInteger。進展:) – peridian