[英]Cast float to decimal in C#. Why is (decimal)0.1F == 0.1M not false because of rounding?
如果我在C#中评估以下内容,则会产生true:
(decimal)0.1F == 0.1M
为什么转换为float并返回十进制不会引入任何舍入错误?
观察到的行为的原因是Microsoft的C#实现仅使用七位小数将float
转换为decimal
。
Microsoft的C#实现使用.NET。 当.NET将单精度浮点数转换为十进制数时, 它最多产生七位有效数字 ,使用舍入到最接近舍入任何残差。
源文本0.1F
变为单精度值0.100000001490116119384765625。 当它转换为带有七位有效数字的十进制数时,结果恰好为0.1。 因此,在Microsoft的C#中, (decimal) 0.1F
产生0.1,所以(decimal) 0.1F == 0.1M
为真。
我们可以将它与非Microsoft实现Mono C#进行比较。 这个在线编译器可用在这里 。 在其中, Console.WriteLine((decimal)0.1F);
打印“0.100000001490116”, (decimal)0.1F == 0.1M
计算结果为false。 将float
转换为decimal
时,Mono C#似乎产生超过七位数。
用于显式转换的Microsoft C#文档说:“当您将float
或double
转换为decimal
,源值将转换为十进制表示,并在需要时在第28个小数位后舍入到最接近的数字。”我会将此解释为表示真的float
值,0.100000001490116119384765625,正好转换为decimal
(因为它需要少于28位),但显然情况并非如此。
我们可以进一步确认这一点并通过将float
转换为double
然后转换为decimal
来说明发生了什么。 Microsoft的C#使用15位有效数字将double
转换为decimal
。 如果我们将0.1F
转换为double
,则值不会改变,因为double
可以精确地表示每个float
值。 因此(double) 0.1F
与0.1F
,0.100000001490116119384765625具有完全相同的值。 但是,现在,当它转换为decimal
,会产生15位数字。 在Microsoft C#实现中, Console.WriteLine((decimal)(double) 0.1F);
打印“0.100000001490116”和(decimal)(double) 0.1F == 0.1M
精度(decimal)(double) 0.1F == 0.1M
计算结果为false。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.