2011-06-12 70 views
6

目前我在我的一個應用程序中實現了一個方程(2^A)[X + Y*(2^B)]32位變量的溢出

問題是與32位值溢出,我不能使用64位數據類型。

假設當B = 3Y = 805306367,它溢出32位值,但當X = -2147483648,結果回到32位範圍。
所以我想存儲(Y*2^B)的結果。任何人都可以爲此提出一些解決方案.... A和B的值從-1515X,Y可以具有從2147483647..-2147483648的值。
輸出範圍可以從0...4294967295

+2

如果A = B = 15和X = Y = 2147483647那麼結果遠遠大於4294967295.是否還有其他限制將輸出限制在0 ... 4294967295範圍內? – Andrei 2011-06-12 12:56:32

+0

在你的等式中,是'^'xor還是力量?方括號代表什麼? – 2017-02-03 00:14:56

回答

6

如果數字對於一個32位變量來說太大,那麼您要麼使用更多的位(要麼通過存儲在一個更大的變量中,要麼使用多個變量),要麼放棄精度並將其存儲在浮點數中。由於Y可以是MAX_INT,因此根據定義,您不能將它乘以大於1的數字,並仍然適合32位int。

1

在這種情況下,我會使用循環而不是乘法。事情是這樣的:

int newX = X; 
int poweredB = (1 << B); // 2^B 
for(int i = 0; i < poweredB ; ++i) 
{ 
    newX += Y; // or change X directly, if you will not need it later. 
} 
int result = (1 << A) * newX; 

:這將工作對於某些情況 - 只有當你有保證,這個結果不會溢出。在你的情況下,當Y是大的正數,X是大的負數(「大」 - 這是太主觀的),這肯定會起作用。但是如果X很大,Y很大 - 那麼會有溢出。不僅在這種情況下,而且在許多其他情況下。

+0

+1表示不需要乘法,只是換檔。 – Codo 2011-06-13 06:51:52

1

基於對A和分配,我想預期的解決方案將涉及該值B:

  • 最好做無符號下面這樣存儲X和Y的跡象和對他們的絕對操作值

  • 商店X和Y中的兩個變量的每個,一個保持高16位的另一保持低位 類似
    INT HIY = Y & 0xFFFF0000地址;

    int loY = Y & 0x0000FFFF;

  • 移高零件右,使所有的變量具有高比特0

  • Y *(2^B)實際上爲Y的向左移位由B比特。它等同於B位高和低的部分移位和,因爲你已經移位的高位部分,這兩個操作將適合他們的32位整數內部

  • 方法X類似地,在高和低的部分

  • 的X和Y的符號
  • 飼養軌道計算X + Y *(2^B)爲高部分和低部分

  • 再次轉移高和低的結果由A位

  • 加入高,低部分進入最終結果

1

如果你不能使用64位的,因爲你的本地C不支持他們,而不是其他一些更重要的原因,你可能會考慮的GNU多精度運算庫http://gmplib.org/