Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I gracefully test for overflow situations in C#?

Update: I'm going to leave it as is: The performance hit of a exception (very rare) is better than the probably performance hit for checking on each operation (common)


I'm trying to support an "EstimatedRowCount" that in one case would be the product of two sub-cursors that are joined together:

estimatedRowCount = left.EstimatedRowCount * right.EstimatedRowCount;
return estimatedRowCount;

Of course, if left and right are big enough, this will throw an OverflowException.

Here, I don't really care if estimatedRowCount is 100% accurate, just big enough to know that this cursor is holding a lot of data.

Right now, I'm doing this:

// We multiply our rowcount
Int64 estimRowCount = 0;
try
{
    estimRowCount = leftRowCount * rightRowCount;
}
catch (OverflowException)
{
    // Ignore overflow exceptions
    estimRowCount = Int64.MaxValue;
}

return estimRowCount;

Is there a better way to test for overflow operations so I don't have to do the try{}catch to guard?

like image 306
Eli Avatar asked Dec 22 '22 13:12

Eli


2 Answers

This sounds like a good use case for the 'unchecked' keyword.

To use, simply wrap your assignment in an 'unchecked' block:

Int64 estimRowCount = 0;
unchecked
{
    estimRowCount = leftRowCount * rightRowCount;
}

Then test to see if the result is negative - if it is, it overflowed:

if (estimRowCount > 0) estimRowCount = Int64.MaxValue;

You'll need to ensure in this case that neither leftRowCount nor rightRowCount can be negative, but given the context I don't think that'll occur.

like image 59
Erik Forbes Avatar answered Jan 07 '23 10:01

Erik Forbes



if (Int64.MaxValue / leftRowCount <= rightRowCount)
{
    estimRowCount = leftRowCount * rightRowCount
}
else
{
    estimRowCount = Int64.MaxValue;
}

Not sure if I could explain myself without an editor. But, I hope you get the idea.

like image 45
shahkalpesh Avatar answered Jan 07 '23 08:01

shahkalpesh