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

大家应该都知道浮点数存在精度问题,所以问题就来了,我如何才能判断两个数是否近似相等,或者某个浮点数是否为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++代码为例。由于不同编程语言有不同的处理方式,大家可以不限制使用任何编程语言。当然,如果您有更通用的方式当然再好不过了。

天蓬老师
天蓬老师

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

모든 응답(3)
洪涛

얼마나 작은지 "충분히 작은지"는 다루고 있는 특정 문제에 따라 결정되어야 합니다. 예를 들어 double을 사용하여 금액을 표현한다면 1e-4은 0으로 간주될 수 있습니다. 그리고 과학적인 계산을 하면 1e-7이 여전히 너무 클 것 같습니다.

<cfloat>DBL_EPSILON1.0과 가장 가까운 차이점으로 정의합니다. 여기를 참조하세요.

PHPzhong

부동소수점 수의 비교는 여전히 실제 저장 규칙을 기반으로 해야 합니다. 왜냐하면 부동소수점 수는 이진수로 저장되며, 이진수를 사용하여 소수를 표현하는 것은 정확하게 표현할 수 없기 때문입니다. 포인트 숫자가 상대적으로 작으면 을 이진수로 정확하게 표현하는 것이 불가능할 수 있습니다. 왜? 먼저 부동 소수점 숫자의 소수점 이하 자릿수를 이진수로 표현하면 다음과 같습니다.
소수점 1자리: 0.5(2^-1)
소수점 2자리: 0.25(2^-2)
.. .
N 소수 자릿수: 2^-n
즉,
부동 소수점 숫자의 소수 부분은 2^-1...2^-n으로 구성됩니다. , 유효 숫자가 적은 부동 소수점 숫자를 정확하게 표현할 수 없는 이유를 이해할 수 있습니다. 예를 들어, 위의 숫자 조합으로 0.3을 정확하게 표현할 수 없다면 다음을 시도해 보세요. 으아아아

출력: 0.30000001192092896

0.3을 0.5로 바꾸면 괜찮습니다. 0.5는 2^-1로 정확하게 표현할 수 있기 때문입니다! 마찬가지로 0.625도 괜찮습니다.
그렇다면 왜 cout << 0.3을 직접 출력할 수 있을까요?
cout이 기본적으로 반올림을 수행하기 때문입니다.

원래 포스터의 질문으로 돌아가서: 0.3 == 0.3을 직접 판단하면 문제가 없습니다. 같은 숫자는 같은 표현이므로 '=='를 직접 사용할 수 있습니다. 특히 0과 같이 정확하게 표현할 수 있는 숫자인 경우에는 더욱 그렇습니다.

그런데 0.1+0.2와 0.3이 같은지 판단하면 안 됩니다. 둘 다 정확도 손실이 있고, 손실 값도 다르기 때문에 직접 비교할 수 없고 사용해야 하기 때문입니다.
같은 방법이죠. abs((0.1+0.2) - 0.3)<EPSILON

Peter_Zhu

부동 소수점 숫자(float 또는 double 유형)의 컴퓨터 표현에는 정밀도 제한이 있습니다. 정밀도 제한을 초과하는 부동 소수점 숫자의 경우 컴퓨터는 정밀도를 초과하는 소수 부분을 자릅니다. 따라서 원래 같지 않은 두 부동 소수점 숫자가 컴퓨터에서는 동일해질 수 있습니다. 예:

으아아아
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿