将双精度变量转换为十进制

138

如何将 double 强制转换为用于货币开发的 decimalM 放在哪里?

decimal dtot = (decimal)(doubleTotal);
5个回答

128

当您进行类型转换时,只需要使用M来表示数字文字即可:

decimal dtot = (decimal)doubleTotal;

请注意,浮点数不适合保留精确值,因此如果您先将数字相加然后转换为Decimal,可能会出现舍入误差。您可能想在将它们相加之前将数字转换为Decimal,或者确保这些数字首先不是浮点数。


作为后续问题,为什么需要显式转换?我已经尝试过了,但会出现错误,不能将double显式转换为decimal,但是decimal不是更精确吗?(就像从int到double的转换可以是隐式的一样。) - user2821275
7
@Cortana: 十进制的精度更高,但范围更小。double类型的值可能超出十进制数的范围,可参考:https://dev59.com/-Gsz5IYBdhLWcg3wj4gc - Guffa

59

您可以这样将double转换为decimal,而不需要使用M文字后缀:

double dbl = 1.2345D;
decimal dec = (decimal) dbl;

声明新的十进制文本值时,应该使用 M

decimal dec = 123.45M;

(没有 M,123.45 被视为双精度数并无法编译。)


36

使用默认转换类:Convert.ToDecimal(Double)


1
不行,因为它会抛出OverflowException异常。 double vol_y = (double)Decimal.MaxValue + 10E+28D; Console.WriteLine("Convert.ToDecimal(vol_y) = " + Convert.ToDecimal(vol_y)); - ToXinE
9
在我看来,在大多数情况下,一个OverflowException比默默地创建错误数据更好。 - this.myself

16
Convert.ToDecimal(the double you are trying to convert);

2
我学到了在C#中,Convert类比强制类型转换更加灵活、安全。 - Tom
4
“Safe”指的是在运行时,当无法转换时会抛出异常而不是编译器错误?我已经因此遭受了很多次伤害,所以主动避免使用Convert... - Peter Ritchie
9
@PeterRitchie的帖子有点老了,但还是应该说一下: 直接调用Convert方法会更加合适。也许我只是一个优化迷,但少解析一条指令是一种优势(因为使用(Type)强制转换语法只是一个调用Convert的操作符重载)。 - Mike Johnson
2
@PeterRitchie:从语言设计的角度来看,最好要求程序员使用两种转换方法之一,而不是允许从doubledecimal进行类型转换。因为对于像(1000000.0/3.0)这样的double值,在某些情况下,我们希望截取“多余”的精度,得到333333.333333333D,但在其他情况下,我们希望保留它,得到333333.333333333313931D。代码应该指定如何执行转换,而不仅仅是说“转换为decimal”。 - supercat
2
@supercat这似乎与我的第一个评论无关,因为使用Convert.ToDecimal(double)(decimal)doubleTotal相同,除非doubleTotal更改为不同的类型,否则您可能会避免编译时错误并引入更难以找到的运行时错误,因为会调用不同的 ToDecimal重载。强制转换运算符更加明确... - Peter Ritchie
显示剩余4条评论

3

这是一个旧问题,我确实利用了这里显示的一些答案。然而,在我的特定场景中,我想要转换为 decimal double 值通常比 decimal.MaxValue 大。因此,我编写了这个扩展方法,而不是处理异常:

    public static decimal ToDecimal(this double @double) => 
        @double > (double) decimal.MaxValue ? decimal.MaxValue : (decimal) @double;

如果您不想烦恼处理溢出异常,并且在发生这种情况时只想保留最大可能的值(我的情况),那么上述方法是有效的,但我知道对于许多其他情况,这不是预期的行为,可能需要异常处理。

4
在以下情况下,这将会失败:double _double = (double)decimal.MaxValue;我建议在比较时使用 >= public static decimal ToDecimal(this double _double) => _double >= (double) decimal.MaxValue ? decimal.MaxValue : (decimal) _double; - Martin Eyles

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接