大家应该都知道浮点数存在精度问题,所以问题就来了,我如何才能判断两个数是否近似相等,或者某个浮点数是否为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++代码为例。由于不同编程语言有不同的处理方式,大家可以不限制使用任何编程语言。当然,如果您有更通用的方式当然再好不过了。
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 que1e-7
soit encore trop gros.<cfloat>
définitDBL_EPSILON
comme la différence la plus proche de1.0
. Voir ici.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 :
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
.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 :