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

C# 从双精度转换为十进制时避免溢出异常,c#,exception,floating-point,overflowexception,C#,Exception,Floating Point,Overflowexception,将double(或float)转换为decimal时,可能会出现溢出异常。所以我写了一个小的扩展方法,通过饱和来防止这种情况: public static decimal ToDecimalSafe(this double input) { try { return (decimal)input; } catch (OverflowException) { if (input < 0) retu

double
(或
float
)转换为
decimal
时,可能会出现溢出异常。所以我写了一个小的扩展方法,通过饱和来防止这种情况:

public static decimal ToDecimalSafe(this double input)
{
    try
    {
        return (decimal)input;
    }
    catch (OverflowException)
    {
        if (input < 0)
            return decimal.MinValue;
        else
            return decimal.MaxValue;
    }
}
公共静态十进制ToDecimalSafe(此双输入)
{
尝试
{
返回(十进制)输入;
}
捕获(溢出例外)
{
如果(输入<0)
返回decimal.MinValue;
其他的
返回decimal.MaxValue;
}
}
问题是,这种溢出在我的用例中经常发生,打破了“异常应该是异常”的准则。这会减慢应用程序的速度,是的,但这并不十分重要。真正的问题是,在调试过程中,它还会导致许多第一次出现的异常,这很烦人。下面是第二次尝试,似乎效果不错:

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;
    }
}
公共静态十进制ToDecimalSafe(此双输入)
{
if(输入<(双精度)十进制最小值)
返回decimal.MinValue;
如果(输入>(双精度)十进制.MaxValue)
返回decimal.MaxValue;
尝试
{
返回(十进制)输入;
}
捕获(溢出例外)
{
如果(输入<0)
返回decimal.MinValue;
其他的
返回decimal.MaxValue;
}
}
我留下了“尝试捕捉”按钮,以确保捕捉到一些可能的边缘案例。这里的问题是:是否存在任何边缘情况,或者我是否可以省略try-catch


double
是否可以是
=(double)decimal.MinValue
该异常将不再发生。您可以用这种方式修改代码

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;
}
公共静态十进制ToDecimalSafe(此双输入)
{
if(输入<(双精度)十进制最小值)
返回decimal.MinValue;
else if(输入>(双精度)decimal.MaxValue)
返回decimal.MaxValue;
其他的
返回(十进制)输入;
}
您也可以使用特定的convert方法,但它不会阻止异常


如果您的问题只是调试中断,这很烦人,那么我建议您查看一下[DebuggerStepThrough]或[DebuggerHidden]属性

如果这种情况经常发生,那么您首先为什么要使用
十进制
而不是
双精度
?听起来你在工程或科学计算中使用的是
十进制
,而不是金融计算-这不是正确的做法。@MatthewWatson这不是什么高精度的东西。它只是用于处理双精度和用户提供并使用十进制的设置的一些硬件之间的交互。硬件提供了一些限制,这些限制的范围往往大得离谱,用户根本不关心这些限制。@MatthewWatson“相当经常”并不是指每秒1000次,而是指在获取这些设置限制时总共达到100次。听起来好像某个地方有人在对科学或工程数据使用
decimal
,这是错误的。对于从硬件发送/检索的数字,使用
decimal
尤其不好,因为硬件肯定不会理解.Net
decimal
结构-但可能会对IEEE标准的
double
类型感到满意。@MatthewWatson它用于机器参数,它不需要太多的精度,而且通常固定在几个分数位置。在这种情况下,decimal的表示属性非常方便。NumericUpDown控件也很方便,而且它们不理解双精度。当然,参数在发送到硬件之前会转换为双精度。我不知道这些属性,谢谢。非常有用。顺便说一句,我花了几分钟的时间试图自己解决这个问题,似乎给(double)decimal.MinValue或(double)decimal.MaxValue作为输入会引发异常。使比较包含(=)可以解决问题,但我必须找出如何找到稍微在范围内的值,以查看是否崩溃。您还需要处理double.NaN值