Todos sabemos que 0/0
es Undefined
y devuelve un error si tuviera que ponerlo en una calculadora, y si tuviera que crear un programa (en C por lo menos) el sistema operativo terminaría cuando trato de dividir por cero.
Pero lo que me he estado preguntando es si la computadora incluso intenta dividir por cero , o simplemente tiene "protección incorporada", de modo que cuando "ve" 0/0
devuelve un error incluso antes de intentar calcularlo.
math
error-handling
arithmetic
Ankush
fuente
fuente
Respuestas:
La CPU ha incorporado la detección. La mayoría de las arquitecturas de los conjuntos de instrucciones especifican que la CPU quedará atrapada en un controlador de excepciones para la división entera entre cero (no creo que le importe si el dividendo es cero).
Es posible que la verificación de un divisor cero ocurra en paralelo en el hardware junto con el intento de hacer la división, sin embargo, la detección de la condición ofensiva cancela efectivamente la división y las trampas, por lo que realmente no podemos saber si alguna parte de que intentó la división o no.
(El hardware a menudo funciona así, haciendo varias cosas en paralelo y luego eligiendo el resultado apropiado porque cada una de las operaciones puede comenzar de inmediato en lugar de serializar la elección de la operación adecuada).
El mismo mecanismo de trampa a excepción también se usará cuando la detección de desbordamiento esté activada, lo que usted solicita usualmente usando diferentes instrucciones de agregar / sub / mul (o una marca en esas instrucciones).
La división de punto flotante también tiene una detección integrada para dividir por cero, pero devuelve un valor diferente ( IEEE 754 especifica NaN ) en lugar de atrapar a un controlador de excepciones.
Hipotéticamente hablando, si la CPU omitió cualquier detección para intentar dividir por cero, los problemas podrían incluir:
fuente
Depende del idioma, del compilador, de si está usando números enteros o números de coma flotante, etc.
Para el número de coma flotante, la mayoría de las implementaciones usan el estándar IEEE 754 , donde la división por 0 está bien definida. 0/0 da un resultado bien definido de NaN (no un número), y x / 0 para x ≠ 0 da + Infinito o -Infinito, dependiendo del signo de x.
En lenguajes como C, C ++, etc. la división por cero invoca un comportamiento indefinido. Entonces, según la definición del lenguaje, cualquier cosa puede suceder. Especialmente cosas que no quieres que sucedan. Al igual que todo funciona perfectamente bien cuando escribe el código y destruye los datos cuando su cliente lo usa. Entonces, desde el punto de vista del lenguaje, no hagas esto . Algunos idiomas garantizan que su aplicación se bloqueará; depende de ellos cómo se implementa esto. Para esos idiomas, la división por cero se bloqueará.
Muchos procesadores tienen algún tipo de instrucción de "división" incorporada, que se comportará de manera diferente según el procesador. En los procesadores Intel de 32 bits y 64 bits, las instrucciones de "división" bloquean su aplicación cuando intenta dividir por cero. Otros procesadores pueden comportarse de manera diferente.
Si un compilador detecta que ocurrirá una división por cero cuando ejecuta algún código, y el compilador es bueno para sus usuarios, probablemente le dará una advertencia y generará una instrucción de "división" incorporada para que el comportamiento sea el mismo.
fuente
EXCEPTION_INT_DIVIDE_BY_ZERO
valor en elEXCEPTION_RECORD
que será manejado por el (con suerte) Structed Exception Handling HandlerParece que te estás preguntando qué pasaría si alguien hiciera una CPU que no compruebe explícitamente cero antes de dividir. Lo que suceda depende completamente de la implementación de la división. Sin entrar en detalles, un tipo de implementación produciría un resultado que tiene todos los bits establecidos, por ejemplo, 65535 en una CPU de 16 bits. Otro podría colgar.
fuente
Como
x/0
no tiene sentido, punto, las computadoras siempre deben verificar la división por cero. Aquí hay un problema: los programadores quieren calcular(a+b)/c
sin tener que molestarse en verificar si ese cálculo tiene sentido. La respuesta subyacente a la división por cero por la CPU + tipo de número + sistema operativo + lenguaje es hacer algo bastante drástico (por ejemplo, bloquear el programa) o hacer algo demasiado benigno (por ejemplo, crear un valor que no sentido como el punto flotante IEEENaN
, un número que es "No es un número").En un entorno ordinario, se espera que un programador sepa si
(a+b)/c
tiene sentido. En este contexto, no hay razón para verificar la división por cero. Si ocurre la división por cero, y si el lenguaje de máquina + lenguaje de implementación + tipo de datos + respuesta del sistema operativo a esto es hacer que el programa se bloquee, está bien. Si la respuesta es crear un valor que eventualmente pueda contaminar cada número del programa, también está bien.Ni "algo drástico" ni "demasiado benigno" es lo correcto en el mundo de la informática de alta confiabilidad. Esas respuestas predeterminadas pueden matar a un paciente, estrellar un avión o hacer explotar una bomba en el lugar equivocado. En un entorno de alta confiabilidad, un programador que escribe
(a+b)/c
será asesinado durante la revisión del código, o en los tiempos modernos, tal vez sea asesinado automáticamente por una herramienta que verifica las construcciones verboten. En este entorno, ese programador debería haber escrito algo similar adiv(add(a,b),c)
(y posiblemente alguna comprobación del estado de error). Debajo del capó, lasdiv
(y también lasadd
) funciones / macros protegen contra la división por cero (o desbordamiento en el caso deadd
). Lo que implica esa protección es muy específico de implementación.fuente
Ahora sabemos eso
x/0
y0/0
no tenemos respuestas bien definidas. ¿Qué sucede si intentas calcular de0/0
todos modos?En un sistema moderno, el cálculo se pasa a la MPU dentro de la CPU y se marca como una operación ilegal, regresando
NaN
.En un sistema mucho más antiguo, como las computadoras hogareñas de los años 80 que no tenían división en chip, el cálculo se realizaba con cualquier software que se estuviera ejecutando. Hay algunas opciones posibles:
0
1
log(0)
y el software utilizará sus rutinas de manejo de errores o se bloqueará0
y e 0 = 1, dando un resultado de1
En otras palabras, dependería de la implementación lo que sucedería y sería posible escribir software que produzca resultados correctos y predecibles para cada valor, pero valores aparentemente extraños para
0/0
eso son, sin embargo, aún internamente consistentes.fuente
NaN
en los enteros.very inefficient
para la división. El costo de la aritmética es (suma = resta) <= multiplicación <= división. Si no tiene una MPU que pueda dividir en el mismo número de ciclos de reloj que la suma (generalmente uno), entonces la división es más costosa que la suma y la resta y, por lo general, también más costosa que la multiplicación.