Por que Visual Studio 2008 me dizer ,9-,8999999999999995 = 0.00000000000000055511151231257827?

StackOverflow https://stackoverflow.com/questions/1662600

Pergunta

Quando eu digito isso na janela imediata Visual Studio 2008:

? .9 - .8999999999999995

Ele me isto dá como resposta:

0.00000000000000055511151231257827

A documentação diz que um casal tem 15-16 dígitos de precisão, mas ele está me dando um resultado com 32 dígitos de precisão. Onde tudo é que a precisão adicional vem?

Foi útil?

Solução

são apenas 15-16 dígitos na resposta. Todos esses zeros à esquerda não contam. O número é realmente mais como 5,5511151231257827 × 10 -16 . A porção mantissa tem 15-16 dígitos na mesma. O expoente (-16) serve para deslocar o ponto decimal mais de 16 lugares, mas não altera o número de dígitos do número global.

Editar

Depois de obter alguns comentários, eu sou curioso agora sobre o que está realmente acontecendo. Liguei o número em questão neste IEEE-754 Converter . Ele tomou a liberdade de arredondamento o último "27" para "30", mas eu não acho que muda os resultados.

As quebras conversor para baixo o número em suas três partes binárias:

Sinal: 0 (positivo)
Expoente: -51
Significand: 1.0100000000000000000000000000000000000000000000000000 (binário para 1,25 10 )

Portanto, este número é 1,01 2 × 2 -51 , ou 1,25 10 × 2 -51 . Uma vez que existem apenas três dígitos binários significativos sendo armazenado, que sugeriria que Lars pode estar em qualquer coisa. Eles não podem ser "ruído aleatório", já que eles são os mesmos cada vez que o número é convertido.

Os dados sugerem que o dígito única armazenado é "5". Os zeros à esquerda vêm do expoente eo resto dos dígitos aparentemente aleatórios são de computação 2 -51 .

Outras dicas

Você deve ler: O que cada Computer Scientist Should Saber Sobre Floating-Point Arithmetic .

Basicamente se trata de números de ponto flutuante a ser armazenado com precisão finita. Você tem que fazer a sua comparação com alguma delta.

if(.9 - .8999999999999995 <= 0.0001)
  //close enough to be equal

Os zeros à esquerda não são significativos / parte da precisão (tanto quanto o número de ponto flutuante está em causa - matematicamente falando, eles são significativo). Os zeros são devidos à parte expoente de representação interna do número de ponto flutuante.

A porção 55511151231257827 (que é o significando ou mantissa ) tem 17 dígitos decimais, que está suficientemente próximo de 15-16 dígitos.

@Lars D: O que você considera ser correta, só é correta dentro do contexto de questão. .9 - .8999999999999995 trabalha fora de um carro alegórico com significand 0,625 e expoente de -50. Tomando 0,625 * 2 -50 resulta em 5.5511151231257827e-16. Agora, fora do contexto da pergunta original, temos um número com 17 dígitos significativos que não acontecer a ser a nossa melhor aproximação binária de ,0000000000000005. No entanto, esses zeros ainda não são significativas no que respeita à representação do número de ponto flutuante está em causa.

? ,9-,8999999999999995

Este processo de subtração, com 15-16 dígitos significativos, dá

,0000000000000005

O resto dos dígitos são apenas erros de arredondamento. No entanto, desde que o computador sempre armazena 15-16 dígitos significativos após o primeiro dígito não-zero, os erros de arredondamento são mostrados, e você terá um monte de fuga dígitos aleatórios produzidos por erros de arredondamento. Assim, o resultado tem 16 dígitos significativos da operação de subtração além de 16 dígitos a partir do armazenamento do resultado, o que dá 32 dígitos.

A parte "flutuante" de meios "ponto flutuante" que você está recebendo algo mais próximo de 5,5511151231257827 * 10 ^ (- 16). Isso não é exatamente como ele é representado, porque, naturalmente, tudo é feito em binário sob o capô, mas o ponto é, o número é representado pelos dígitos significativos, além de um número que representa o quão longe para mover a raíz (ponto decimal). Como sempre, a Wikipedia pode lhe dar mais detalhes:

(O segundo link é mais especificamente focado no seu caso particular.)

Eu acho que é porque, no sistema binário, 5 é periódica, pois não é divisível por 2. E então o que Mark Rushakoff disse se aplica.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top