Dupliqué possible: strong>
Sortie étrange en comparaison de flotteur avec littéral flottantQuand j'essaie de comparer 2 mêmes
float code> valeurs, il n'imprime pas "Valeurs égales" dans le code suivant: p>
void main() { float a = 0.7; clrscr(); if (a < 0.7) printf("value : %f",a); else if (a == 0.7) printf("equal values"); else printf("hello"); getch(); }
7 Réponses :
L'absence de précision absolue dans les flotteurs rend plus difficile la comparaison triviale que pour les entiers. Voir Cette page sur la comparaison des flotteurs dans C. En particulier, un extrait d'un code Soulevé de là montre une «solution de contournement» à ce problème:
if (fabs(result - expectedResult) < 0.00001)
Il n'y a pas de "manque de précision absolue dans des flotteurs". Leur précision est absolue et les valeurs sont exactes. Le problème est qu'ils sont basés sur la base 2 arithmétiques et nous utilisons normalement la base 10. Les valeurs de base 10 peuvent ne pas avoir d'équivalent exact dans la base 2 et inversement. 0.5 et 10.125 sont des exemples d'équivalents exacts. 0,3 et 11,6 exemples de quand il n'y a pas d'équivalent.
Si vous avez besoin de comparer ici 0.00001 peut être changé en moins (comme 0.00000001) ou plus (comme 0,0001)> Cela dépend de la précision dont vous avez besoin. p> p> A code> avec
0.7 code> que
Vous devez obtenir la valeur absolue du résultat du résultat de la soustraction ou que l'EPSILON ne se développe que d'une manière.
Les numéros de points flottants ne doivent pas être comparés à l'opérateur "==". strong> em> au lieu de comparer des nombres de flotteurs avec l'opérateur "==", vous pouvez Utilisez une fonction comme celle-ci: p>
Peut être simplifié à: Retour Fabs (F1 - F2) <0.00001 CODE>
Euh ... Et si F1 et F2 sont plus petits que 0.00001?
@Olofforshell Que diriez-vous de modifier l'énoncé comme Precision float = 0.00001 * F1 * F2; code>?
Le nombre de points flottants ne sont pas ce que vous pensez être: Voici deux sources avec plus d'informations: Ce que chaque scientifique informatique devrait connaître sur l'arithmétique de point flottant et Guide Point . P>
La réponse courte est qu'en raison de la manière dont les numéros de points flottants sont représentés, vous ne pouvez pas faire de comparaison de base ou d'arithmétique et qu'attendez-vous. P>
Bien que de nombreuses personnes vous disent de toujours comparer les numéros de points flottants avec un epsilon (et c'est généralement une bonne idée, bien que cela soit un pourcentage des valeurs comparées plutôt qu'une valeur fixe), ce n'est pas réellement nécessaire ici depuis Vous utilisez des constantes.
votre problème spécifique em> est que: p> utilise la double em> constante em> Code> 0.7 Code> Pour créer un numéro de précision em> (perdre une certaine précision) tandis que: p> comparera deux double < / em> numéros de précision ( La précision qui a été perdue lors du tournage du double Si vous modifiez toutes ces Vous pouvez voir cela en action avec: p> qui va produire quelque chose comme (légèrement modifié pour montrer la différence): p> A code> est favorisé en premier). p>
0.7 code> dans le flotteur
A code> n'est pas retrouvé lors de la promotion
A code> à un double. p>
0.7 code> sur
0.7f < / code> (pour forcer le flotteur plutôt que double), ou si vous venez de faire
a code> un double, cela fonctionnera bien - j'utilise rarement
float code> à moins que j'ai un massif tableau de t ourlet et besoin d'économiser de l'espace. p>
Merci d'avoir écrit une réponse qui ne suggère pas d'Epsilon. Ce blog post que j'ai écrit il y a quelque temps a plus d'exemples de comportements qui peuvent être surprenants. blog.frama-c.com/ index.php? Post / 2011/11/08 / Floating-Point-Qu IZ
La méthode Epsilon semble simple mais est en fait assez complexe en ce que l'epsilon choisi doit être fonction de l'exposant de la valeur comparée (vecteur de constantes, une solution pour chaque exposant possible est une solution). En outre, lorsque vous abordez les valeurs extrêmes de l'exponent epsilon devient de moins en moins utile car sa valeur s'approche de la valeur comparée à celle de la valeur.
Vous comparez une approximation de la précision de 0,7 avec une approximation de la double précision. Pour obtenir la sortie attendue, vous devez utiliser:
0.7d = 0.6999999999999999555910790149937383830547332763671875
Pourquoi ne fonctionne-t-il pas avec 0.5F? 0.5 = .1; c'est-à-dire et sa mantissie correspond également au format flottant à la précision unique.
La comparaison entre les deux nécessite une conversion. Le compilateur convertira la valeur code> de la valeur code> à une valeur code> double code> ... et la valeur résultant de la conversion d'un flotteur en double n'est pas la même que la valeur résultant du compilateur Conversion d'une chaîne de texte (le code source) en un double. P>
Mais ne comparez jamais jamais les valeurs de point flottant ( Vous voudrez peut-être lire "Ce que chaque programmeur doit savoir sur l'arithmétique de point flottant" . < / p> A code> est un
float code>;
0,7 code> est une valeur de type
double code>. p>
float code>,
double code> ou
long double code>) avec
== code>. p>
0.7 code> est une valeur code> double code>,
0.7f code> est un
float code>.
Beaucoup de doublons, par exemple Sortie étrange dans la comparaison de float avec littéral float et Problème de point flottant dans C
Il devrait y avoir un float vs double tag sur alors simplement pour ces questions :)