2015-08-15 66 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