Pregunta

¿Por qué Java no puede devolver un valor con gracia con una división por cero y, en cambio, tiene que lanzar una excepción?

Estoy recibiendo un ArrayIndexOutOfBoundsException:0 Esto se debe a que Damagetaken es en realidad una variedad de valores que almacena muchos 'daños' diferentes.

En Java estoy tratando de crear una barra de progreso. Nuestro ejemplo: el daño incurrido, en un juego de carreras, al establecer el valor para la altura como porcentaje del daño máximo permitido antes de Gameover.

Al comienzo del programa damageTaken = 0;

(damageTaken / maximumDamage)

dará números entre 0 a 1.

Luego, simplemente multiplico que por la altura de la barra de progreso, para crear una barra de relleno de la altura apropiada.

El programa se bloquea. ¡Quiero que la barra de progreso sea de cero altura!

¿Fue útil?

Solución

No te estás dividiendo por cero, eres dividiendo cero por algo.

Está completamente permitido tomar dos mitades de cero. La respuesta es cero. Digamos que tienes cero manzanas. Divides tus cero manzanas entre Alice y Bob. Alice y Bob ahora tienen cero manzanas.

Pero, no puedes dividir por cero. Digamos que tienes dos manzanas. Ahora, quieres dar estas manzanas a cero personas. ¿Cuántas manzanas obtiene cada persona? La respuesta está indefinida, por lo que la división por cero es imposible.

Otros consejos

(damageTaken / maximumDamage)

Esto te da una división por cero excepción solo si maximumDamage es cero.

Si damageTaken es cero, no hay problema.

Simplemente agregue un caso especial para 0;

private int getProgress()
    if (damageTaken == 0) {
        return 0;
    } else {
        return (damageTaken / maximumDamage) * progress.getHeight();
    }
}

Sin embargo, (y es un gran) la razón por la que te estás dividiendo por 0 es porque maximumDamage es 0, no damageTaken. Entonces, lo que probablemente realmente quieras es:

private int getProgress()
    if (maximumDamage== 0) {
        return 0;
    } else {
        return (damageTaken / maximumDamage) * progress.getHeight();
    }
}

Dejemos de hablar de ilegalidad, como si la policía de matemáticas uniformadas estuviera a punto de asaltar la habitación. ;) Para el razonamiento matemático detrás de esto, Esta pregunta relacionada es útil.

Es justo preguntar por qué, después de todo este tiempo, las plataformas de programación modernas no manejan los errores de división por cero por nosotros de alguna manera estándar, pero para responder la pregunta: Java, como la mayoría de cualquier otra plataforma, arroja un error cuando se produce la división por cero. En general, usted puede:

  • Manejo antes: verifique la variable que se utilizará como su denominador para cero antes de hacer la división
  • Manejo después: puede ver la excepción lanzada cuando ocurre la división por cero y manejarla con gracia.

Tenga en cuenta que, como buena práctica, el segundo método solo es apropiado cuando no esperaría que la variable sea cero En operación normal del sistema.

Entonces, sí, necesita un caso especial para manejar esta situación. Bienvenido a la programación. ;)

Conceptualmente, tener un rendimiento de 4/0 algún número arbitrario no sería peor que tener un intento de duplicar un recuento de 2000000000 de rendimiento de -294967296. Sin embargo, la mayoría de los procesadores ignorarán la mayoría de los tipos de desbordamiento aritmético a menos que uno verifique explícitamente, pero no puede ignorar un intento de dividir en cero a menos que uno verifique explícitamente los operandos de antemano (y omita la operación si no son válidas). Dado que muchos procesadores tienen banderas de "desbordamiento", nada evitaría que un procesador especifique que un intento de división por cero simplemente no hacer nada más que establecer el indicador de desbordamiento (una operación de división exitosa debería aclararlo); El código que quiere activar una excepción en tal caso podría hacerlo.

Sospecho que la razón del comportamiento distinto proviene de los primeros días de la informática; El hardware para una instrucción de división podría juzgar que estaba completo cuando el resto era menor que el divisor. Si eso nunca sucedió, la instrucción podría estancarse hasta que un circuito de reloj de supervisión general (diseñado para señalar una falla si por cualquier razón, las instrucciones dejan de ejecutar) apague las cosas. El hardware para detectar el problema y la salida sin detener la CPU habría sido trivial para los estándares actuales, pero en los días en que las computadoras se construyeron a partir de transistores discretos, era más barato y casi tan efectivo, informar a los programadores No intentes dividir por cero, nunca.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top