很容易讓C#在整數溢出時拋出異常。但是,這不是我要找的。我想檢測溢出,所以我可以繼續高階計算。我正在構建一個大的int實現。整數溢出檢測C#添加
我可以捕獲溢出異常,但這對性能並不好。更不用說它在概念上是不正確的。
任何想法如何檢查溢出沒有例外?
很容易讓C#在整數溢出時拋出異常。但是,這不是我要找的。我想檢測溢出,所以我可以繼續高階計算。我正在構建一個大的int實現。整數溢出檢測C#添加
我可以捕獲溢出異常,但這對性能並不好。更不用說它在概念上是不正確的。
任何想法如何檢查溢出沒有例外?
如果您正在尋找攜帶行爲,其他答案/評論涵蓋相當不錯。然而,我發現最初的問題是一個有趣的大腦難題(儘管實際上並不實用),具體來說,檢測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;
}
}
雖然我可能不會使用這個(BigInteger服務於我的目的),但它確實以非常酷的方式回答了這個問題。缺點是你可能無法做類似的乘法。 – Boyd
絕對 - 這就是爲什麼我在開始時提到它是有用的。但很高興你喜歡它:-) –
如果你想用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這樣的事情,因此無符號類型無處不在。
您對擴展符號有什麼樣的問題? – Boyd
請添加一個可能溢出的代碼示例。 – cyberj0g
你知道C#中有一個'BigInteger'類,或者你只是爲了練習而這麼做? – Rob
當您使用Parse()或者當您正在執行數學運算時,我認爲溢出與Single(),Double()或Float()對象有關。如果由於Parse而發生錯誤而不是使用ParseExact()。如果是數學運算,通常由分母的分母非常小(或零)引起。所以在分割之前檢查分母。 – jdweng