c#

时间:2016-05-25 15:39:47

标签: c# .net double multiplication

我有一个简单的乘法问题,我无法理解......我正在使用.Net Framework 4,并在x86中构建。我正在执行以下代码:

double x = 348333.673899683;
double y = 4521014.98461396;
double aux = x * y;

aux的预期值是 1574821759346,09949827752137468 (我用一个简单的计算器完成了它)。但是,我在aux中获得的值是 1574821822464 。看到精度错误,即使整数部分已更改。

如果我在乘法中放置一个断点并将鼠标悬停在de *运算符上,我会看到 x * y = 1574821759346.0994 ,这是好的。如果我将鼠标悬停在aux变量上,我会看到 aux = 1574821822464

为了澄清最后一段,下面可以看到两张图片:

enter image description here

enter image description here

首先,我认为可能是因为x86编译,但是阅读下一篇文章,我放弃了这个选项:

The Double Byte Size in 32 bit and 64 bit OS

我无法理解这里发生了什么。任何帮助将不胜感激。

---编辑更多信息---

我正在使用VS2015。我已经添加了三行来调试它:

log.Info(x);
log.Info(y);
log.Info(aux);

要显示我正在使用库 log4net 的日志。输出是:

23322 [8] INFO Art.Model.Scenarios (null) - 348333,673899683
24745 [8] INFO Art.Model.Scenarios (null) - 4521014,98461396
26274 [8] INFO Art.Model.Scenarios (null) - 1574821822464

所以这不是debuger中的错误。如果我创建一个全新的项目和解决方案,它可以正常工作,但我无法理解为什么不能在这个解决方案中工作。

---第二次编辑---

感谢我的评论,我尝试了一些新的东西:

double x = 348333.673899683;
double y = 4521014.98461396;
double aux = x * y;

decimal xx = 348333.673899683m;
decimal yy = 4521014.98461396m;
decimal auxx = xx * yy;

log.Info(x);
log.Info(y);
log.Info(aux);

log.Info(xx);
log.Info(yy);
log.Info(auxx);

结果是:

16129 [8] INFO Art.Model.Scenarios (null) - 348333,673899683
16145 [8] INFO Art.Model.Scenarios (null) - 4521014,98461396
16145 [8] INFO Art.Model.Scenarios (null) - 1574821822464
16145 [8] INFO Art.Model.Scenarios (null) - 348333,673899683
16145 [8] INFO Art.Model.Scenarios (null) - 4521014,98461396
16145 [8] INFO Art.Model.Scenarios (null) - 1574821759346,0994982775213747

因此它适用于十进制,但不适用于 double 。有人可以解释一下吗?我不明白为什么会这样。

1 个答案:

答案 0 :(得分:2)

最有可能的是,如果您使用的是DirectX(我能找到问题背后的唯一原因),这个问题似乎与每次创建和/或处理设备时强制FPU达到单一精度的事实有关。模式,因此失去准确性并导致双,长,十进制变量被截断。如果我尝试使用IEEE-754浮点转换器并输入您的数据,我会得到这个结果,这正是您的情况:您的数据在某些时候被读作双精度数,但随后被截断为单个.precision浮点数,如你所见:

enter image description here

可以通过在标志FpuPreserve下显式构建Device对象来解决此问题。

我也有这个问题,并且在开始时虽然关于不正确的强制转换,但是在经过长时间的跟踪后发现在构建DirectX设备对象后,值被截断了。