C++ 中的双整数转换

use*_*047 2 c++ memory-management type-conversion visual-studio-2010

我使用Visual Studio 2010编写 C++ 应用程序。在其中之一中,我将类型从双精度转换整数,如下所示:

intAmount = (int)doubleAmount;
Run Code Online (Sandbox Code Playgroud)

其中intAmount整数类型,doubleAmount双精度类型。

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

例如: whendoubleAmount = 15400000或 it is 18000000。这 2 个值显示正确。

经过一些分析,我明白这不是类型转换的正确方法。所以我将其修复如下:

intAmt = doubleAmount >= 0 ? (int)(doubleAmount+0.5) : (int)(doubleAmount-0.5);
Run Code Online (Sandbox Code Playgroud)

上述修复对我来说效果很好。

我的问题是:为什么这个问题只存在于doubleAmount = 16200000.

任何人都可以请建议吗?

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

Dav*_*nan 5

首先,让我用一个简单的测试程序证明你声称正在发生的事情并没有发生:

#include <iostream>

int main()
{
    double doubleAmount = 16200000.0;
    int intAmount = (int)doubleAmount;
    std::cout << intAmount << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

这输出

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

  • @DavidHeffernan我认为这个数字来自哪里并不重要,因为问题的根源不在于计算,而在于数字以浮点格式表示的方式。 (2认同)