2010-03-04 27 views
60

Tengo un código para calcular la diferencia porcentual entre 2 números - (oldNum - newNum)/oldNum * 100; - donde ambos números son double s. Esperaba tener que agregar algún tipo de control/manejo de excepciones en caso de que oldNum sea 0. Sin embargo, cuando realicé una prueba con valores de 0.0 para oldNum y newNum, la ejecución continuó como si nada hubiera sucedido y no se hubiera producido ningún error. Ejecutar este código con int s definitivamente causaría una excepción de división aritmética por cero. ¿Por qué Java lo ignora cuando se trata de double s?¿Por qué Java no arroja una excepción al dividir por 0.0?

+4

Buena pregunta: la inconsistencia entre el entero y el comportamiento doble agrega confusión y molestia. –

+2

posible duplicado de [¿Por qué la división por cero con números de punto flotante (o precisión doble) no arroja java.lang.ArithmeticException:/por cero en Java] (http://stackoverflow.com/questions/12954193/why-does- division-by-zero-with-floating-point-or-double-precision-numbers-not) – Raedwald

+2

@Raedwald - teniendo en cuenta que esta pregunta fue publicada dos años y medio antes de la que enlazó, yo diría que esa pregunta es (posible) duplicado de este :) – froadie

Respuesta

42

El resultado de la división por cero es, matemáticamente hablando, indefinido, que se puede expresar con un flotador/doble (como NaN - no es un número), no es, sin embargo, mal en ningún sentido fundamental.

Como un número entero debe contener un valor numérico específico, se debe generar un error en la división por cero al tratar con ellos.

+6

Exactamente. Esto está definido en la Especificación del lenguaje Java aquí: http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2.3 –

+1

Intenté dar salida al resultado, y es un valor NaN. ¿Eso significa que los ints no pueden contener NaN? – froadie

+1

pero este es el caso de '0.0/0.0' que es NaN. –

4

La forma en que se almacena un doble es bastante diferente de un int. Consulte http://firstclassthoughts.co.uk/java/traps/java_double_traps.html para obtener una explicación más detallada sobre cómo maneja Java los cálculos dobles. También debe leer los números de coma flotante, en particular el concepto de Not a Number (NaN).

Si está interesado en obtener más información sobre la representación en coma flotante, le aconsejo que lea this document (formato de Word, lo siento). Se profundiza en la representación binaria de los números, lo que puede ser útil para su comprensión.

101

de Java float y double tipos, como casi cualquier otro idioma por ahí (y casi cualquier unidad de FP de hardware), implementan la norma IEEE 754 para las matemáticas de punto flotante, que obliga a la división por cero para devolver un valor especial "infinito" . Lanzar una excepción en realidad violaría ese estándar.

La aritmética de enteros (implementada como two's complement representada por Java y la mayoría de los demás lenguajes y hardware) es diferente y no tiene valores especiales de infinito o NaN, por lo que arrojar excepciones es un comportamiento útil.

+3

La respuesta correcta a esta pregunta debería ser esta. Necesitaba saber por qué 'float' y' double' no causan Excepciones. Gracias. –

+1

Esta debería ser la respuesta correcta.La respuesta actualmente marcada como correcta no responde a la pregunta, ni deja en claro que Java sigue a IEEE 754. – Necrototem

3

Aunque los desarrolladores de Java saben sobre el tipo primitivo doble y Double clase, mientras se hace la aritmética de punto flotante que no prestan suficiente atención a Double.INFINITY, NaN, -0.0 y otras normas que rigen los cálculos aritméticos que implican ellos.

La respuesta simple a esta pregunta es que no arrojará ArithmeticException y devolverá Double.INFINITY. Además, tenga en cuenta que la comparación x == Double.NaN siempre evalúa a false, incluso si x es un NaN.

Para comprobar si x es un , se debe utilizar la llamada al método Double.isNaN(x) para verificar si el número dado es NaN o no. Esto está muy cerca de NULL en SQL.

Puede ser útil para usted.

1

cuando se divide por cero (0 ó 0,00)

  1. Si se divide por el doble 0, JVM mostrará Infinity.

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

    Consola: Infinity

  2. Si se divide int por 0, y JVM lanzará excepción aritmética.

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

    Consola: Exception in thread "main" java.lang.ArithmeticException:/by zero

  3. Pero si dividimos por int 0.0, a continuación, se mostrará JVM Infinity:

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

    Consola: Infinity

Esto se debe a que JVM automáticamente escribirá "fundir int" en "double", por lo que obtendremos infinity en lugar de "ArithmeticException".

Cuestiones relacionadas