Flotteur vs Double
Est-il jamais un cas où une comparaison (equals()
) entre les deux valeurs à virgule flottante serait de retour false
si vous la comparez aussi DOUBLE
mais de retour true
si vous la comparez en tant que FLOAT?
Je suis en train d'écrire une procédure, dans le cadre de mon projet de groupe, pour comparer deux valeurs numériques de tous les types de donnée. Il y a 4 types de j'aimerais avoir à traiter avec un total de : double
, float
, int
et long
. Donc j'aimerais groupe double
et float
en une fonction, qui est, je venais de jeter un float
à double
et faire la comparaison.
Aurait il des résultats incorrects?
Grâce.
La question est donc explicitement au sujet de savoir si l'expansion de la simple à la double précision, peuvent affecter l'égalité? Parce que le réflexe de réponse à la phrase d'ouverture serait de parler de l'aliasing quand on perd de la précision.
Désolé, je suppose que ma question était un peu confus. J'ai reformulé pour plus de clarté.
Désolé, je suppose que ma question était un peu confus. J'ai reformulé pour plus de clarté.
OriginalL'auteur user113454 | 2012-04-10
Vous devez vous connecter pour publier un commentaire.
Si vous êtes à la conversion de double de flotteurs et la différence entre eux est au-delà de la précision du type float, vous pouvez exécuter des ennuis.
Par exemple, disons que vous avez les deux valeurs:
et que la précision d'un flotteur n'avait que six chiffres après la virgule. Cela voudrait dire que les deux
float
de valeurs9.87654
, d'où l'égalité, même si le double des valeurs elles-mêmes ne sont pas égaux.Toutefois, si vous parlez de la flotte de vote à double, identiques flotte devrait vous donner identiques doubles. Si les flotteurs sont différentes, l'une précision supplémentaire permettra d'assurer les doubles sont distincts.
float
àdouble
. Donc, vous dites que je ne devrais pas obtenir toutes les données-correction problème en faisant cela, non? Est-il une raison pourquoi vouloir faire de comparaisons dans flotter plutôt que dans double? Je me souviens que nous avons utilisé pour obtenir quelques plaintes au sujet de tout faire en double(mais j'ai oublié pourquoi. Cela n'a rien à voir avec la performance ou de la mémoire, par la voie). MerciJ'ai tendance à utiliser des doubles pour tout aujourd'hui - gone sont les jours où j'ai soigné sur l'enregistrement de quelques octets ici et là 🙂 bien sûr, si vous êtes le maintien d'un milliard d'élément de tableau, vous pouvez envisager d'utiliser le plus petit type de données.
D'accord, un milliard d'éléments est le temps où je commence à penser à l'aide de
float
.Vous pouvez avoir des problèmes si vous voulez comparer le double à flotteurs - voir ma réponse ci-dessous. Je suis d'accord avec paxdiablo - si vous pouvez simplement utiliser
double
s partout, vous devez 🙂"Oui" est incorrecte. Si vous avez deux flotteurs et vous les élargir à double alors le résultat de la comparaison des doubles sera toujours le même que le résultat de la comparaison des flotteurs. La réponse "Oui" semble être pour une autre question sur la conversion de la double à flotteurs - c'est une bonne réponse à une question différente, qui est source de confusion.
OriginalL'auteur paxdiablo
Aussi longtemps que vous n'êtes pas de mélange promu flotteurs et nativement calculé en double dans votre comparaison, vous devriez être ok, mais prendre soin:
La comparaison de flottants (ou doubles) pour l'égalité est difficile - voir ce très long mais excellent discussion.
Voici quelques faits saillants:
Vous ne pouvez pas utiliser
==
, en raison de problèmes avec la précision limitée de la virgule flottante formatsfloat(0,1) et double(0.1) sont des valeurs différentes (0.100000001490116119384765625 et 0.1000000000000000055511151231257827021181583404541015625) respectivement. Dans votre cas, cela signifie que la comparaison de deux flotteurs (en se convertissant au double) sera probablement ok, mais attention, si vous souhaitez comparer un flotteur avec un lit double.
Il est courant d'utiliser un epsilon ou de faible valeur et de faire une comparaison avec (flotteurs a et b sont considérées comme égales si
a - b < epsilon
). En C, float.h définitFLT_EPSILON
pour exactement cet effet. Cependant, ce type de comparaison ne fonctionne pas oùa
etb
sont tous les deux très petites ou très grandes.Vous pouvez résoudre ce problème en utilisant une échelle de-relative-de-la-taille-de-a-et-b, epsilon, mais ce chiffre se décompose dans certains cas (comme les comparaisons à zéro).
Vous pouvez comparer les entier des représentations de nombres en virgule flottante pour trouver le nombre représentable, de flotteurs il y a entre eux. C'est ce que Java est
Float.equals()
. Ceci est appelé l'ULP différence, pour les "Unités dans la Dernière Place de la" différence". Il est généralement bon, mais aussi se décompose lorsque l'on compare les contre zéro.L'article conclut:
Donc, pour répondre à votre question:
double
s àfloat
s, alors vous risquez de perdre de la précision, et de signaler de manière incorrecte deuxdouble
s comme égales (comme paxdiablo points).float
s àdouble
, puis la précision ne sera pas un problème sauf vous comparez unfloat
avec undouble
(Dites que vous l'avions l. 1.234 en float, et vous n'avez eu que 4 décimales de précision, puis le double 1.2345 POURRAIT représenter la même valeur que le flotteur. Dans ce cas, vous seriez probablement mieux de faire la comparaison à la précision de lafloat
, ou, plus généralement, au niveau d'erreur de la plupart représentation inexacte dans la comparaison).Un couple de considérations pratiques (puisque cela semble comme c'est pour une mission):
L'epsilon comparaison mentionnée par la plupart est probablement pas un problème (mais inclure une discussion des limites de l'écriture). Si jamais vous êtes planification à comparer à double flotteurs, essayez de le faire en float, mais si pas, essayez de faire toutes les comparaisons en double. Mieux encore, il suffit d'utiliser
double
s partout.Si vous voulez totalement ace la cession, comprennent une écriture-up des questions lorsque l'on compare les flotteurs et la raison pour laquelle vous avez choisi tout particulier à la méthode de comparaison.
OriginalL'auteur Timothy Jones
Je ne comprends pas pourquoi vous faites cela. Le
==
opérateur déjà s'adresse à tous les types possibles sur les deux côtés, avec de nombreuses règles sur le type de la contrainte et de l'élargissement qui sont déjà spécifiées dans les normes linguistiques. Tout ce que vous avez à faire est de l'utiliser.overriding
la==
des tâches des opérateurs. Mais je voudrais juste savoir si je voudrais obtenir des résultats incorrects lorsque vous essayez de promouvoirfloat
àdouble
et faire un 64bit comparaison, par opposition à 32 bits de comparaison==
ne peut pas être utilisé en toute sécurité de comparer doubles en C - en fait, GCC va produire un avertissement si vous essayez.Je n'ai rien dit à propos de 'primordial'. Vous avez juste à utiliser l'opérateur. Il sait déjà comment comparer n'importe quel type primitif à toutes les autres.
eh bien, ma question était un peu confus. J'ai reformulé.
Je vais seulement ajouter que les normes linguistiques, j'ai mentionné les ne pas spécifier la promotion de flotteur double de ==.
OriginalL'auteur user207421
Je suis peut-être pas répondre à l'OP de la question, mais plutôt de répondre à certains plus ou moins floue conseils qui nécessitent des éclaircissements.
De la comparaison de deux valeurs à virgule flottante pour l'égalité est tout à fait possible et peut être fait. Si le type est simple ou double précision est souvent de moindre importance.
Avoir dit que les étapes menant à la comparaison elle-même demande une grande attention et une compréhension approfondie de la virgule flottante dos et ne pas faire, pourquoi et pourquoi les pauvres.
Envisager la suite C déclarations:
Dans la plupart des naïfs à virgule flottante de programmation, ils sont perçus comme "équivalent" je e la production de la "même". Dans le monde réel de la virgule flottante ils peuvent être. Ou en fait, les deux premières sont équivalentes (comme le second suit C règles d'évaluation, j'ai e des opérateurs de même priorité de gauche à droite). La troisième peut ou peut ne pas être équivalente à la première twp.
Pourquoi est-ce?
"a * b /c" ou "b /c * a" peut provoquer le "inexact" exception que j'ai e un intermédiaire, ou le résultat final (ou les deux) est (sont) n'est pas exacte(ly représentable en format à virgule flottante). Si c'est le cas, les résultats seront plus ou moins subtilement différentes. Cela peut ou peut ne pas conduire à la fin des résultats se prêtent à une comparaison d'égalité. Être conscient de cela et pas à pas à travers les opérations une à une - en notant les résultats intermédiaires - va permettre au patient programmeur de "battre le système" i e construire une qualité de floating-point de comparaison pour pratiquement n'importe quelle situation.
Pour tout le monde, passant au-dessus de la comparaison d'égalité pour les variables-poiny nombre est une bonne chose, des conseils solides.
C'est vraiment un peu ironique, parce que la plupart des programmeurs savent que entier mathématiques résultats prévisibles de troncatures dans diverses situations. Quand il s'agit de virgule flottante, presque tout le monde est plus ou moins abasourdi que les résultats ne sont pas exactes. Allez comprendre.
OriginalL'auteur Olof Forshell
Vous devriez être bien de faire qui jettent tant que le test d'égalité implique un delta.
Par exemple:
abs((double) floatVal1 - (double) floatVal2) < .000001
devrait fonctionner.Modifier en réponse à la question du changement
Non, vous ne le seraient pas. Le ci-dessus est toujours debout.
C'était un moyen rapide et sale exemple pour montrer que la comparaison doit être valide. Je n'étais pas le seul à le faire (par exemple @PetrAbdulin). Vous avez raison, dans l'idéal, le delta serait un nombre généré de l'ordre de la flotte. Comme pour le fait que j'ai dit "doit travailler", c'est dans ma nature, en tant que programmeur de ne pas parler dans l'absolu. Mais cette comparaison serait de travailler. Vous son n'était pas trop certain à propos de votre avis vous-même: "ne pas le delta être construit...". Avez-vous testé que des conseils?
Et par "Que la comparaison serait de travailler", je voulais dire que le casting de la partie de travail. Le delta créé comme vous l'avez suggéré.
OriginalL'auteur Tim Pote
Pour la comparaison entre float f et double d, vous pouvez calculer la différence de f et de d. Si abs(f-d) est inférieure à un certain seuil, vous pouvez penser à l'égalité détient. Ces seuils pourraient être absolue ou relative en tant que votre condition d'application. Il y a quelques bonnes solutions Ici. Et j'espère qu'il est utile.
OriginalL'auteur Freedom
Pas.
Si vous commencez avec deux flotteurs, ce qui pourrait être flotteur variables (float x = foo();) ou float constantes (1.234234234 f), alors vous pouvez les comparer directement, bien sûr. Si vous les convertir en double et de les comparer ensuite les résultats seront identiques.
Cela fonctionne parce que le double est un super-ensemble de flotteur. C'est, chaque valeur peut être stockée dans un flotteur peut être stockée dans un double. La gamme de l'exposant et la mantisse sont à la fois augmenté. Il y a des milliards de valeurs qui peuvent être stockées dans un double, mais pas dans un flotteur, mais il ya zéro des valeurs qui peuvent être stockées dans un flotteur, mais pas un double.
Comme indiqué dans mon flotteur article de comparaison il peut être difficile de faire une comparaison entre float ou double des valeurs, en raison des erreurs d'arrondi peuvent se produise. Mais, la conversion à la fois des nombres de float en double ne pas en changer. Toutes les mentions de epsilons (qui sont souvent, mais pas toujours nécessaire) sont complètement orthogonale à la question.
D'autre part, la comparaison d'un flotteur à un double est de la folie. 1.1 (un double) n'est pas égal à 1,1 f (float) parce 1.1 ne peut pas être représentée exactement en soit.
OriginalL'auteur Bruce Dawson