2010-02-17 4 views
12

Comment forcer Java à lancer une exception arithmétique en divisant par 0.0 ou en extrayant la racine du double négatif? Code suit:Comment forcer Java à lancer une exception arithmétique?

double a = 1; // or a = 0 to test division by 0 
    double b = 2; 
    double c = 100; 

    double d = b*b - 4*a*c; 
    double x1 = (-b - Math.sqrt(d))/2/a; 
    double x2 = (-b + Math.sqrt(d))/2/a; 
+0

La formule quadratique n'est-elle pas censée être divisée par 2 * a et non 2/a? – DyingCactus

+0

** Pourquoi ** voulez-vous obtenir une exception au lieu de simplement vérifier le résultat? Ou était le problème * réel * que vous ne savez pas comment vérifier le résultat? – BalusC

+1

@DyingCactus: x/2/a == x/(2 * a) –

Répondre

12

Il est impossible de faire Java lancer des exceptions pour ces opérations parce que Java implémente l'IEEE 754 standard pour l'arithmétique en virgule flottante, qui exige que ces opérations doivent retourner les modèles de bits spécifiques avec le sens "Not a Number" ou "Infinity".

Si vous voulez traiter ces cas spécialement, vous pouvez comparer les résultats avec les constantes correspondantes comme Double.POSITIVE_INFINITY (pour NaN vous devez utiliser la méthode isNAN() parce que NaN! = NaN). Notez que vous n'avez pas à vérifier après chaque opération car les opérations suivantes conserveront la valeur NaN ou Infinity. Vérifiez simplement le résultat final.

+0

juste une note: 'Double.NaN! = Double .NaN' est ** true ** et 'Double.NaN == Double.NaN' est ** false **, mieux vaut' Double.isNaN (double) ' –

+0

@Interruption: bon point –

+4

Ce n'est pas vrai que le manque de Java d'exceptions en virgule flottante est * car * il implémente IEEE 754. La machine virtuelle Java en particulier * [diffère] (http://java.sun.com/docs/books/jvms/second_edition/html/Overview.doc.html# 35254) * de IEEE 754 en n'ayant aucun moyen de piéger ou signaler ces conditions. –

0

Ce code lancera une ArithmeticException:

int x = 1/0; 
+0

'System.out.println (1d/0d);' imprime 'Infinity' – sfussenegger

+0

-1 Et, ne lance rien – OscarRyz

+2

Mon mauvais: c'était la division entière qui a jeté l'exception. –

2

Je pense, vous devrez vérifier manuellement, par exemple

public double void checkValue(double val) throws ArithmeticException { 
    if (Double.isInfinite(val) || Double.isNaN(val)) 
     throw new ArithmeticException("illegal double value: " + val); 
    else 
     return val; 
} 

Donc, pour votre exemple

double d = checkValue(b*b - 4*a*c); 
double x1 = checkValue((-b - Math.sqrt(d))/2/a); 
double x2 = checkValue((-b + Math.sqrt(d))/2/a); 
+1

Je ne veux pas appeler checkValue à chaque fois que la division par zéro ou une autre "mauvaise" opération peut se produire. Je voudrais entourer mon code avec try-catch et vérifier les échecs dans un bloc de code, ayant des trucs d'entretien (c.-à-d. CheckValue() appels) hors du code principal. – DNNX

+0

@DNNX: la méthode "check in one place" est supportée par 'NaN': Lorsqu'un problème survient alors le résultat final de votre calcul sera' NaN'. Juste vérifier pour cela à la fin. –

+0

@DNNX "Vous ne pouvez pas toujours obtenir ce que vous voulez/Mais si vous essayez quelque temps, vous trouverez/Vous obtenez ce dont vous avez besoin" (Jagger/Richards);) – sfussenegger

Questions connexes