visual-c++ - 整数值,如果不是在数学运算中将类型强制转换为 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”。
解决方案
您好 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/
推荐阅读
- odoo - 如何在odoo v10中将“day, hh:mm:ss”格式转换为hh:mm
- c - 在 C 中创建一个字符串后,我试图将其内容复制到该字符串的文件在我实际告诉它之前执行此操作
- git - github中是否有任何选项可以从其他用户的存储库中获取代码?
- php - 从今天和明天添加数组记录
- android - 有什么方法可以将我的手机摄像头信号连接到 ROS?
- editor - WinEdt中的鼠标滚轮滚动问题
- node.js - 使用机器人自动创建 youtube 播放列表和添加过滤视频
- node.js - 初始化脚本上的 Sanity Studio CMS(新贵)
- git - 如何指定登录 GitHub 的 ssh 密钥?
- python - 在 Pandas 中连接但保留重复的列名