检查计算是否超过MaxValue

时间:2012-09-01 19:02:27

标签: c# overflow decimal

我目前有以下方法,它返回百分比值。例如,对于350,000美元的项目价格和7%的百分比,它返回​​24,500。

    public static decimal GetPercentValue(decimal? percentage, decimal baseValue)
    {
        decimal result = 0m;

        if (percentage != null)
        {
            try
            {
                result = Convert.ToDecimal(baseValue * percentage / 100m);
            }
            catch (OverflowException)
            {
                result = 0;
                Logger.Warn("OverflowException caught in GetPercentValue() - should better be handled UI-Sided!");
            }
        }

        return result;
    }

我不认为这是以正确的方式处理的,所以有没有办法在这种情况下避免异常?

当用户输入像999,999,999,999,999,999这样的疯狂号码并计算9999999999%时,会抛出OverflowException。这样我就无法检查percentagebaseValue <= decimal.MaxValue只是因为它们不是......计算结果本身就超过了小数范围。

2 个答案:

答案 0 :(得分:1)

这是一个老问题,但我遇到了类似的问题,并考虑提供一种可能的替代解决方案。当两个数字的某些计算产生的数字大于MaxValue时,就会出现问题。这会导致异常,很难以通常的方式进行测试:

decimal existingValue = decimal.MaxValue;
decimal newValue = (decimal)100;

//doesn't work -- exception thrown here
if(existingValue + newValue <= decimal.MaxValue)
{

}

似乎对我有用的解决方案(不使用Try-Catch块)是重写方程式,在本例中是减法:

if(decimal.MaxValue - existingValue >= newValue)
{
    //DoSomething
}

由于减法,不会超出MaxValue。我还没有尝试过乘法/除法的例子,但我猜它也会起作用。

答案 1 :(得分:0)

错误处理应该(很可能)在方法之外完成。现在你正在隐藏异常并返回错误的结果(发生错误时返回0)。您的方法的调用者无法判断结果是否正确或是否是由于OverflowException。

我会改写这样的方法:

public static decimal GetPercentValue(decimal? percentage, decimal baseValue)
{
    if (percentage == null)
        return 0;

    return baseValue*(percentage.Value/100);
}

并且可选地添加一个验证方法,用户可以调用该方法在调用实际方法之前检查参数。验证错误可以在UI中显示:

public static string ValidatePercentValue(decimal? percentage, decimal baseValue)
{
    try
    {
        GetPercentValue(percentage, baseValue);
        return null;
    }
    catch (Exception ex)
    {
        return ex.Message;
    }
}

除此之外......

baseValue*(percentage.Value/100)

......比......更好。

baseValue*percentage.Value/100

尝试计算decimal.MaxValue的100%。第一个工作,而第二个抛出OverflowException。