decimal vs duplo! – Qual deles devo usar e quando?

Eu continuo vendo pessoas usando duplas em c #. Eu sei que li em algum lugar que o dobro às vezes perde a precisão. Minha pergunta é quando devo usar um duplo e quando devo usar um tipo decimal? Qual tipo é adequado para cálculos de dinheiro? (ou seja, mais de US $ 100 milhões)

Por dinheiro, sempre decimal. É por isso que foi criado.

Se os números devem sumr corretamente ou balancear, use decimal. Isso inclui qualquer armazenamento financeiro ou cálculos, pontuações ou outros números que as pessoas possam fazer à mão.

Se o valor exato dos números não for importante, use o dobro para a velocidade. Isso inclui computação gráfica, física ou outras ciências físicas, onde já existe um “número de dígitos significativos”.

Minha pergunta é quando devo usar um duplo e quando devo usar um tipo decimal?

decimal para quando você trabalha com valores no intervalo de 10 ^ (+/- 28) e onde você tem expectativas sobre o comportamento com base nas representações da base 10 – basicamente dinheiro.

double para quando você precisar de precisão relativa (ou seja, perder precisão nos dígitos finais em grandes valores não é um problema) em grandezas totalmente diferentes – cobre double mais que 10 ^ (+/- 300). Cálculos científicos são o melhor exemplo aqui.

qual tipo é adequado para cálculos de dinheiro?

decimal, decimal , decimal

Não aceite substitutos.

O fator mais importante é que o double , sendo implementado como uma fração binária, não pode representar com precisão muitas frações decimal (como 0.1) e seu número total de dígitos é menor, uma vez que é 64 bits versus 128 bits para decimal . Por fim, os aplicativos financeiros geralmente precisam seguir modos de arredondamento específicos (às vezes determinados por lei). decimal suporta estes ; double não.

System.Single / float – 7 dígitos
System.Double / double – 15-16 dígitos
System.Decimal / decimal – 28-29 dígitos significativos

A maneira como fui picado usando o tipo errado (alguns anos atrás) é com grandes quantidades:

  • £ 520.532,52 – 8 dígitos
  • £ 1.323.523,12 – 9 dígitos

Você acaba com 1 milhão por um float.

Um valor monetário de 15 dígitos:

  • £ 1,234,567,890,123.45

9 trilhões com um duplo. Mas com divisão e comparações é mais complicado (eu definitivamente não sou especialista em números flutuantes e irracionais – veja o ponto de Marc ). Misturar casas decimais e duplas causa problemas:

Uma operação matemática ou de comparação que usa um número de ponto flutuante pode não produzir o mesmo resultado se um número decimal for usado porque o número de ponto flutuante pode não se aproximar exatamente do número decimal.

Quando devo usar o dobro em vez do decimal? tem algumas respostas semelhantes e mais detalhadas.

Usar o double vez do decimal para aplicações monetárias é uma micro-otimização – essa é a maneira mais simples que eu vejo.

Decimal é para valores exatos. O dobro é para valores aproximados.

 USD: $12,345.67 USD (Decimal) CAD: $13,617.27 (Decimal) Exchange Rate: 1.102932 (Double) 

Por dinheiro: decimal . Custa um pouco mais de memory, mas não tem problemas de arredondamento como o double às vezes tem.

Definitivamente, use tipos inteiros para seus cálculos de dinheiro. Isso não pode ser enfatizado o suficiente, já que à primeira vista pode parecer que um tipo de ponto flutuante é adequado.

Aqui um exemplo em código python:

 >>> amount = float(100.00) # one hundred dollars >>> print amount 100.0 >>> new_amount = amount + 1 >>> print new_amount 101.0 >>> print new_amount - amount >>> 1.0 

parece bem normal.

Agora tente novamente com 10 ^ 20 dólares do Zimbábue

 >>> amount = float(1e20) >>> print amount 1e+20 >>> new_amount = amount + 1 >>> print new_amount 1e+20 >>> print new_amount-amount 0.0 

Como você pode ver, o dólar desapareceu.

Se você usar o tipo inteiro, ele funciona bem:

 >>> amount = int(1e20) >>> print amount 100000000000000000000 >>> new_amount = amount + 1 >>> print new_amount 100000000000000000001 >>> print new_amount - amount 1 

Eu acho que a principal diferença ao lado da largura do bit é que o decimal tem o expoente base 10 e o dobro tem o expoente

http://software-product-development.blogspot.com/2008/07/net-double-vs-decimal.html