3

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?

asked Mar 24, 2014 at 14:35
0

3 Answers 3

3

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
answered Mar 24, 2014 at 14:40
Sign up to request clarification or add additional context in comments.

Comments

2

What about doing this the other way around?

byte oldValue = 240;
byte newValue;
unchecked
{
 newValue = (byte)((oldValue + 24) % 255);
}
// if (newValue < oldValue), overflow happened and newValue 
// contains the "amount" of overflow

(the % 255 is needed on byte, since byte + byte is an integer, perhaps for portability reasons)

Note that this only works if the number you're adding is the same size as the value (ie. both are bytes, both are ints...) and it only works for adding. For subtracting, you'd simply invert the comparison (newValue > oldValue). It isn't of any use when multiplicating.

The pro of this method is that it doesn't depend on having a data type big enough not to cause overflow in the first place, which is a weakness of some of the other methods suggested.

answered Mar 24, 2014 at 14:48

Comments

2

How about something like this?

if (byte.MaxValue - 240 < 24)
{
 // handle overflow
}

For underflow to, say, see if you can do 24 - 240

if (byte.MinValue + 240 > 24)
{
 // handle underflow
}
answered Mar 24, 2014 at 14:40

2 Comments

Correct me if I am mistaken, but this doesn't detect underflows, or does it?
Right. You would have to write a similar check for underflows.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.