检查双精度何时有效为零

checking when a double is effectively zero

本文关键字:有效 何时 双精度 检查      更新时间:2023-10-16

在我的程序中,我计算两个值(加倍)xy,然后找到数字1/(x^2 + y^2)。当xy如此接近零时,我的问题就出现了,以至于分数给出了NaN。事实上,当两个变量都接近零时,分数应该为零。我试着使用比较x==0 || y==0,但这不起作用,因为它们是替身。

有没有一种计算有效的方法来考虑这一点?

#include <iostream>
using namespace std;
val(double x, double y)
{
    return 1/(x*x + y*y);
}
int main()
{
    //determine x and y....
    val(x, y)
    return 0;
}

如果你想将一个双值与零进行比较,你应该这样做:

bool IsZero(double dest)
{
if(dest > -0.0000001 && dest < 0.0000001)
return true;
else
return false;
}

我不知道你为什么会得到NaN,除非xy已经是NaN,或者你正在进行的计算不是你所显示的,或者你使用的是一些非IEEE浮点实现。

对于IEEE浮点,小浮点值的平方总是可以表示的,要么是较小的非零值,要么是0。无论如何,不要被分母中的计算分散注意力。潜在的问题是,在某个时刻,即使d不为0,1/d也会变得太大,无法表示为二重,从而得到无限的结果。如果你想把无穷大变成零,最简单的方法是检查无穷大并用0:代替它

#include <math.h>
double res = // whatever
if (isinf(res))
    res = 0;

这是假设C99或C++11。

#include <float.h>
// could also be your custom consant
// see also http://stackoverflow.com/a/77735/213682
// also this http://stackoverflow.com/a/2729750/213682
const double my_epsilon = DBL_MIN;
double val(double x, double y)
{
    double denom = x*x + y*y;
    if (denom < my_epsilon) {
        return 0.0; // or some other value indicating an error
    }
    return 1.0 / denom;
}

在我的机器上,1.0 / DBL_MIN给出了一个强大的数字:

44942328371557897693232629769725618340449424473
55766431835752028943316895137524078317711933060
18840052800284699678483394146974422036041556232
11857659868531094441973356216371319075554900311
52352986327073802125144220953767058561572036847
82776352068092908376276711465745599868114846199
29076208839082406056034304.000000