Pergunta

Depois de uma hora de tentar encontrar um bug no meu código eu finalmente encontrei a razão. Eu estava tentando adicionar uma pequena bóia para 1F, mas nada estava acontecendo. Enquanto tenta descobrir por que eu achei que acrescentando que pequena bóia para 0f funcionou perfeitamente.

Por que isso está acontecendo? Será que isso tem a ver com 'ordens de magnitude'? Existe alguma solução para este problema?

Agradecemos antecipadamente.

Editar:

Alterar a precisão dupla ou decimal não é uma opção no momento.

Foi útil?

Solução

Como a precisão para uma precisão única (32 bits) Valor de ponto flutuante é de cerca de 7 dígitos após o ponto decimal. O que significa que o valor que você está adicionando é essencialmente zero, pelo menos quando adicionado a 1. O valor em si, no entanto, pode facilmente armazenado em um flutuador desde o expoente é pequeno nesse caso. Mas, para adicioná-lo com sucesso para 1 você tem que usar o expoente do número maior ... e, em seguida, os dígitos após os zeros desaparecer no arredondamento.

Você pode usar double se precisar de mais precisão. Em termos de performance isso não deve fazer a diferença no hardware e memória de hoje é também muitas vezes não é tão restrita que você tem que pensar em cada única variável.

EDIT: Como você disse que o uso de double não é uma opção que você pode usar Kahan somatório , como akuhn apontou em um comentário.

Outra opção pode ser a de realizar cálculos intermediários em precisão dupla e posteriormente expressos para float novamente. Isso só vai ajudar, no entanto, quando há poucos mais operações do que apenas adicionando um número muito pequeno para um maior.

Outras dicas

Isso provavelmente acontece porque o número de dígitos de precisão em um flutuador é constante, mas o expoente, obviamente, pode variar.

Isto significa que embora você pode adicionar o seu número pequeno a 0, você não pode esperar para adicioná-lo para um número que tem uma diferente expoente de 0, uma vez que não só não será suficiente dígitos de precisão para a esquerda.

Você deve ler O que cada cientista computador deve saber sobre Floating-Point Arithmetic .

Parece que ele tem algo a ver com a precisão de ponto flutuante. Se eu fosse você, eu iria usar um tipo diferente, como decimal. Isso deve corrigir erros de precisão.

Com float, você só tem um precisão de cerca de sete dígitos . Portanto, o seu number'll ser arredondado para 1F. Se você deseja armazenar esse número, o uso double vez

http://msdn.microsoft.com/en-us/library /ayazw934.aspx

Além da resposta aceita: Se você precisa para resumir muitos pequeno número e alguns maiores, você deve usar Kahan Soma .

Se o desempenho for um problema (porque você não pode usar double), então binário dimensionamento / fixo ponto pode ser uma opção. floats são armazenados como números inteiros, mas escalado por um grande número (digamos, 2 ^ 16). aritmética intermediário é feito com (relativamente rápidos) operações de inteiros. A resposta final pode estar de volta convertido para ponto flutuante no final, dividindo pelo fator de escala.

Isso geralmente é feito se o processador alvo carece de um hardware unidade de ponto flutuante.

Você está usando o sufixo f em seus literais, o que tornará esses carros alegóricos em vez de camas. Portanto, o seu muito pequeno flutuador desaparecerão na maior float.

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