(Completas) Tutorial para compreender IEEE erros de ponto flutuante

Traduções deste artigo Traduções deste artigo
ID do artigo: 42980 - Exibir os produtos aos quais esse artigo se aplica.
Expandir tudo | Recolher tudo

Neste artigo

Sumário

Matemática de ponto flutuante é um tópico complexo que muitos programadores confunde. O tutorial abaixo deve ajudar a reconhecer programação situações onde os erros de ponto flutuante são prováveis de ocorrer e como evitá-los. Ele também deve permitem que você a reconhecer casos são causados por limitações inerentes matemática de ponto flutuante em oposição a bugs de compilador real.

Mais Informações

Decimal e binário número sistemas

Normalmente, podemos contar as coisas de base 10. A base é completamente arbitrária. O único motivo que as pessoas tem usado tradicionalmente base 10 é que eles têm 10 dedos, que fez a contagem de ferramentas úteis.

O número 532.25 em decimal (base 10) significa que o seguinte:
   (5 * 10^2) + (3 * 10^1) + (2 * 10^0) + (2 * 10^-1) + (5 * 10^-2)
       500    +     30     +      2     +     2/10    +    5/100
   _________
   =  532.25
				

No sistema de número binário (base 2), cada coluna representa uma potência de 2 em vez de 10. Por exemplo, o número 101.01 significa que o seguinte:
   (1 * 2^2) + (0 * 2^1) + (1 * 2^0) + (0 * 2^-1) + (1 * 2^-2)
       4     +      0    +     1     +      0     +    1/4
   _________
   =  5.25  Decimal
				

Como números inteiros estão representados nos PCs

Como não há nenhuma parte fracionária para um inteiro, sua representação de máquina é muito mais simples do que valores de ponto flutuante. Números inteiros normais em computadores pessoais (PCs) são 2 bytes (16 bits) longo com o bit mais significativo indicando o sinal. Números inteiros longos são 4 bytes. Valores positivos são números binários simples. Por exemplo:
    1 Decimal = 1 Binary
    2 Decimal = 10 Binary
   22 Decimal = 10110 Binary, etc.
				

No entanto, números inteiros negativos são representados usando dos dois complemento esquema. Para obter dos dois complemento representação para um número negativo, coloque a representação binária para valor de absoluto do número e inverter todos os bits e adicionar 1. Por exemplo:
   4 Decimal = 0000 0000 0000 0100
               1111 1111 1111 1011     Flip the Bits
   -4        = 1111 1111 1111 1100     Add 1
				

Observe que-1 decimal = 1111 1111 1111 1111 em binário, que explica por que o Basic trata-1 como true lógico (todos os bits = 1). Isso é uma conseqüência de não ter operadores separados para comparações lógicas e bit a bit. Com freqüência no Basic, é conveniente usar o fragmento de código abaixo quando seu programa farão muitas comparações lógicas. Isso ajuda muito legibilidade.
   CONST TRUE = -1
   CONST FALSE = NOT TRUE
				

Observe que adicionar qualquer combinação do dois complementar números juntos usando comum aritmética binária produz o resultado correto.

Ponto flutuante complicações

Cada inteiro decimal pode ser representado por um inteiro binário exatamente; no entanto, isso não é verdadeiro para números fracionários. Na verdade, cada número que seja irrational na base 10 também será irrational em qualquer sistema com uma base menor do que 10.

Para binário, em particular, números fracionários apenas que possam ser representados no p de formulário/q, onde q é uma potência de número inteiro de 2, podem ser expressos exatamente, com um número finito de bits.

Frações decimais mesmo comuns, como decimal 0,0001, não pode ser representadas exatamente em binário. (0,0001 é uma fração binária repetição com um período de 104 bits!)

Isso explica por que um exemplo simples, como o seguinte
   SUM = 0
   FOR I% = 1 TO 10000
      SUM = SUM + 0.0001
   NEXT I%
   PRINT SUM                   ' Theoretically = 1.0.
				

será PRINT 1.000054 como saída. O pequeno erro na representação 0,0001 em binário propaga para a soma.

Pelo mesmo motivo, você deve sempre ter muito cuidado ao fazer comparações no números reais. O exemplo a seguir ilustra um erro de programação comum:
   item1# = 69.82#
   item2# = 69.20# + 0.62#
   IF item1# = item2# then print "Equality!"
				

Isso não PRINT "Igualdade!" porque não pode ser representado 69.82 exatamente no binário, que faz com que o valor que resulta da atribuição para ser um POUCO diferente (em binário) que o valor é gerado a partir da expressão. Na prática, você deve sempre código tais comparações de forma a permitir que para alguns tolerância. Por exemplo:
   IF (item1# < 69.83#) AND (item1# > 69.81#) then print "Equal"
				

Isso será PRINT "Igual".

IEEE Formatar números

QuickBasic para MS-DOS versão 3.0 foi fornecido com uma versão MBF (Microsoft binário flutuante pontos) e uma versão IEEE (Institute of Electrical and Electronics Engineers) para computadores com um co-processador matemático. QuickBasic para MS-DOS, as versões 4.0 e posteriores só usam IEEE. Microsoft escolheu o padrão IEEE para representar valores de ponto flutuante em versões atuais do Basic pelos seguintes três motivos principais:
  1. Para permitir Basic para usar os Intel matemática coprocessors, qual formato usar IEEE. Os Intel 80 x 87 série coprocessors não é possível trabalhar com números de formato binário do Microsoft.
  2. Para tornar interlanguage chamar entre Basic, C, Pascal, FORTRAN e MASM muito mais fácil. Caso contrário, as rotinas de conversão teria de ser usado para enviar valores numéricos de um idioma para outro.
  3. Para obter consistência. IEEE é o aceita padrão da indústria para compiladores C e FORTRAN.
A seguir está uma comparação rápida de representações IEEE e MBF para um número de precisão dupla:
               Sign Bits   Exponent Bits   Mantissa Bits
               ---------   -------------   -------------
   IEEE        1           11              52 + 1 (Implied)
    MBF        1            8              56
				

Para obter mais informações sobre as diferenças entre IEEE e MBF representação ponto flutuante, de consulta na Base de dados de Conhecimento da Microsoft as seguintes palavras:
   IEEE and floating and point and appnote
				

Observe que o IEEE tem mais bits dedicados a expoente, que permite que representam uma variedade maior de valores. MBF tem mais mantissa bits, que permite que ele ser mais preciso dentro de seu intervalo mais estreita.

Conceitos gerais de ponto flutuante

É importante perceber que qualquer sistema de ponto flutuante binário pode representar apenas um número finito de valores de ponto flutuante no formulário exato. Todos os outros valores devem ser aproximados pelo valor representáveis mais próximo. O padrão IEEE especifica o método de arredondamento de valores para o valor representáveis "mais próximo". QuickBasic para MS-DOS suporta o padrão e arredondado de acordo com as regras do IEEE.

Além disso, tenha em mente que os números que podem ser representados no IEEE estão espalhados em um intervalo muito grande. Você pode imaginá-los em uma linha de número. Há uma alta densidade de números representáveis próximo 1.0 e-1.0 mas menos e menos que você vá para 0 ou infinito.

O objetivo do padrão IEEE, que é projetado para cálculos, de engenharia é maximizar a precisão (para obter número feche possível para o real). Precisão refere-se ao número de dígitos que você pode representar. O padrão IEEE tenta equilibrar o número de bits dedicados para o expoente com o número de bits usados para a parte fracionária do número, para manter a precisão e a precisão dentro dos limites aceitáveis.

Detalhes do IEEE

Números de ponto flutuante são representados no seguinte formato, onde [expoente] é o expoente binário:
   X =  Fraction * 2^(exponent - bias)
				

[Fração] é a parte fracionária normalizada do número, normalizado porque o expoente é ajustado para que o bit à esquerda é sempre um 1. Dessa forma, ele não precisa ser armazenado e obtenha um pouco mais de precisão. É por isso que há um bit implícito. Você pode considerar isso como notação científica, onde você manipular o expoente com um dígito à esquerda da vírgula decimal, exceto em binário, você pode sempre manipular o expoente para o primeiro bit é um 1, já que existem apenas 1s e 0s.

[diferença] é o valor de ajuste usado para evitar ter que armazenar lado dos expoentes negativos.

A diferença para números de precisão simples é 127 e 1023 (decimal) para números de precisão dupla.

Os valores iguais para todos os 0s e 1s (binário) são reservados para representar casos especiais. Há outros casos especiais, que indicam a várias condições de erro.

Exemplos de precisão única

2 = 1 * 2 ^ 1 = 0000 0100 0000 a 0000... 0000 0000 = hex 4000 0000
Observação o bit de sinal é zero e o expoente armazenado é 0 0000 128 ou 100 em binário, que é 127 mais 1. Mantissa armazenado é (1). 000 0000... 0000 0000, que tem um líder implícita 1 e binário apontar, portanto, mantissa real é 1.

-2 =-1 * 2 ^ 1 = 0000 1100 0000 A 0000... 0000 0000 = C000 0000 hex
Mesmo + 2, exceto que o bit de sinal é definido. Isso é verdadeiro para todos os números de ponto flutuante formato IEEE.

4 = 1 * 2 ^ 2 = 0000 0100 1000 0000... 0000 0000 = hex 4080 0000
Mesmo mantissa, expoente aumenta em um (ajustada valor é 1 0000 129 ou 100 em binário.

6 = 1,5 * 2 ^ 2 = 0000 0100 1100 0000... 0000 0000 = 40 C 0 hex 0000
Mesmo expoente, mantissa é maior por metade--é 100 (1). 0000... 0000 0000, que, como esta é uma fração binária é 1-1/2 (os valores de dígitos fracionários são 1/2, 1/4, 1/8, etc..).

1 = 1 * 2 ^ 0 = 0011 1111 1000 0000... 0000 0000 = 3F80 0000 hex
Mesmo expoente como outras potências de 2, mantissa é uma menor que 2 em 1111 1 127 ou 011 em binário.

0,75 = 1,5 * 2 ^-1 = 0011 1111 0100 0000... 0000 0000 = 3F40 0000 hex
O expoente ajustado é 126, 011 1111 binário em 0 e o mantissa é 100 (1). 0000... 0000 0000, 1-1/2.

2.5 = 1,25 * 2 ^ 1 = 0000 0100 0010 0000... 0000 0000 = hex 4020 0000
Exatamente o mesmo que 2, exceto que o bit que representa 1/4 é definido no mantissa.

0,1 = 1,6 * 2 ^-4 = 0011 1101 1100 1100... 1100 1101 = 3DCC CCCD hex
1/10 é uma fração de repetição em binário. O mantissa é apenas tímido de 1.6, e o expoente ajustado diz que 1.6 seja dividido por 16 (é 011 1101 1 em binário, que é 123 em decimal). O expoente true é 127 123 = - 4, o que significa que o fator pelo qual multiplicar é 2 **-4 = 1/16. Observe que mantissa armazenado é arredondado o último bit. Isso é uma tentativa para representar o número não representável com precisão possível. (O motivo 1 e 1/10/100 são não exatamente representáveis no binário é semelhante da maneira que 1/3 é não exatamente representáveis no formato decimal.)

0 = 1.0 * 2 ^-128 = zeros--um caso especial.

Outros erros comuns de ponto flutuante

Estes são erros comuns de ponto flutuante:
  1. Erro de arredondamento

    Este erro ocorre quando todos os bits em um número binário não podem ser usados em um cálculo.

    Exemplo: Adicionar 0,0001 para 0.9900 (precisão simples)

    Decimal 0,0001 serão representados como:
    10100011011011100010111 (1). * 2^(-14+Bias) (13 levam 0s em binário!)
    0.9900 serão representados como:
    11111010111000010100011 (1). * 2^(-1+Bias)
    Agora para adicionar, na verdade, esses números, os pontos decimais (binários) devem ser alinhados. Para isso elas devem ser Unnormalized. Aqui é a adição resultante:
           .000000000000011010001101 * 2^0  <- Only 11 of 23 Bits retained
          +.111111010111000010100011 * 2^0
          ________________________________
           .111111010111011100110000 * 2^0
    
    						
    isso é chamado um erro de arredondamento porque alguns computadores arredondar ao deslocar para adição. Outras pessoas simplesmente truncar. Arredondar - desativar erros são importantes a serem consideradas sempre que você estiver adicionando ou multiplicar dois valores muito diferentes.
  2. Subtrair dois quase igual a valores
           .1235
          -.1234
           _____
           .0001
    
    						
    este ser normalizada. Observe que, embora os números originais cada tinham quatro dígitos significativos, o resultado tem apenas um dígito significativo.
  3. Estouro e estouro negativo

    Isso ocorre quando o resultado é muito grande ou muito pequeno para ser representado pelo tipo de dados.
  4. Erro quantizing

    Isso ocorre com esses números não podem ser representados no formulário exato pelo padrão do ponto flutuante.
  5. Divisão por um número muito pequeno

    Isso pode disparar um erro de "divisão por zero" ou pode produzir resultados incorretos, como no exemplo a seguir:
          A = 112000000
          B = 100000
          C = 0.0009
          X = A - B / C
    
    						
    QuickBasic In para MS-DOS, X agora tem o valor 888887, em vez da resposta correta, 900000.
  6. Erro de saída

    Esse tipo de erro ocorre quando as funções de saída alteram os valores que estiverem trabalhando com.

Propriedades

ID do artigo: 42980 - Última revisão: terça-feira, 16 de agosto de 2005 - Revisão: 3.1
A informação contida neste artigo aplica-se a:
  • Microsoft Visual Basic 2.0 Standard Edition
  • Microsoft Visual Basic 3.0 Professional Edition
  • Microsoft Visual Basic 4.0 Standard Edition
  • Microsoft Visual Basic 1.0 Standard Edition
  • Microsoft Visual Basic 2.0 Professional Edition
  • Microsoft Visual Basic 3.0 Professional Edition
  • Microsoft Visual Basic 4.0 Professional Edition
  • Microsoft Visual Basic for MS-DOS
  • Microsoft QuickBasic 4.0
  • Microsoft QuickBASIC 4.0b
  • Microsoft QuickBasic 4.5 for MS-DOS
  • Microsoft BASIC Compiler 6.0
  • Microsoft BASIC Compiler 6.0b
  • Microsoft BASIC Professional Development System 7.0
  • Microsoft Cinemania 97 Standard Edition
Palavras-chave: 
kbmt KB42980 KbMtpt
Tradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine Translation ou MT), não tendo sido portanto traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 42980
Aviso de Isenção de Responsabilidade sobre Conteúdo do KB Aposentado
Este artigo trata de produtos para os quais a Microsoft não mais oferece suporte. Por esta razão, este artigo é oferecido "como está" e não será mais atualizado.

Submeter comentários

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com