2010-02-17 40 views
12

¿Cómo forzar a Java a lanzar una excepción aritmética al dividir por 0.0 o extraer la raíz del doble negativo? Código sigue:¿Cómo forzar a Java a lanzar una excepción aritmética?

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

¿No se supone que la fórmula cuadrática se divide entre 2 * a y no 2/a? – DyingCactus

+0

** ¿Por qué ** desea obtener una excepción en lugar de simplemente verificar el resultado? ¿O fue el problema * real * que no sabes cómo comprobar el resultado? – BalusC

+1

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

Respuesta

12

No es posible hacer Java excepciones tiro para estas operaciones porque Java implementa el IEEE 754 estándar para la aritmética de punto flotante, que ordena que estas operaciones deben volver patrones de bits específicos con el significado "No es un número" o "Infinito".

Si desea tratar estos casos especialmente, puede comparar los resultados con las constantes correspondientes como Double.POSITIVE_INFINITY (para NaN debe utilizar el método isNAN() porque NaN! = NaN). Tenga en cuenta que no tiene que verificar después de cada operación individual ya que las operaciones subsiguientes mantendrán el valor de NaN o Infinito. Solo revisa el resultado final.

+0

solo una nota: 'Double.NaN! = Double .NaN' es ** verdadero ** y 'Double.NaN == Double.NaN' es ** falso **, mejor uso' Double.isNaN (double) ' –

+0

@Interruption: buen punto –

+4

No es cierto que falte Java de excepciones de coma flotante es * porque * implementa IEEE 754. La máquina virtual Java específicamente * [difiere] (http://java.sun.com/docs/books/jvms/second_edition/html/Overview.doc.html# 35254) * de IEEE 754 al no tener forma de atrapar o señalar estas condiciones. –

0

Este código generará un ArithmeticException:

int x = 1/0; 
+0

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

+0

-1 Y, no tira nada – OscarRyz

+2

Mi error: fue la división de enteros que arrojó la excepción. –

2

Creo, que tendrá que comprobar manualmente, por ejemplo,

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; 
} 

Así, por tu ejemplo

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

No quiero llamar a checkValue cada vez que se puede producir una división por cero u otra operación "incorrecta". Me gustaría rodear mi código con try-catch y verificar fallas en un bloque de código, teniendo cosas de limpieza (es decir, checkValue() llamadas) fuera del código principal. – DNNX

+0

@DNNX: el método "check in one place" es compatible con 'NaN': cuando ocurre un problema, el resultado final de su cálculo será' NaN'. Solo verifica eso al final. –

+0

@DNNX "No siempre puedes obtener lo que quieres/Pero si lo intentas alguna vez, encontrarás/Obtendrás lo que necesitas" (Jagger/Richards);) – sfussenegger

Cuestiones relacionadas