关于C++中的浮点数比较
about float number comparision in C++
>我有一个循环来循环给定的最小和最大范围之间的浮点数,如下所示
#include <iostream>
using namespace std;
void main(void)
{
for (double x=0.012; x<=0.013; x+=0.001)
{
cout << x << endl;
}
}
这是非常简单的代码,但正如我在计算机语言中所知,我们需要将两个浮点数与考虑的 EPS 进行比较。因此,上面的代码不起作用(我们希望它从 0.012 循环两次到 0.013,但它只循环一次(。所以我手动将 EPS 添加到上限。
#include <iostream>
using namespace std;
#define EPS 0.0000001
void main(void)
{
for (double x=0.012; x<=0.013+EPS; x+=0.001)
{
cout << x << endl;
}
}
它现在有效。但是手动执行此操作看起来很丑陋,因为EPS实际上应该取决于机器。我正在将我的代码从 matlab 移植到 C++ 并且由于有 eps 命令,我在 matlab 中没有问题。但是在 C/C++ 中有这样的东西吗?
捏造比较是错误的技术。即使您的比较"正确",浮点循环计数器也会在迭代之间累积误差。
您可以通过对循环计数器使用精确算法来消除误差累积。它可能仍具有浮点类型,但您使用完全可表示的值,例如:
for (double i = 12; i <= 13; ++i)
然后,在循环中,根据需要缩放计数器:
for (double i = 12; i <= 13; ++i)
{
double x = i / 1000.;
…
}
显然,在两次迭代的循环中累积的错误并不多。但是,我希望您的值只是一个例子,在实践中可能会有更长的循环。使用此技术,x
的唯一错误是在缩放操作中,因此每次迭代中只有一个错误,而不是每次迭代一个错误。
请注意,除以 1000 比缩放 .001 更准确。除以 1000 只有一个错误(在除法中(。但是,由于 .001 在二进制浮点中不能完全表示,因此乘以它有两个错误(在将 .001 转换为浮点数和乘法中(。另一方面,除法通常是一个非常缓慢的操作,因此您可以选择乘法。
最后,尽管此技术保证了所需的迭代次数,但由于缩放中的舍入误差,缩放值在第一次或最后一次迭代中可能会略微超出理想目标间隔。如果这对应用程序很重要,则必须在这些迭代中调整值。
相关文章:
- 浮点数比较为什么没有相等的函数
- 将 32 位浮点数和不强制转换的 32 位整数与双精度进行比较,当其中一个值可能太大而无法完全适合另一种类型时
- 比较最小值/最大值的浮点数(浮点数或双精度数)
- 浮点数的二进制相等比较是否正确
- 视觉比较C 与C 构建器中的浮点数
- 浮点数比较技巧:内联装配
- 如果我为浮点数定义了自定义比较函数,std::sort 会正常工作吗?
- 无法理解浮点数和对象实例化之间比较的原因
- 使用谷歌测试和谷歌模拟的浮点数组比较
- 移植将 32 位浮点数与使用 64 位进行比较的代码,此值表示什么
- 将浮点数与零进行比较
- 比较浮点数与零的标准方法是什么
- 将浮点数与常量进行比较时出现奇怪的行为
- 比较浮点数的正确方法
- 关于C++中的浮点数比较
- 通过作弊快速比较大于零的 IEEE 浮点数
- 比较浮点数和整数
- 比较浮点数 - 谷歌测试框架
- 将浮点数与小数点后三位进行比较
- 使用相等性对浮点数进行比较的情况