Todos nós sabemos que 0/0
é Undefined
e retorna um erro se eu o colocasse em uma calculadora e se eu criasse um programa (pelo menos em C) o sistema operacional o encerraria quando tento dividir por zero.
Mas o que eu queria saber é se o computador tenta dividir por zero , ou apenas possui "proteção interna", de modo que, quando "vê" 0/0
, retorna um erro antes mesmo de tentar calculá-lo?
math
error-handling
arithmetic
Ankush
fonte
fonte
Respostas:
A CPU foi incorporada na detecção. A maioria das arquiteturas de conjunto de instruções especifica que a CPU interceptará um manipulador de exceção para a divisão de números inteiros por zero (não acho que se importe se o dividendo for zero).
É possível que a verificação de um divisor zero ocorra paralelamente no hardware, juntamente com a tentativa de fazer a divisão; no entanto, a detecção da condição ofensiva efetivamente cancela a divisão e intercepta, portanto, não podemos realmente dizer se alguma parte disso, tentou a divisão ou não.
(O hardware geralmente funciona dessa maneira, fazendo várias coisas em paralelo e depois escolhendo o resultado apropriado, porque todas as operações podem começar imediatamente, em vez de serializar a escolha da operação apropriada.)
O mesmo mecanismo de interceptação para exceção também será usado quando a detecção de estouro estiver ativada, o que você solicita geralmente usando instruções add / sub / mul diferentes (ou um sinalizador nessas instruções).
A divisão de ponto flutuante também tem detecção embutida para dividir por zero, mas retorna um valor diferente ( IEEE 754 especifica NaN ) em vez de interceptar um manipulador de exceção.
Hipoteticamente, se a CPU omitir qualquer detecção por tentativa de dividir por zero, os problemas podem incluir:
fonte
Depende do idioma, do compilador, se você está usando números inteiros ou de ponto flutuante, e assim por diante.
Para número de ponto flutuante, a maioria das implementações usa o padrão IEEE 754 , onde a divisão por 0 é bem definida. 0/0 fornece um resultado bem definido de NaN (não um número), e x / 0 para x ≠ 0 fornece + Infinity ou -Infinity, dependendo do sinal de x.
Em linguagens como C, C ++ etc., a divisão por zero invoca um comportamento indefinido. Portanto, de acordo com a definição da linguagem, tudo pode acontecer. Especialmente coisas que você não quer que aconteça. Como tudo funcionando perfeitamente quando você escreve o código e destrói os dados quando o cliente o usa. Portanto, do ponto de vista do idioma, não faça isso . Alguns idiomas garantem que seu aplicativo falhe; cabe a eles como isso é implementado. Para esses idiomas, a divisão por zero falhará.
Muitos processadores possuem algum tipo de instrução de "divisão" integrada, que se comportará de maneira diferente dependendo do processador. Nos processadores Intel de 32 bits e 64 bits, as instruções "dividir" travam o aplicativo quando você tenta dividir por zero. Outros processadores podem se comportar de maneira diferente.
Se um compilador detectar que uma divisão por zero ocorrerá quando você executar algum código, e o compilador for bom para seus usuários, provavelmente fornecerá um aviso e gerará uma instrução interna de "divisão" para que o comportamento seja o mesmo.
fonte
EXCEPTION_INT_DIVIDE_BY_ZERO
valor noEXCEPTION_RECORD
qual será tratado pelo (esperançosamente) manipulador de manipulação de exceção estruturada instaladoParece que você está se perguntando o que aconteceria se alguém fizesse uma CPU que não verifica explicitamente zero antes de dividir. O que aconteceria depende inteiramente da implementação da divisão. Sem entrar em detalhes, um tipo de implementação produziria um resultado com todos os bits definidos, por exemplo, 65535 em uma CPU de 16 bits. Outro pode desligar.
fonte
Como
x/0
não faz sentido, ponto final, os computadores devem sempre verificar a divisão por zero. Há um problema aqui: os programadores querem calcular(a+b)/c
sem ter que se preocupar em verificar se esse cálculo ainda faz sentido. A resposta secreta à divisão por zero pela CPU + tipo de número + sistema operacional + idioma é fazer algo bastante drástico (por exemplo, travar o programa) ou fazer algo excessivamente benigno (por exemplo, criar um valor que não prejudique sentido como o ponto flutuante IEEENaN
, um número que é "Não é um número").Em um ambiente comum, espera-se
(a+b)/c
que um programador saiba se faz sentido. Nesse contexto, não há razão para verificar a divisão por zero. Se a divisão por zero ocorrer, e se a resposta da linguagem de máquina + linguagem de implementação + tipo de dados + sistema operacional a isso for travar o programa, tudo bem. Se a resposta for criar um valor que possa eventualmente poluir todos os números do programa, tudo bem também.Nem "algo drástico" ou "excessivamente benigno" é a coisa certa a se fazer no mundo da computação de alta confiabilidade. Essas respostas padrão podem matar um paciente, derrubar um avião ou fazer uma bomba explodir no lugar errado. Em um ambiente de alta confiabilidade, um programador que escreve
(a+b)/c
será morto durante a revisão de código ou, nos tempos modernos, talvez morto automaticamente por uma ferramenta que verifica construções de verboten. Nesse ambiente, esse programador deveria ter escrito algo comodiv(add(a,b),c)
(e possivelmente alguma verificação do status do erro). Sob o capô, asdiv
(e também asadd
) funções / macros protegem contra a divisão por zero (ou transbordamento no caso deadd
). O que essa proteção implica é muito específico da implementação.fonte
Já sabemos disso
x/0
e0/0
não temos respostas bem definidas. O que acontece se você tentar calcular de0/0
qualquer maneira?Em um sistema moderno, o cálculo é passado para a MPU na CPU e é sinalizado como uma operação ilegal, retornando
NaN
.Em um sistema muito mais antigo, como os computadores domésticos dos anos 80 que não tinham divisão no chip, o cálculo era feito por qualquer software que estivesse sendo executado. Existem algumas opções possíveis:
0
1
log(0)
e o software usa suas rotinas de tratamento de erros ou falha0
e e 0 = 1, resultando em1
Em outras palavras, seria dependente da implementação o que aconteceria e seria possível escrever um software que produza resultados corretos e previsíveis para todos os valores, mas valores aparentemente estranhos para
0/0
isso, no entanto, ainda são internamente consistentes.fonte
NaN
os números inteiros.very inefficient
para divisão. O custo da aritmética é (adição = subtração) <= multiplicação <= divisão. Se você não possui uma MPU que pode fazer a divisão no mesmo número de ciclos de clock da adição (geralmente um), a divisão é mais cara que a adição e subtração e geralmente mais cara que a multiplicação.