web-dev-qa-db-fra.com

Pourquoi Java ne génère-t-il pas d'exception lors de la division par 0,0?

J'ai un code pour calculer la différence en pourcentage entre 2 nombres - (oldNum - newNum) / oldNum * 100; - où les deux nombres sont doubles. Je m'attendais à devoir ajouter une sorte de vérification/gestion des exceptions dans le cas où oldNum est 0. Cependant, lorsque j'ai fait un test avec des valeurs de 0,0 pour oldNum et newNum, l'exécution s'est poursuivie comme si de rien n'était et qu'aucune erreur n'a été générée. L'exécution de ce code avec ints entraînerait certainement une exception de division arithmétique par zéro. Pourquoi Java l'ignore-t-il quand il s'agit de doubles?

68
froadie

Le résultat de la division par zéro est, mathématiquement parlant, non défini, qui peut être exprimé avec un flottant/double (comme NaN - pas un nombre), ce n'est pas, cependant, mal dans un sens fondamental.

Comme un entier doit contenir une valeur numérique spécifique, une erreur doit être levée par division par zéro lors de leur traitement.

45
Kris

Les types float et double de Java, comme à peu près n'importe quel autre langage (et à peu près n'importe quel matériel FP unit), implémentent le IEEE 754 standard pour les mathématiques à virgule flottante, qui oblige la division par zéro à renvoyer une valeur spéciale "infini". Le fait de lever une exception violerait en fait cette norme.

L'arithmétique entière (implémentée sous la forme complément à deux représentation par Java et la plupart des autres langages et matériels) est différente et n'a pas de valeurs spéciales à l'infini ou NaN, donc lever des exceptions est utile comportement là-bas.

110

La façon dont un double est stocké est très différente d'un int. Voir http://firstclassthoughts.co.uk/Java/traps/Java_double_traps.html pour une explication plus détaillée sur la façon dont Java gère les doubles calculs. Vous devriez également lire sur les nombres à virgule flottante, en particulier le concept de Pas un nombre (NaN) .

Si vous souhaitez en savoir plus sur la représentation en virgule flottante, je vous conseille de lire ce document (format Word, désolé). Il plonge dans la représentation binaire des nombres, ce qui peut être utile pour votre compréhension.

5
Mike

Bien que Java connaissent le double type primitif et la classe Double, en faisant de l'arithmétique à virgule flottante, ils ne prêtent pas assez d'attention à Double.INFINITY, NaN, -0.0 et d'autres règles qui régissent les calculs arithmétiques les impliquant.

La réponse simple à cette question est qu'elle ne lancera pas ArithmeticException et ne retournera pas Double.INFINITY. Notez également que la comparaison x == Double.NaN Est toujours évaluée à false, même si x lui-même est un NaN.

Pour tester si x est un NaN, il faut utiliser la méthode call Double.isNaN(x) pour vérifier si le nombre donné est NaN ou non. C'est très proche de NULL dans SQL.

Cela peut vous être utile.

4
ziyapathan

lorsqu'il est divisé par zéro (0 ou 0,00)

  1. Si vous divisez le double par 0, la JVM affichera Infinity.

    public static void main(String [] args){ double a=10.00; System.out.println(a/0); }

    Console: Infinity

  2. Si vous divisez int par 0, alors la JVM lancera exception arithmétique.

    public static void main(String [] args){ int a=10; System.out.println(a/0); }

    Console: Exception in thread "main" Java.lang.ArithmeticException: / by zero

  3. Mais si nous divisons int par 0,0, la JVM affichera Infinity:

    public static void main(String [] args){ int a=10; System.out.println(a/0.0); }

    Console: Infinity

En effet, JVM saisira automatiquement cast int pour doubler, nous obtenons donc l'infini au lieu de ArithmeticException.

4
Raman Gupta