87 votes

Java Entier compareTo() - pourquoi utiliser la comparaison vs soustraction?

J'ai trouvé qu' java.lang.Integer de la mise en œuvre de l' compareTo méthode se présente comme suit:

public int compareTo(Integer anotherInteger) {
    int thisVal = this.value;
    int anotherVal = anotherInteger.value;
    return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1));
}

La question est de savoir pourquoi l'utilisation de la comparaison à la place de la soustraction:

return thisVal - anotherVal;

103voto

Itay Maman Points 15470

Cela est dû à débordement d'entier. Lors de l' thisVal est très grand et anotherVal est négatif, puis en soustrayant le second au premier, vous obtenez un résultat qui est plus grand que thisVal qui peut déborder de la zone négative.

67voto

polygenelubricants Points 136838

La soustraction "truc" pour comparer deux valeur numérique est cassé!!!

        int a = -2000000000;
        int b =  2000000000;
        System.out.println(a - b);
        // prints "294967296"

Ici, a < b, encore a - b est positif.

NE PAS utiliser cet idiome. Il ne fonctionne pas.

En outre, même si cela fonctionne, il ne sera PAS fournir une amélioration significative dans les performances, et peut, en fait, le coût de la lisibilité.

Voir aussi

  • Java casse-têtes de Puzzle de 65 ans: Une Étrange Saga des Suspects de Tri

    Ce puzzle a plusieurs leçons. Le plus spécifique est: Ne pas utiliser une soustraction à base comparateur sauf si vous êtes sûr que la différence entre les valeurs ne sera jamais plus grand que Integer.MAX_VALUE. De manière plus générale, méfiez-vous de l' int de dépassement. Une autre leçon est que vous devriez éviter de "sage" du code. S'efforcer d'écrire clairement, le code est correct, et ne pas l'optimiser, sauf si cela s'avère nécessaire.

9voto

FredOverflow Points 88201

Pour parler simplement, l' int type n'est pas assez grand pour stocker la différence entre les deux arbitraire int valeurs. Par exemple, la différence entre 1,5 milliard et -1.5 milliards de dollars est de 3,0 milliards de dollars, mais int ne peut pas contenir des valeurs de plus de 2,1 milliards de dollars.

3voto

Adamski Points 29884

C'est peut-être pour éviter le débordement / underflow.

2voto

PauliL Points 830

Outre le dépassement de chose, vous devez noter que la version avec soustraction ne donne pas les mêmes résultats.

  • La première compareTo version renvoie l'une des trois valeurs possibles: -1, 0 ou 1.
  • Si vous remplacez la dernière ligne avec la soustraction, le résultat peut être n'importe quelle valeur entière.

Si vous savez il n'y aura pas de débordement, vous pouvez utiliser quelque chose comme ceci:

public int compareTo(Integer anotherInteger) {
    return sign(this.value - anotherInteger.valuel);
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X