Java ne semble pas comparer droit Doubles
Question
J'ai créé une liste chaînée, avec insert, recherche et supprimer des fonctions. J'ai aussi créé un itérateur pour elle. Maintenant, supposons que je fais ceci:
myList<Integer> test = new myList();
test.insert(30);
test.insert(20);
test.insert(10);
myList.iterator it = test.search(20);
if(it.hasNext())
System.out.println(it.next());
Et le tour est joué, il fonctionne (il imprime la valeur de l'élément au niveau du noeud, dans ce cas 20). Maintenant, si je fais ceci:
myList<Double> test = new myList();
test.insert(30.1);
test.insert(20.1);
test.insert(10.1);
myList.iterator it = test.search(20.1);
if(it.hasNext())
System.out.println(it.next());
Il n'a pas, parce que l'itérateur pointe null. Voici la mise en œuvre de la fonction de recherche:
public iterator search(T data)
{
no<T> temp = first;
while( (temp != null) && (temp.data != data) )
temp = temp.next;
return (new iterator(temp));
}
Voici comment je sais qu'il ya quelque chose de louche avec les comparaisons: Si je change une partie du code ci-dessus comme ceci:
while( (temp != null) && (temp.data != data) )
System.out.println(temp.data + " " + data);
temp = temp.next;
Je peux le voir imprimer les numéros dans la liste. Il imprime, à un moment donné, « 20.1 20.1 » (par exemple). Alors, comment puis-je résoudre ce problème? La fonction semble être à droite, mais il semble comme si Java ne compare pas les chiffres correctement.
EDIT: wth, BigDecimal m'a donné aussi le même genre de problème
.EDIT 2: égal à égal () a travaillé, n'a pas réalisé quelque chose d'autre clochait. Désolé.
La solution
Vous ne voulez pas! = Opérateur pour cela. Il comapres références. Vous voulez que la méthode de .equals()
:
public iterator search(T data)
{
no<T> temp = first;
while (!data.equals(temp.data)) {
temp = temp.next;
}
return (new iterator(temp));
}
En outre, méfiez-vous auto-boxing . Vous trouverez peut-être que les boîtes de test.search(20.1)
20.1 à un Float
pas Double
, ce qui va probablement casser votre comparaison. Comparez les résultats avec test.search(20.1d)
. Si je me souviens bien, l'expression:
new Float(20.1).equals(new Double(20.1))
est faux.
Autres conseils
Notez que l'utilisation .equals()
pour comparer double peut conduire à des erreurs. Double.equals()
utilise comme son test d'égalité:
d1.doubleValue() == d2.doubleValue()
Doubles approximations et flotteurs sont de numéros stockés dans un espace fixe dans la mémoire.
Afin de bien comparer nombres à virgule flottante , vous devez être conscient qu'en raison de la nature des flotteurs, il y aura une erreur.
voir: http://www.google.com/search?q = flottant + + point de l'égalité
Un moyen rapide et facile de comparer double est d'utiliser Math.abs(a-b)<ACCEPTABLE_ERROR
où ACCEPTABLE_ERROR pourrait être .000000000001
en fonction de ce que vous faites exactement.
(Notez que cela ne gère pas les cas de pointe comme NaN et INFINITY)