首页 > 解决方案 > 整数值,如果不是在数学运算中将类型强制转换为 double 会产生令人费解的结果

问题描述

我在 VS 2015 - x64 上运行一个小型 MFC 项目。只需检查浮动操作的结果。

float fScale = 0.0199999996;
float fOffset = 0;
    
double doubleX2 = fOffset + 1 * fScale;

只有fOffset在 'for()' 循环中改变,从 0 到 3000000。fScale 始终保持不变。

结果:

fOffset            doubleX2
0.000000                0.020000
63.000000              63.020000
64.000000              64.019997
127.000000            127.019997
128.000000            128.020004
255.000000            255.020004
256.000000            256.019989
511.000000            511.019989
512.000000            512.020020
8191.000000          8191.020020
8192.000000          8192.019531
65535.000000        65535.019531
65536.000000        65536.023438
131071.000000      131071.023438
131072.000000      131072.015625
262143.000000      262143.015625
262144.000000      262144.031250
524287.000000      524287.031250
524288.000000      524288.000000
1999999.000000    1999999.000000
2999999.000000    2999999.000000

我不知道为什么小数部分会变化并最终变为零。我期望小数部分总是 0.0199999996。但是,如果我输入 double 类型的整数“1”,则小数部分始终为“.020000”。

标签: visual-c++

解决方案


您好 Float 是 C++ 中的一种高价值数据结构,它可以存储从 Around - 3x10^38 到 +3x10^38 的值。Double 是另一种极高价值的数据结构,它存储在 -1x10^308 到 +1x10^308 左右。而与这些结构相比,Int 很小。

-> Float 的小数精度约为 6 位,而 Double 的小数精度为 15 位。

->假设如果您将 900.0000000f 转换为 Double,则存储在 Double 中的值就是 900。

-> 计算机使用二进制将浮点数转换为十进制,首先将浮点数转换为二进制,因此将高精度数字转换为二进制会弹出精度上的轻微错误。因此,您可能并不总是获得假定值。在头文件中有一个叫做 std::setprecision(precision) 的操纵器,您可以使用它来控制数字的精度。

-> 如果计算是小数字或任何其他不重要的数字,这可以忽略。仍然如果您认为需要进行误差分析所需的精度。

这个链接有一些很好的解释 https://floating-point-gui.de/errors/propagation/


推荐阅读