Pergunta

Eu sempre digo no c # uma variável do tipo double não é adequado para o dinheiro. Todas as coisas estranhas podem acontecer. Mas eu não consigo criar um exemplo para demonstrar algumas destas questões. Alguém pode fornecer um exemplo?

(edit; este post foi originalmente marcado C #; algumas respostas referem a detalhes específicos de decimal, o que significa, portanto, System.Decimal ).

(edit 2: Eu estava determinado a pedir algum código c #, então eu não acho que isso é agnóstico linguagem só)

Foi útil?

Solução

Muito, muito inadequado. Use decimal.

double x = 3.65, y = 0.05, z = 3.7;
Console.WriteLine((x + y) == z); // false

(exemplo de página de Jon aqui - ;-p leitura recomendada)

Outras dicas

Você vai obter erros estranhos efetivamente causados ??por arredondamento. Além disso, as comparações com os valores exatos são extremamente complicado - você geralmente precisa aplicar algum tipo de epsilon para verificar se o valor real que está sendo "quase" um particular

.

Aqui está um exemplo concreto:

using System;

class Test
{
    static void Main()
    {
        double x = 0.1;
        double y = x + x + x;
        Console.WriteLine(y == 0.3); // Prints False
    }
}

Sim, é inadequado.

Se bem me lembro dupla tem cerca de 17 números significativos, assim erros normalmente arredondamento terão lugar muito atrás do ponto decimal. A maioria dos softwares financeira usa 4 decimais atrás do ponto decimal, que deixa 13 decimais para trabalhar com isso o número máximo que você pode trabalhar com às operações individuais ainda é muito maior do que a dívida nacional dos EUA. Mas erros de arredondamento vai aumentar com o tempo. Se o seu software é executado por um longo tempo você vai finalmente começar a perder centavos. Determinadas operações vai piorar o seu estado. Por exemplo, adicionando grandes quantidades de pequenas quantidades irá causar uma perda significativa de precisão.

Você precisa de tipos de dados de ponto para as operações de pagamento fixo, a maioria das pessoas não se importa se você perder um centavo aqui e ali, mas os contabilistas não são como a maioria das pessoas ..

Editar
De acordo com este site http://msdn.microsoft.com/en-us/library /678hzkk9.aspx Duplas realmente tem de 15 a 16 dígitos significativos em vez de 17.

@ Jon Skeet decimal é mais adequado do que o dobro devido à sua maior precisão, 28 ou 29 decimais significativos. Isso significa menos chance de erros de arredondamento acumuladas se tornar significativo. tipos de dados de ponto fixo (inteiros ou seja, que representam centavos ou 100 de um centavo como eu vi usado) como Boojum menciona são realmente mais adequado.

Desde decimal usa um fator de escala de múltiplos de 10, números como 0,1 pode ser representado exatamente. Em essência, o tipo decimal representa como 1/10 ^ 1, enquanto que um double representaria isso como 104857/2 ^ 20 (na realidade, seria mais como realmente-big-número / 2 ^ 1023).

Um decimal pode representar exactamente qualquer valor de base 10 com até 28/29 algarismos significativos (como 0,1). A double não pode.

O meu entendimento é que a maioria dos sistemas financeiros expressar moeda usando números inteiros -. Ou seja, tudo contagem em centavos de dólar

IEEE precisão dupla realmente pode representam todos os inteiros exatamente no intervalo de -2 ^ 53 através + 2 ^ 53. (Delight, pg do Hacker. 262) Se você usa apenas adição, subtração e multiplicação, e manter tudo em inteiros dentro desta faixa, então você deve ver nenhuma perda de precisão. Eu seria muito cauteloso das operações de divisão ou mais complexas, no entanto.

Usando o dobro quando você não sabe o que está fazendo é inadequado.

"double" pode representar uma quantidade de um trilhão de dólares com um erro de 1/90 de um centavo. Então você vai obter resultados altamente precisos. Quer calcular quanto custa para colocar um homem em Marte e recuperá-lo vivo? dupla vai fazer muito bem.

Mas com o dinheiro muitas vezes há regras muito específicas que dizem que um certo cálculo deve dar um certo resultado e nenhum outro. Se você calcular um valor que é muito muito muito perto de $ 98,135, em seguida, haverá frequentemente uma regra que determina se o resultado deve ser de US $ 98,14 ou US $ 98,13 e você deve seguir essa regra e obter o resultado que é necessário .

Dependendo de onde você mora, usando 64 bit inteiros para representar centavos ou moedas ou kopeks ou o que é a menor unidade no seu país geralmente vai funcionar muito bem. Por exemplo, 64 bit inteiros assinados representam centavos podem representar valores de até 92,223 trilhões de dólares. 32 bit inteiros são geralmente inadequadas.

Sem uma dupla sempre terá erros de arredondamento, use "decimal" se você estiver em .Net ...

Na verdade ponto flutuante duplo é perfeitamente adequado para representar quantidades de dinheiro enquanto você escolher uma unidade adequada.

Consulte http://www.idinews.com/moneyRep.html

Assim, é ponto fixo longo . Ou consome 8 bytes, certamente preferível à 16 consumida por um decimal item.

obras ou não alguma coisa (ou seja, produz o resultado esperado e correto) não é uma questão de qualquer voto ou preferência individual. Uma técnica ou funciona ou não.

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