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

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

天蓬老师
天蓬老师

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

répondre à tous(3)
洪涛

Le degré de « assez petit » doit être déterminé par le problème spécifique traité. Par exemple, si vous utilisez double pour exprimer le montant, 1e-4 peut être considéré comme zéro. Et si on fait des calculs scientifiques, j'ai bien peur que 1e-7 soit encore trop gros.

<cfloat> définit DBL_EPSILON comme la différence la plus proche de 1.0. Voir ici.

PHPzhong

La comparaison des nombres à virgule flottante doit toujours être basée sur des règles de stockage réelles, car les nombres à virgule flottante sont stockés en binaire, et l'utilisation du binaire pour représenter les décimales ne peut pas être représentée avec précision Même si les chiffres décimaux significatifs du flottant. les nombres de points sont relativement petits, il se peut alors qu'il ne soit pas possible de représenter avec précision en binaire. Pourquoi?
Tout d'abord, la représentation binaire des décimales des nombres à virgule flottante est la suivante :
1 décimale : 0,5 (2^-1)
2 décimales : 0,25 (2^-2)
.. .
N décimales : 2^-n
C'est-à-dire que la partie décimale de tout nombre à virgule flottante est composée de 2^-1...2^-n , afin que vous puissiez comprendre pourquoi les nombres à virgule flottante avec peu de chiffres significatifs ne peuvent pas être représentés avec précision. Par exemple, 0,3 ne peut pas être représenté avec précision par la combinaison de chiffres ci-dessus. Si vous n'y croyez pas, essayez :

.
#include <iostream>
#include <iomanip>

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

Sortie : 0,30000001192092896
Et si vous remplacez 0,3 par 0,5, c'est très bien, car 0,5 peut être représenté avec précision par 2^-1 ! De la même manière, 0,625 est également acceptable.
Alors pourquoi pouvons-nous généralement générer 0,3 directement lorsque cout << C'est parce que cout effectue l'arrondi par défaut .

Retour à la question de l'affiche originale : si vous jugez directement 0,3 == 0,3, alors il n'y a pas de problème, car le même nombre a la même représentation, vous pouvez donc utiliser '==' directement. Cela est particulièrement vrai s’il s’agit d’un nombre qui peut être représenté avec précision, comme 0.
Mais si vous jugez si 0,1+0,2 et 0,3 sont égaux, cela ne fonctionnera pas, car ils ont tous deux des pertes de précision et les valeurs de perte sont différentes, vous ne pouvez donc pas les comparer directement et devez utiliser une méthode comme abs((0.1+0.2) - 0.3)<EPSILON.

Peter_Zhu

La représentation informatique des nombres à virgule flottante (type flottant ou double) a une limite de précision. Pour les nombres à virgule flottante qui dépassent la limite de précision, l'ordinateur tronquera la partie décimale au-delà de leur précision. Par conséquent, deux nombres à virgule flottante initialement inégaux peuvent devenir égaux dans l’ordinateur. Par exemple :

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

如果两个同符号浮点数之差的绝对值小于或等于某一个可接受的误差(即精度),就认为它们是相等的。
不要直接用“==”或者“!=”对两个浮点数进行比较,但是可以直接用“<”和“>”比较谁大谁小。
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal