简体   繁体   English

从双精度转换为十进制时避免溢出异常

[英]Avoiding OverflowException when converting from double to decimal

When converting double (or float ) to decimal , overflow exceptions are possible.double (或float )转换为decimal ,可能会出现溢出异常。 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.我离开了 try-catch 以确保我捕获了一些可能的边缘情况。 The question here is: are there any edge cases or can I just omit the try-catch?这里的问题是:是否有任何边缘情况,或者我可以省略 try-catch 吗?

Can a double be >= (double)decimal.MinValue and <= (double)decimal.MaxValue and still cause an overflow when converting? double可以是>= (double)decimal.MinValue<= (double)decimal.MaxValue并且在转换时仍然会导致溢出吗?

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如果您的问题只是令人讨厌的调试中断,那么我建议您查看 [DebuggerStepThrough] 或 [DebuggerHidden] 属性

我使用了cristallo的答案,它对我有用,唯一的提示是您也应该考虑NaN。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM