Um computador tentará dividir por zero?

58

Nós todos sabemos que 0/0 é Undefined e retorna um erro se eu fosse colocá-lo em uma calculadora, e se eu fosse criar um programa (pelo menos em C) o SO terminaria quando eu tentasse dividir por zero.

Mas o que eu tenho imaginado é se o computador tenta até mesmo dividir por zero , ou ele apenas tem "proteção embutida", então quando ele "vê" 0/0 it retorna um erro mesmo antes de tentar computá-lo?

    
por Ankush 26.02.2016 / 08:33
fonte

5 respostas

74

A CPU possui detecção integrada. A maioria das arquiteturas de conjunto de instruções especificam que a CPU irá 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 aconteça paralelamente em hardware junto com a tentativa de fazer a divisão, no entanto, a detecção da condição ofensiva efetivamente cancela a divisão e as armadilhas, então não podemos dizer realmente se alguma parte dele tentou a divisão ou não.

(O hardware geralmente funciona assim, fazendo várias coisas em paralelo e depois escolhendo o resultado apropriado depois, porque então cada uma das operações pode começar imediatamente, em vez de serializar a escolha da operação apropriada.)

A mesma armadilha para o mecanismo de exceção também será usada quando a detecção de overflow estiver ativada, o que você pede normalmente usando instruções add / sub / mul diferentes (ou um sinalizador nessas instruções).

Divisão de ponto flutuante também incorporou detecção para divisão por zero, mas retorna um valor diferente ( IEEE 754 especifica < href="https://en.wikipedia.org/wiki/NaN"> NaN ) em vez de trapping para um manipulador de exceção.

Hipoteticamente falando, se a CPU omitiu qualquer detecção para tentativa de divisão por zero, os problemas poderiam incluir:

  • desligar a CPU (por exemplo, em um loop inf.) - isso pode acontecer se a CPU usar um algoritmo para dividir que pare quando o numerador for menor que o divisor (em valor absoluto). Um problema como esse seria praticamente considerado como falha na CPU.
  • uma resposta de lixo (possivelmente previsível), se a CPU usar um contador para terminar a divisão no número máximo possível de etapas de divisão (por exemplo, 31 ou 32 em uma máquina de 32 bits).
por 26.02.2016 / 08:41
fonte
34

Depende da linguagem, do compilador, se você está usando números inteiros ou números de ponto flutuante, e assim por diante.

Para o 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 dá um resultado bem definido de NaN (não-um-número), e x / 0 para x ≠ 0 dá + Infinity ou -Infinity, dependendo do sinal de x.

Em linguagens como C, C ++, etc., a divisão por zero invoca o comportamento indefinido. Então, de acordo com a definição da linguagem, qualquer coisa pode acontecer. Especialmente coisas que você não quer que aconteçam. Como tudo funcionando perfeitamente quando você escreve o código e destrói dados quando o cliente o usa. Então, do ponto de vista da linguagem, não faça isso . Algumas linguagens garantem que seu aplicativo irá travar; cabe a eles como isso é implementado. Para esses idiomas, a divisão por zero irá falhar.

Muitos processadores possuem algum tipo de instrução "dividir", que se comportará de maneira diferente dependendo do processador. Nos processadores Intel de 32 bits e 64 bits, as instruções de "divisão" irão travar seu aplicativo quando você tentar dividir por zero. Outros processadores podem se comportar de maneira diferente.

Se um compilador detectar que uma divisão por zero acontecerá quando você executar algum código, e o compilador for legal para seus usuários, ele provavelmente dará um aviso, e gerará uma instrução "dividir" embutida para que o comportamento é o mesmo.

    
por 26.02.2016 / 10:38
fonte
13

Parece que você está se perguntando o que aconteceria se alguém fizesse uma CPU que não verifique 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.

    
por 26.02.2016 / 13:18
fonte
1

But what I've been wondering is if the computer even attempts to divide by zero, or does it just have "built in protection", so that when it "sees" 0/0 it returns an error even before attempting to compute it?

Como x/0 não faz sentido, ponto, os computadores devem sempre verificar a divisão por zero. Há um problema aqui: os programadores querem calcular (a+b)/c sem precisar se preocupar em verificar se esse cálculo faz sentido. A resposta abaixo da divisão por zero pela CPU + tipo de número + sistema operacional + linguagem é fazer algo bastante drástico (por exemplo, travar o programa) ou fazer algo excessivamente benigno (por exemplo, criar um valor que não faz sentido, como o ponto flutuante IEEE NaN , um número que é "Não é um número").

Em uma configuração comum, espera-se que um programador saiba se (a+b)/c faz sentido. Neste contexto, não há razão para verificar a divisão por zero. Se a divisão por zero acontecer, e se a linguagem da máquina + linguagem de implementação + tipo de dados + resposta do sistema operacional para isso fizer o programa travar, 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, colidir com um avião de passageiros ou fazer uma bomba explodir no lugar errado. Em um ambiente de alta confiabilidade, um programador que escreve (a+b)/c será picado até a morte durante a revisão de código ou, nos tempos modernos, talvez seja morto automaticamente por uma ferramenta que verifica as construções de verboten. Nesse ambiente, esse programador deve ter escrito algo nos moldes de div(add(a,b),c) (e possivelmente alguma verificação de status de erro). Sob o capô, as funções / macros div (e também a add ) protegem contra divisão por zero (ou estouro no caso de add ). O que essa proteção implica é muito específico da implementação.

    
por 28.02.2016 / 18:39
fonte
-2

Sabemos que x/0 e 0/0 não têm respostas bem definidas. O que acontece se você tentar calcular 0/0 mesmo assim?

Em um sistema moderno, o cálculo é passado para a MPU dentro da 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 escolhas possíveis:

  • Subtraia cópias menores e menores do divisor até que o valor chegue a zero e acompanhe quais cópias foram subtraídas
    • Se verificar zero antes da primeira subtração, sairá rapidamente e o resultado será 0
    • Se assumir que deve ser capaz de subtrair pelo menos uma vez, o resultado será 1
  • Calcule os logaritmos de ambos os números, subtraia-os e aumente e para o poder do resultado. Um método muito ineficiente comparado ao método de subtração acima, mas matematicamente válido
    • Um estouro pode ocorrer ao tentar calcular log(0) e o software usaria suas rotinas de tratamento de erros ou travaria
    • O software pode assumir que todos os logaritmos podem ser calculados em um número fixo de etapas e retornar um valor grande, mas incorreto. Como os dois logaritmos seriam iguais, a diferença seria 0 e e 0 = 1, dando um resultado de 1

Em outras palavras, seria implementação dependente do que aconteceria e seria possível escrever um software que produza resultados corretos e previsíveis para cada valor, mas valores aparentemente estranhos para 0/0 que são, no entanto, ainda internamente consistentes.

    
por 27.02.2016 / 22:45
fonte