我使用Visual Studio 2010编写C++应用程序。在其中之一中,我将类型从double转换为integer,如下所示:

intAmount = (int)doubleAmount;

其中intAmount是整数类型,而doubleAmount是 double 类型。

我尝试显示这些,当doubleAmount = 16200000时出现问题,它显示为16199999而在其他情况下,我不会遇到任何问题。

例如:doubleAmount = 1540000018000000时。这两个值正确显示。

经过一番分析,我了解到这不是正确的类型转换方式。因此,我将其修复如下:
intAmt = doubleAmount >= 0 ? (int)(doubleAmount+0.5) : (int)(doubleAmount-0.5);

上面的修复程序对我来说效果很好。

但是我的问题是:为什么仅当doubleAmount = 16200000时才存在此问题。

有人可以建议吗?

编辑请注意,计算doubleAmount = 0.81 * 20000000等于16200000

最佳答案

首先,让我通过一个简单的测试程序来证明您声称正在发生的事情并未发生:

#include <iostream>

int main()
{
    double doubleAmount = 16200000.0;
    int intAmount = (int)doubleAmount;
    std::cout << intAmount << std::endl;
}

这个输出

16200000

程序中发生的事情是,尽管您认为浮点值是16200000.0,但实际上它类似于16199999.xxx。您的值很可能来自某种计算,该计算得出的值接近16200000.0,但略小于16200000.0。当您截断到int时,您会得到16199999

为什么您认为该值是16200000.0,而实际上却是一个稍小的值呢?我再次推测,但最有可能的原因是,您没有将数值精确地打印出来。确保当您打印出该值或在调试器中对其进行检查时,您正在观察该值的全部精度。

这种现象在浮点计算中很常见。有限精度二进制浮点数据类型不能表示所有数字,也不能完全执行所有计算。这些不精确性是二进制浮点运算中固有的。

如果不知道您要解决的问题,也不知道值是如何计算的,就不可能为您提供正确的解决方案的建议。舍入到最接近的整数(使用std::roundstd::lround)确实可以解决您的问题。但是,如果没有更多细节,就不可能确定地说出来。

最后,如果您还没有这样做,该是阅读David Goldberg的经典著作What Every Computer Scientist Should Know About Floating-Point Arithmetic的时候了。

09-25 18:27