2015-08-15 64 views
1

很容易讓C#在整數溢出時拋出異常。但是,這不是我要找的。我想檢測溢出,所以我可以繼續高階計算。我正在構建一個大的int實現。整數溢出檢測C#添加

我可以捕獲溢出異常,但這對性能並不好。更不用說它在概念上是不正確的。

任何想法如何檢查溢出沒有例外?

+0

請添加一個可能溢出的代碼示例。 – cyberj0g

+2

你知道C#中有一個'BigInteger'類,或者你只是爲了練習而這麼做? – Rob

+1

當您使用Parse()或者當您正在執行數學運算時,我認爲溢出與Single(),Double()或Float()對象有關。如果由於Parse而發生錯誤而不是使用ParseExact()。如果是數學運算,通常由分母的分母非常小(或零)引起。所以在分割之前檢查分母。 – jdweng

回答

2

如果您正在尋找攜帶行爲,其他答案/評論涵蓋相當不錯。然而,我發現最初的問題是一個有趣的大腦難題(儘管實際上並不實用),具體來說,檢測2個帶符號整數的最佳性能是純粹的C#方式是否會增加溢出。理想情況下,它會生成一個沒有分支的最小IL指令。這裏是我最終得到的最好結果 - 一個帶有bool標誌(當溢出時爲true,否則爲false),另一個爲int「bit」(溢出時爲1,否則爲0)。兩者都滿足上述標準,「位」版本少有少量IL指令。享受:-)

static int Add(int a, int b, out bool overflowFlag) 
{ 
    unchecked 
    { 
     int c = a + b; 
     overflowFlag = ((a^b) >= 0) & ((a^c) < 0); 
     return c; 
    } 
} 
static int Add(int a, int b, out int overflowBit) 
{ 
    unchecked 
    { 
     int c = a + b; 
     overflowBit = (int)((uint)((a^c) & ~(a^b)) >> 31); 
     return c; 
    } 
} 
+0

雖然我可能不會使用這個(BigInteger服務於我的目的),但它確實以非常酷的方式回答了這個問題。缺點是你可能無法做類似的乘法。 – Boyd

+0

絕對 - 這就是爲什麼我在開始時提到它是有用的。但很高興你喜歡它:-) –

0

如果你想用carry進行加減運算,我真的推薦使用uint而不是int!在做計算之前投兩值ulong

//Adds a and b 
uint[] a = ... , b = ... ;//input 
ulong carry=0 
for(int i=0;i<length;i++) 
{ 
    carry += (ulong)a[i] + (ulong)b[i]; 
    uint result = (uint)carry; 
    carry >>= 32;//divide by 2^32 
    //TODO: store result 
} 
//TODO: process remaining carry 

我曾與符號擴展問題,當我第一次implemnted這樣的事情,因此無符號類型無處不在。

+0

您對擴展符號有什麼樣的問題? – Boyd