Comparing floating point numbers in C

删除回忆录丶 提交于 2019-12-17 07:35:08

问题


I've got a double that prints as 0.000000 and I'm trying to compare it to 0.0f, unsuccessfully. Why is there a difference here? What's the most reliable way to determine if your double is zero?


回答1:


To determine whether it's close enough to zero that it will print as 0.000000 to six decimal places, something like:

fabs(d) < 0.0000005

Dealing with small inaccuracies in floating-point calculations can get quite complicated in general, though.

If you want a better idea what value you've got, try printing with %g instead of %f.




回答2:


You can do a range. Like -0.00001 <= x <= 0.00001




回答3:


This is fundamental problem with floating point arithmetic on modern computers. They are by nature imprecise, and cannot be reliably compared. For example, the language ML explicitly disallows equality comparison on real types because it was considered too unsafe. See also the excellent (if a bit long and mathematically oriented) paper by David Goldberg on this topic.

Edit: tl;dr: you might be doing it wrong.




回答4:


Also, one often overlooked features of floating point number are the denormalized numbers. That's numbers which have the minimal exponent, yet don't fit in the 0.5-1 range.

Those numbers are lower than FLT_MIN for float, and DBL_MIN for double.

A common mistake with using a threshold is to compare two values, or use FLT_MIN/DBL_MIN as limit.

For example, this would lead unlogical result (if you don't know about denormals):

bool areDifferent(float a, float b) {
    if (a == b) return false;  // Or also: if ((a - b) == FLT_MIN) 
    return true;
}


// What is the output of areDifferent(val, val + FLT_MIN * 0.5f) ?
// true, not false, even if adding half the "minimum value".

Denormals also usually implies a performance loss in computation. Yet, you can not disable them, else such code could still produce a DIVIDE BY ZERO floating point exception (if enabled):

float getInverse(float a, float b) {
    if (a != b)
        return 1.0f / (a-b); // With denormals disabled, a != b can be true, but (a - b) can still be denormals, it'll rounded to 0 and throw the exception
    return FLT_MAX;
}


来源:https://stackoverflow.com/questions/7008649/comparing-floating-point-numbers-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!