如何在不准确的计算上获得例外?

时间:2016-08-15 09:29:37

标签: c# decimal precision

每当我们需要高十进制精度时,我们使用小数来进行计算。有没有办法检查精度是否足以进行计算?

我想让以下代码抛出异常:

decimal almostMax = Decimal.MaxValue - 1;
decimal x = almostMax + 0.1m; // This should create an exception, since x equals almostMax.
Assert.AreEqual(x, almostMax); // This does NOT fail.

在实际代码中它并不重要,但保证安全是件好事。

2 个答案:

答案 0 :(得分:3)

此扩展方法应该有所帮助。它会反转操作并检查是否可以从结果中正确计算输入参数。如果情况并非如此,那么操作会造成精确损失。

public static decimal Add(this decimal a, decimal b)
{
    var result = a + b;

    if (result - a != b || result - b != a)
        throw new InvalidOperationException("Precision loss!");

    return result;
}

工作示例:https://dotnetfiddle.net/vx6UYY

如果你想使用+之类的常规运算符,你必须使用Philipp Schmid's solution并在你自己的十进制类型上实现运算符。

答案 1 :(得分:0)

您可以创建一个SaveDecimal类并重载+运算符
https://msdn.microsoft.com/en-us/library/aa288467%28v=vs.71%29.aspx

public class SafeDecimal
{
    private decimal DecValue;

    public SafeDecimal(decimal Value)
    {
        DecValue = Value;
    }

    public decimal GetValue()
    {
        return DecValue;
    }

    public static SafeDecimal operator +(SafeDecimal A, SafeDecimal B)
    {
        decimal almostMax = Decimal.MaxValue - 1;

        checked
        {
            if (almostMax <= A.GetValue() + B.GetValue())
                throw new Exception("----scary error message----");
        }

        return new SafeDecimal(A.GetValue() + B.GetValue());
    }
}