Boyd
Boyd

Reputation: 103

Integer overflow detection C# for Add

It's easy to get C# to throw an exception on an integer overflow. However, that's not what I'm looking for. I want to detect the overflow so I can continue the calculation in the high order. I'm building a sort of big int implementation.

I could catch the overflow exception, but that's not great for performance. Not to mention that it's conceptually incorrect.

Any idea how to check for overflow without exceptions?

Upvotes: 1

Views: 1667

Answers (2)

Ivan Stoev
Ivan Stoev

Reputation: 205649

If you are seeking for a carry behavior, other answers/comments cover that pretty well. However, I find the original question to be an interesting brain puzzle (although not practically useful), specifically what is the best performance pure C# way to detect 2 signed integers add overflow. Ideally it would generate a minimum IL instructions with no branches. Here is the best I ended up - one with bool flag (true when overflow, false otherwise) and another with int "bit" (1 when overflow, 0 otherwise). Both satisfy the above criteria, "bit" version has few less IL instructions. Enjoy:-)

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;
    }
}

Upvotes: 5

Zotta
Zotta

Reputation: 2603

If you want to implement addition and subtraction with carry, I really recommend using uint instead of int! Cast both values to ulong before doing the calculation:

//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

I had problems with sign extension, when i first implemnted something like this, hence the unsigned types everywhere.

Upvotes: 1

Related Questions