relatively_random
relatively_random

Reputation: 5126

Avoiding OverflowException when converting from double to decimal

When converting double (or float) to decimal, overflow exceptions are possible. So I've written this small extension method that prevents this by saturating:

public static decimal ToDecimalSafe(this double input)
{
    try
    {
        return (decimal)input;
    }
    catch (OverflowException)
    {
        if (input < 0)
            return decimal.MinValue;
        else
            return decimal.MaxValue;
    }
}

The issue is, this overflow happens pretty often in my use case, breaking the "exceptions should be exceptional" guideline. This slows down the application, yes, but that's not terribly important. The real issue is it also causes lots of first-chance exceptions during debugging, which is annoying. Here's attempt number two, which seems to be working fine:

public static decimal ToDecimalSafe(this double input)
{
    if (input < (double)decimal.MinValue)
        return decimal.MinValue;
    if (input > (double)decimal.MaxValue)
        return decimal.MaxValue;

    try
    {
        return (decimal)input;
    }
    catch (OverflowException)
    {
        if (input < 0)
            return decimal.MinValue;
        else
            return decimal.MaxValue;
    }
}

I left the try-catch to make sure I catch some possible edge cases. The question here is: are there any edge cases or can I just omit the try-catch?

Can a double be >= (double)decimal.MinValue and <= (double)decimal.MaxValue and still cause an overflow when converting?

Upvotes: 3

Views: 4342

Answers (1)

cristallo
cristallo

Reputation: 2089

The exception will not happen anymore. You can modify your code in this way.

public static decimal ToDecimalSafe(this double input)
{
    if (input < (double)decimal.MinValue)
        return decimal.MinValue;
    else if (input > (double)decimal.MaxValue)
        return decimal.MaxValue;
    else
        return (decimal)input;
}

You can also use the specific convert method but it does not prevent the exception

Convert.ToDecimal

If your problem is just the debugging break that is annoying then I suggest to take a look at [DebuggerStepThrough] or [DebuggerHidden] attributes

Upvotes: 2

Related Questions