繁体   English   中英

将十进制转换为双精度时的奇怪行为

[英]Strange behavior when casting decimal to double

我在将小数转换为双精度时遇到奇怪的问题。

以下代码返回true:

Math.Round(0.010000000312312m, 2) == 0.01m //true

但是,当我将其转换为两倍时,它返回false:

(double)Math.Round(0.010000000312312m, 2) == (double)0.01m //false

我想使用Math.Pow时遇到了这个问题,由于十进制没有Math.Pow重载,因此不得不将十进制强制转换为双精度。

这是有据可查的行为吗? 当我不得不将十进制强制转换为双精度时如何避免呢?

Visual Studio的屏幕截图:

Visual Studio的屏幕截图

将Math.Round强制转换为以下结果的两倍:

(double)Math.Round(0.010000000312312m, 2)   0.0099999997764825821   double
(double)0.01m   0.01    double

更新

好的,我将问题重现如下:

  1. 当我运行WPF应用程序并在启动后立即在watch中检查输出时,我像在空项目上一样得到了真。
  2. 应用程序的一部分将值从滑块发送到计算算法。 我得到错误的结果,并在计算方法上设置了断点。 现在,当我在监视窗口中检查值时,我得到了false(不做任何修改,我只是刷新监视窗口)。
  3. 一旦在较小的项目中重现该问题,我将在此处发布。

更新2

不幸的是,我无法在较小的项目中重现该问题。 我认为埃里克(Eric)的回答解释了原因。

人们在这里的评论中报告说,比较的结果有时是正确的,有时是错误的。

不幸的是,这是意料之中的。 C#编译器,抖动和CPU都允许在超过 64位双精度上双打执行算术, 因为他们认为合适的 这意味着有时看起来像“相同”计算的结果可以在一个计算中以64位精度完成,而在另一计算中以80或128位精度完成,并且两个结果的最后一位可能有所不同。

让我确保您理解“他们认为合适”的意思。 无论出于何种原因,您都可以得到不同的结果。 您可以在调试和零售中获得不同的结果。 如果使编译器使用常量进行计算,并且使运行时在运行时进行计算,则可以获得不同的结果。 当调试器运行时,您可以获得不同的结果。 您可以在运行时和调试器的表达式评估器中获得不同的结果。 任何理由 双重运算本质上不可靠的 这是由于浮点芯片的设计所致。 在不影响性能的前提下,无法使这些芯片上的双重算术具有更高的可重复性。

由于这个原因和其他原因, 您几乎绝不应该为完全相等而比较两个两倍 而是减去双精度值,然后查看差的绝对值是否小于合理范围。

此外,重要的是要了解为什么将 精度数舍入到小数点两位很困难。 非零有限双精度数是形式为(1 + f)x 2 e的数字 ,其中f是分母为2的幂的分数,e是指数。 显然,不可能以这种形式表示0.01,因为无法从等于2的幂的分母中得到等于10的幂的分母。

双精度0.01实际上是二进制数1.0100011110101110000101000111101011100001010001111011 x 2 -7 (十进制是0.01000000000000000020816681711721685132943093776702880859375)。 那是您可能双倍接近 0.01的最接近值 如果需要精确表示该值,请使用小数 这就是为什么将其称为小数

顺便说一句,我已经在StackOverflow上多次回答了这个问题。 例如:

当用括号分隔和用语句分隔时,为什么C#中的浮点精度不同?

另外,如果您需要“分解”双精度码以查看其位数,那么我在前一阵子打过的方便代码非常有用。 它要求您安装Solver Foundation,但这是免费下载。

http://ericlippert.com/2011/02/17/looking-inside-a-double/

这是记录的行为。 十进制数据类型比双精度类型更精确。 因此,当您从十进制转换为双精度时,可能会丢失数据。 这就是为什么要求您进行类型的显式转换的原因。

有关更多信息,请参见以下MSDN C#参考:

十进制数据类型: http : //msdn.microsoft.com/zh-cn/library/364x0z75(v=vs.110).aspx

双重数据类型: http : //msdn.microsoft.com/zh-cn/library/678hzkk9(v=vs.110).aspx

转换和类型转换: http : //msdn.microsoft.com/zh-cn/library/ms173105.aspx

暂无
暂无

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

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