java - 浮点数如何比较是否相等或者如何判断某个浮点数是否为0?
天蓬老师
天蓬老师 2017-04-18 10:18:47
0
3
1967

大家应该都知道浮点数存在精度问题,所以问题就来了,我如何才能判断两个数是否近似相等,或者某个浮点数是否为0。
其实这是一个问题,对于前者,我们需要二者作差,然后与0进行比较。这样前者与后者就是同一个问题了,即如何判断某个浮点数是否为0。我所知道的比较简单但是不是很好的方法就是使用1e-7或者更小的数,如下所示(以单精度为例):

#include <iostream>
#include <cfloat>

using namespace std;

int main()
{
    float num;

    cout << "输入一个数:";
    cin >> num;

    if (num < 1e-7 && num > -1e-7)
        cout << num << "近似为0" << endl;
    else
        cout << num << "不近似为0" << endl;

    return 0;
}

上述方式以C++代码为例。由于不同编程语言有不同的处理方式,大家可以不限制使用任何编程语言。当然,如果您有更通用的方式当然再好不过了。

天蓬老师
天蓬老师

欢迎选择我的课程,让我们一起见证您的进步~~

reply all(3)
洪涛

How small is "small enough" should be determined by the specific problem being dealt with. For example, using double表示金额的话,1e-4就可以认为是零了。而如果进行科学计算,恐怕1e-7 is too big.

<cfloat>中有定义DBL_EPSILON为与1.0The closest difference. See here.

PHPzhong

The comparison of floating point numbers still needs to be based on actual storage rules, because floating point numbers are stored in binary, and using binary to represent decimal cannot be accurately represented. Even if the decimal significant digits of floating point numbers are relatively small, it may not be possible. Exactly represented in binary . why?
First of all, the binary representation of the decimal places of floating point numbers is as follows:
1 decimal place: 0.5 (2^-1)
2 decimal places: 0.25 (2^-2)
...
n decimal places: 2 ^-n
In other words, the decimal part of any floating-point number is composed of 2^-1...2^-n, so you can understand why floating-point numbers with few significant digits cannot If it is accurately expressed, for example, 0.3, it cannot be accurately expressed using the above combination of digits. If you don’t believe in cout, try it:

#include <iostream>
#include <iomanip>

int main()
{
    float a = 0.3f;
    std::cout << std::setprecision(32) << a << std::endl;
    return 0;
}

Output: 0.30000001192092896
And if you replace 0.3 with 0.5, that’s fine, because 0.5 can be accurately represented by 2^-1! In the same way, 0.625 is also OK.
Then why can we usually output 0.3 directly when cout << 0.3? That's because cout performs rounding processing by default.

Back to the original poster's question: If you directly judge 0.3 == 0.3, that's no problem, because the same number has the same representation, so you can use '==' directly. This is especially true if it is a number that can be represented accurately, such as 0.
But if you want to judge whether 0.1+0.2 and 0.3 are equal, it won’t work, because they both have accuracy loss, and the loss values ​​are different, so you can’t directly compare and you need to use a method like abs((0.1+0.2) - 0.3)<EPSILON.

Peter_Zhu

Computer representation of floating-point numbers (float or double type) has a precision limit. For floating-point numbers that exceed the precision limit, the computer will truncate the decimal part beyond their precision. Therefore, two floating point numbers that are originally unequal may become equal in the computer. For example:

float a=10.222222225,b=10.222222229
数学上a和b是不相等的,但在32位计算机中它们是相等的。

如果两个同符号浮点数之差的绝对值小于或等于某一个可接受的误差(即精度),就认为它们是相等的。
不要直接用“==”或者“!=”对两个浮点数进行比较,但是可以直接用“<”和“>”比较谁大谁小。
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template