c++ - 为什么下面的中间类型转换会出现不准确?
问题描述
以下示例来自《发现现代 C++ 》一书的第 14 页,Peter Gottschling。作者指出:
为了说明这种转换行为,让我们看下面的例子:
long l = 1234567890123;
long l2 = l + 1.0f - 1.0; // imprecise
long l3 = l + (1.0f - 1.0); // precise
这导致在作者的平台上:
l2 = 1234567954431;
l3 = 1234567890123;
我的问题是,究竟是什么导致了这种不精确性?是因为加法和减法的左结合性,所以l2
计算为(l + 1.0f) - 1.0
?如果是这样,(请参阅)的值范围肯定3.4E +/- 38 (7 digits)
涵盖float
了value,1234567890123
因此据我所知,缩小应该不是问题。
解决方案
Afloat
通常为 32 位。与最大值~3.4e38
相同的相同尺寸相比,您认为它如何实现更大的范围(最大值) ?int
~2.1e9
唯一可能的答案是它无法在达到最大值的过程中存储一些整数。并且可表示数字之间的差距随着绝对值的增加而增加。
考虑这段代码:
#include <cmath>
#include <iostream>
#include <limits>
void foo(float x, int n)
{
while (n-- > 0)
{
std::cout << x << "\n "[n > 0];
x = std::nextafter(x, std::numeric_limits<float>::infinity());
}
}
int main()
{
std::cout.precision(1000);
foo(0.001, 3);
foo(1, 3);
foo(100000000, 3);
}
它以尽可能慢的速度迭代这些float
值,即将值增加尽可能小的数量。
0.001000000047497451305389404296875 0.00100000016391277313232421875 0.001000000280328094959259033203125
1 1.00000011920928955078125 1.0000002384185791015625
100000000 100000008 100000016
如您所见,100000000
它附近只能表示每8个整数。
推荐阅读
- c# - 将 cefsharp js 绑定对象限制为白名单域
- python - AttributeError:“set”对象没有“get”属性
- javascript - 访问堆积条形图中的嵌套数据
- c++ - std::variant 在 MSVC 和 gcc 中的行为不同
- reactjs - 为什么我的信息传递滞后一个?
- java - 如何根据相应的值更改地图键?
- python - Python矩阵分解评估
- c++ - 如何使用命令行参数获取向量输入?
- python - 使用 Python 从 IP 摄像机获取 Onvif 事件
- reactjs - 浏览器刷新显示“page not found”错误,当单spa应用程序部署在子目录中时