gpt4 book ai didi

c# - 将 decimal 转换为 double 时的奇怪行为

转载 作者:太空狗 更新时间:2023-10-30 00:14:59 25 4
gpt4 key购买 nike

我在将 decimal 转换为 double 时遇到奇怪的问题。

以下代码返回 true:

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

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

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

当我想使用 Math.Pow 并被迫将 decimal 转换为 double 时,我遇到了这个问题,因为 decimal 没有 Math.Pow 重载。

这是记录在案的行为吗?当我被迫将 decimal 转换为 double 时,如何避免这种情况?

来自 Visual Studio 的屏幕截图:

Screenshot from Visual Studio

转换 Math.Round 使我的结果加倍:

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

更新

好的,我正在重现问题如下:

  1. 当我运行 WPF 应用程序并在它启动后检查 watch 中的输出时,我得到了 true 就像在空项目中一样。
  2. 有一部分应用程序将值从 slider 发送到计算算法。我得到了错误的结果,我在计算方法上设置了断点。现在,当我检查监 window 口中的值时,我得到 false(没有任何修改,我只是刷新监 window 口)。
  3. 一旦我在某个较小的项目中重现该问题,我就会将其发布在这里。

更新 2

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

最佳答案

人们在这里的评论中报告说,比较的结果有时是真的,有时是假的。

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

让我确保您理解我所说的“他们认为合适”的意思。您可以出于任何原因获得不同的结果。您可以在调试和零售中获得不同的结果。如果让编译器在常量中进行计算,而让运行时在运行时进行计算,则会得到不同的结果。当调试器运行时,您可以获得不同的结果。您可以在运行时和调试器的表达式计算器中得到不同的结果。 任何理由。双重算术本质上是不可靠的。这是由于浮点芯片的设计;在不显着降低性能的情况下,这些芯片上的双重运算无法提高可重复性。

出于这个和其他原因您几乎不应该比较两个 double 是否完全相等。相反,减去 double 值,看看差异的绝对值是否小于合理范围。

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

双0.01实际上是二进制编号1.0100011111111111110010001101111111111111101000111111 x 2 -7 ,在十进制中为0.010000000000000000000000000000000020816816817171717172168516851943776776776777702010000000000000000000000000000000000000000000000000000000000000000000000000000000000。这是最接近你可能在 double 中达到 0.01 的值。如果您需要准确表示该值,则使用小数。这就是为什么它被称为十进制

顺便说一下,我已经在 StackOverflow 上多次回答过这个问题的变体。例如:

Why differs floating-point precision in C# when separated by parantheses and when separated by statements?

此外,如果您需要“拆开”一个 double 以查看它的位是什么,我不久前编写的这个方便的代码非常有用。它要求您安装 Solver Foundation,但这是免费下载的。

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

关于c# - 将 decimal 转换为 double 时的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18361015/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com