¿Una computadora intentará dividir entre cero?

58

Todos sabemos que 0/0 es Undefined y devuelve un error si lo pusiera en una calculadora, y si tuviera que crear un programa (al menos en C), el sistema operativo lo terminaría cuando intentara dividir por cero.

Pero lo que me he estado preguntando es si la computadora incluso intenta dividir entre cero , o simplemente tiene "protección integrada", de modo que cuando "ve" 0/0 it devuelve un error incluso antes de intentar calcularlo?

    
pregunta Ankush 26.02.2016 - 08:33

5 respuestas

74

La CPU tiene una detección integrada. La mayoría de las arquitecturas de conjuntos de instrucciones especifican que la CPU capturará un controlador de excepciones para la división de enteros 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 no podemos decirlo. si alguna parte de ella intentó la división o no.

(El hardware a menudo funciona así, haciendo varias cosas en paralelo y luego seleccionando el resultado apropiado porque cada una de las operaciones puede comenzar de inmediato en lugar de serializar la opción de la operación apropiada).

El mismo mecanismo de captura a excepción también se utilizará cuando la detección de desbordamiento esté activada, lo que suele solicitar utilizando 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 < a href="https://en.wikipedia.org/wiki/NaN"> NaN ) en lugar de interceptar un controlador de excepciones.

Hablando hipotéticamente, si la CPU omite cualquier detección para intentar dividir entre cero, los problemas podrían incluir:

  • colgar la CPU (por ejemplo, en un bucle inf.): esto puede suceder si la CPU usa un algoritmo para dividir que se detiene cuando el numerador es menor que el divisor (en valor absoluto). Una caída como esta contaría como un fallo en la CPU.
  • una respuesta de basura (posiblemente predecible), si la CPU usa un contador para terminar la división en el número máximo posible de pasos de división (por ejemplo, 31 o 32 en una máquina de 32 bits).
respondido por el Erik Eidt 26.02.2016 - 08:41
34

Depende del idioma, del compilador, de si está utilizando números enteros o de coma flotante, etc.

Para el número de punto flotante, la mayoría de las implementaciones utilizan el estándar IEEE 754 , donde la división por 0 está bien definida. 0/0 da un resultado bien definido de NaN (no es 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, de acuerdo con la definición del idioma, 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 datos cuando el cliente lo usa. Entonces, desde el punto de vista del idioma, 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 estrellará.

Muchos procesadores tienen algún tipo de instrucción integrada de "dividir", que se comportará de manera diferente dependiendo del procesador. En los procesadores Intel de 32 bits y 64 bits, las instrucciones de "división" bloquearán su aplicación cuando intente dividir por cero. Otros procesadores pueden comportarse de manera diferente.

Si un compilador detecta que ocurrirá una división por cero cuando ejecute algún código, y el compilador es bueno para sus usuarios, es probable que le dé una advertencia y genere una instrucción integrada de "división" para que El comportamiento es el mismo.

    
respondido por el gnasher729 26.02.2016 - 10:38
13

Parece que te estás preguntando qué pasaría si alguien creara una CPU que no comprueba explícitamente el cero antes de dividir. Lo que sucedería depende enteramente 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.

    
respondido por el Bingo 26.02.2016 - 13:18
1
  

Pero lo que me he estado preguntando es si la computadora incluso intenta dividir por cero, o simplemente tiene "protección integrada", de modo que cuando "ve" 0/0 devuelve un error incluso antes de intentar computarlo?

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 comprobar si ese cálculo tiene sentido. La respuesta debajo de la cubierta a la división por cero por la CPU + tipo de número + sistema operativo + idioma es hacer algo bastante drástico (por ejemplo, bloquear el programa) o hacer algo demasiado benigno (por ejemplo, crear un valor que no haga sentido como el punto flotante IEEE NaN , un número que es "No es un número").

En una configuración normal, 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 se produce una división por cero, y si el lenguaje de máquina + el idioma de implementación + el tipo de datos + el sistema operativo responden a esto para bloquear el programa, está bien. Si la respuesta es crear un valor que eventualmente pueda contaminar cada número en el programa, también está bien.

Ni "algo drástico" ni "demasiado benigno" es lo correcto en el mundo de la computación 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á ejecutado durante la revisión del código, o en los tiempos modernos, quizás eliminado automáticamente por una herramienta que verifica las construcciones verboten. En este entorno, ese programador debería haber escrito algo en la línea de div(add(a,b),c) (y posiblemente algún control de estado de error). Debajo de la cubierta, las funciones / macros div (y también el add ) protegen contra la división por cero (o desbordamiento en el caso de add ). Lo que conlleva esa protección es muy específico de la implementación.

    
respondido por el David Hammen 28.02.2016 - 18:39
-2

Ya sabemos que x/0 y 0/0 no tienen respuestas bien definidas. ¿Qué sucede si intentas calcular 0/0 de 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, devolviendo NaN .

En un sistema mucho más antiguo, como las computadoras domésticas de los años 80 que no tenían una división en el chip, el cálculo fue realizado por cualquier software que se estuviera ejecutando. Hay algunas opciones posibles:

  • Reste copias cada vez más pequeñas del divisor hasta que el valor llegue a cero y haga un seguimiento de las copias de los que se restaron
    • Si comprueba cero antes de la primera resta, saldrá rápidamente y el resultado será 0
    • Si asume que debe poder restar al menos una vez, el resultado será 1
  • Calcule los logaritmos de ambos números, reste y aumente e a la potencia del resultado. Un método muy ineficiente comparado con el método de sustracción anterior, pero matemáticamente válido
    • Puede ocurrir un desbordamiento al intentar calcular log(0) y el software usará sus rutinas de manejo de errores o se bloqueará
    • El software podría asumir que todos los logaritmos se pueden calcular en un número fijo de pasos y devolver un valor grande, pero incorrecto. Dado que ambos logaritmos serían iguales, la diferencia sería 0 y e 0 = 1, dando un resultado de 1

En otras palabras, dependería de la implementación lo que sucedería y sería posible escribir un software que produzca resultados correctos y predecibles para cada valor pero valores aparentemente extraños para 0/0 que todavía son internamente coherentes.

    
respondido por el CJ Dennis 27.02.2016 - 22:45

Lea otras preguntas en las etiquetas