C++中的浮点陷阱

32 浏览
0 Comments

C++中的浮点陷阱

这个问题已经在其他地方有了答案:

可能是重复问题:

浮点数和双精度数比较的最有效方法

我是C++的新手。我在阅读C++时有个问题。

如何确定两个浮点数是否相等?

提前感谢

admin 更改状态以发布 2023年5月24日
0
0 Comments

如果你的浮点类型使用IEEE 754表示法(大多数情况下是这样的),那么你应该利用浮点数的二进制表示与数值大小的相同排序。也就是说,如果你将浮点数二进制表示中的一位增加一位,则会得到下一个更大的数。

利用这一事实,我们可以通过计算它们的二进制差异来比较浮点数。这被称为“单位在最后一位 (ULP) 比较”。涉及到符号、零、无穷大和 NaN (Not a Number) 等细节问题,但这就是要点了。这里有一篇综合文章解释了这个问题。

基本上,我们认为两个浮点数相等,如果它们的单位在最后一位上有一小部分差异。结合你的编译器文档和自己的代码,你可以确定哪种截断适合你的需求。

伪代码如下:

double x, y;
// this is type punning, should be done differently in reality
uint64_t ux = *reinterpret_cast(&x);
uint64_t uy = *reinterpret_cast(&y);
return abs(ux - uy) < CUT_OFF; // e.g. CUT_OFF = 3;

上面的代码只是一个粗略的示例,不会起作用,你必须在最终比较之前处理许多特殊情况。请参阅文章了解详情。

0
0 Comments

有一个特殊的常量你需要知道,叫做DBL_EPSILON(或FLT_EPSILON)。这是可以加到1.0并改变其值的最小值。值1.0非常重要 - 较大的数字在添加到DBL_EPSILON时不会改变。现在,您可以将此值比例缩放到要比较的数字,以确定它们是否不同。比较两个双精度浮点数的正确表达式是:

if (fabs(a-b) <= DBL_EPSILON * fmax(fabs(a), fabs(b)))
{
    // ...
}

0