Hoje veremos o tipo decimal e como realizar cálculos de alta precisão usando C#. |
O tipo decimal é um tipo de dados de ponto
flutuante que possui mais precisão e um intervalo menor do que
o tipo float e double, sendo apropriado para cálculos financeiros e
monetários.
O valor padrão de um decimal é 0 e para experessar
valores usando um tipo decimal usamos o sufixo m ou M.
var valor = 12.456m;
var custo = 99.56M;
|
Os humanos estão acostumados a representar números não inteiros em uma forma decimal e esperam resultados exatos em representações decimais.
Alguns valores não podem ser representados exatamente usando tipos de dados double/float.
Por exemplo, armazenando o valor 0.1 na variável double/float (que são valores binários de ponto flutuante), obtemos apenas uma aproximação do valor. Da mesma forma, o valor de 1/3 não pode ser representado exatamente no tipo de decimal.
Os números de ponto flutuante
Os números de ponto flutuante representam números reais e medem quantidades contínuas, como peso, altura ou velocidade. No C# temos três tipos de ponto flutuante: float, double e decimal.
C# Alias | Tipo .NET | Tamanho | Precisão | Intervalo |
---|---|---|---|---|
float | System.Single | 4 bytes | 7 digitos | +-1.5 x 10-45 to +-3.4 x 1038 |
double | System.Double | 8 bytes | 15-16 digitos | +-5.0 x 10-324 to +-1.7 x 10308 |
decimal | System.Decimal | 16 bytes | 28-29 casas decimais | +-1.0 x 10-28 to +-7.9 x 1028 |
Como regra geral, decimal é usado para valores contados enquanto float/double para valores medidos.
Nenhum dos tipos é perfeito; geralmente, os tipos decimais são mais adequados para cálculos financeiros e monetários, enquanto os tipos double/float para cálculos científicos.
O tipo decimal é um tipo de dados de ponto flutuante de 128 bits e pode ter até 28-29 dígitos significativos. A seguir temos um trecho de código que compara a precisão entre os tipos float, double e decimal:
Resultado:
O valor 1/3 é um número irracional e pode ser representado apenas como uma
aproximação. A partir do exemplo, podemos ver que decimal tem mais casas
decimais após o ponto flutuante.
Os tipos decimais são muito mais lentos do que um tipo
double/float e permitem a codificação ou zeros à
direita.
Os tipos decimais são mais adequados para cálculos financeiros e monetários, enquanto os tipos double/float para cálculos científicos.
Vejamos um exemplo comparando a precisão para cálculos financeiros
Resultado:
No resultado acima vemos que o valor double possui um pequeno erro.
Este erro pode ser ignorado em muitos cálculos como uma medida de peso, ou altura de uma pessoa, isso seria irrelevante, no entanto em cálculos financeiros poderia causar problemas.
Ao contrário dos tipos double/float, tentar aumentar um valor decimal além de seu limite causa uma exception do tipo System.OverflowException.
Para mostrar isso vamos incrementar o valor de uma unidade de float e decimal ao valor máximo de cada tipo:
float
maxValue =
float.MaxValue; float nextValue = maxValue + 1f; Console.WriteLine(maxValue.ToString( "f"));Console.WriteLine(nextValue.ToString("f")); decimal maxValue2 = decimal.MaxValue;decimal nextValue2 = maxValue2 + 1m; Console.WriteLine(maxValue.ToString( "m"));Console.WriteLine(nextValue.ToString("m")); |
Executando teremos o resultado abaixo:
Observe que ao tentar exceder o valor máximo para decimal obtemos um System.OverflowException.
Métodos embutidos de decimal
O tipo decimal tem alguns métodos internos, como
Adicionar, Subtrair, Arredondar, etc. A seguir temos um exemplo do uso
destes métodos:
Resultado:
E estamos conversados....
"Ele (Jesus) deu a si mesmo por nós, a fim de nos remir de toda iniquidade e
purificar, para si mesmo, um povo exclusivamente seu, dedicado à prática de boas
obras."
Tito 2:14
Referências: