Search code examples
c#exceptionmathinteger-overflowinteger-arithmetic

Check for arithmetic overflow and get overflow count?


What would be the most appropriate way to detect an arithmetic overflow (or underflow for that matter) and get the overflow count?

For easier understanding I'll will be using byte, but this is the same for int or any other basic integer type. Now imagine I have the value 240 and want to add 24 to it. Clearly an arithmetic overflow. Using the checked keyword this is easy to detect at least ...

byte value = 240;
try
{
    checked
    {
        value += 24;
    }
}
catch (OverflowException e)
{
    // handle overflow, get overflow count via % etc.
}

... by throwing an exception.

This is what I am using at the moment.

However, I don't quite like the exception handling in this one. Exceptions are usually pretty expensive, and I want to avoid them right from the start. To me this seems like a Boneheaded-Exception anyways. Is there some arithmetic wizardry I could do to detect this upfront?


Solution

  • I guess you could check if the difference between the current value and the maximum if large enough to do the addition:

    var difference = byte.MaxValue - value;
    
    if(difference >= 24)//OK to add 24
    else//will cause overflow
    

    To detect underflows you can use the byte.MinValue value instead:

    var difference = value - byte.MinValue;
    if(difference >= 24)//OK to subtract 24
    else//will cause underflow
    

    With these in mind you could go as far as making some extension methods for them:

    public static class OverflowExtensions
    {
        public static bool WillAdditionOverflow(this byte b, int val)
        {
            return byte.MaxValue - b < val;
        }
    
        public static bool WillSubtractionUnderflow(this byte b, int val)
        {
            return b - byte.MinValue < val;
        }
    }
    

    Which you can use like so:

    using MyApp.OverflowExtensions;
    //...
    
    if(value.WillAdditionOverflow(24))
        //value + 24 will cause overflow
    
    if(value.WillSubtractionUnderflow(24))
        //value - 24 will cause underflow