.Net
- Float(Single), Double e Decimal. Afinal qual devo usar ?
![]() |
Decidir qual o tipo de ponto flutuante usar vai depender da aplicação, mas aqui estão alguns considerações que podem ajudar a decidir: |
Os tipos de dados FLOAT, DOUBLE e DECIMAL são usados para armazenar números reais até uma certa precisão.
Qual a diferença entre esses tipos então ?
A tabela abaixo compara o intervalo, precisão, maior inteiro e tamanho:
Tipo | Intervalo | Precisão(Digitos) | Maior Inteiro Exato |
Tamanho |
Float | 1.5x10^-45 / 3.4x10^38 | 7 | 2^24 | 4 bytes |
Double | 5.0x10^-324 / 1.7x10^308 | 15-16 | 2^53 | 8 bytes |
Decimal | 1.0x10^-28 / 7.9x10^28 | 28-29 | 2^113 | 16 bytes |
Obs: Maior inteiro exato significa o maior valor inteiro que pode ser representado sem perda de precisão. Estes valores devem ser mantidos em mente quando você está convertendo entre tipos inteiros e ponto flutuante.
Para qualquer cálculo que envolva dinheiro ou finanças, o tipo Decimal deve ser sempre utilizado. Só este tipo tem a precisão adequada para evitar os erros críticos de arredondamento.
Por quê ?
O tipo de dados Decimal é simplesmente um tipo de ponto flutuante que é representado internamente como base 10 ao invés de base dois.
Obviamente, com base 10 (o nosso sistema de numeração real) qualquer número decimal pode ser construído para o valor exato ter que realizar aproximações.
O tipo Decimal é realmente uma estrutura que contém funções sobrecarregadas para todas as operações matemáticas e de comparação, ou seja, ele é realmente uma implementação da aritmética de base 10.
Considere o código abaixo feito na linguagem C# em uma aplicação Console: (Feita no Visual C# 2010 Express Editions)
using System;
namespace Macoratti
{
class Program
{
static void Main(string[] args)
{
int numero_iteracoes = 1;
Console.WriteLine("Primeiro laço, usando o tipo float :");
// executa somente 4 vezes e não 5 como esperado
for (float d = 1.1f; d <= 1.5f; d += 0.1f)
{
Console.WriteLine("Iteração #: {0}, valor float : {1}", numero_iteracoes++, d.ToString("e10"));
}
Console.WriteLine("\r\nSegundo laço, usando o tipo Decimal :");
// reseta o contador
numero_iteracoes = 1;
// executa corretamente para 5 interações
for (Decimal d = 1.1m; d <= 1.5m; d += 0.1m)
{
Console.WriteLine("Iteração #: {0}, valor Decimal : {1}", numero_iteracoes++, d.ToString("e10"));
}
Console.WriteLine("Pressione algo para continuar..");
Console.ReadKey();
}
}
}
|
![]() |
Note que o primeiro laço é executado 4 vezes e não 5 como se esperava.
É por isso que o segundo laço for() é executado 5 vezes como esperado e a variável "d" do tipo Decimal tem sempre o valor exato atribuída a ela.
Considerações para o VB .NET (Float -> Single)
Para o VB .NET o equivalente ao tipo de dados Float da linguagem C# é o tipo da dados Single.
O tipo de dados Single armazena números de ponto flutuante de precisão simples assinados com IEEE de 32 bits e variando do valor de - 3.4028235E + 38 até -1.401298E - 45 para valores negativos e de 1.401298E - 45 a 3.4028235E + 38 para valores positivos. Números de precisão simples armazenam uma aproximação de um número real.
Use o tipo de dado Single para armazenar valores inteiros que não necessitam de todos os bits de um Double. Em alguns casos a commom language runtime(CLR) pode ser suficiente para armazenar suas variáveis do tipo Single próximas uma da outra e diminuir o uso de memória.
A versão do exemplo para o VB .NET em uma aplicação do tipo Console Application é vista abaixo:
Imports System.Threading.Interlocked Imports System.Math Module Module1 Sub Main() Dim numero_iteracoes As Integer = 1 Console.WriteLine("Preimeiro laço, usando o tipo float :") ' executa somente 4 vezes e não 5 como esperado Dim d0 As Single = 1.1F While d0 <= 1.5F Console.WriteLine("Iteração #: {0}, valor float : {1}", Max(Increment(numero_iteracoes), numero_iteracoes - 1), d0.ToString("e10")) d0 += 0.1F End While Console.WriteLine(vbCr & vbLf & "Segundo laço, usando o tipo Decimal :") ' reseta o contador numero_iteracoes = 1 ' executa corretamente para 5 interações Dim d1 As Decimal = 1.1D While d1 <= 1.5D Console.WriteLine("Iteração #: {0}, valor Decimal : {1}", Max(Increment(numero_iteracoes), numero_iteracoes - 1), d1.ToString("e10")) d1 += 0.1D End While Console.WriteLine("Pressione algo para continuar..") Console.ReadKey() End Sub End Module |
![]() |
As considerações feitas valem tanto para o VB .NET como para o C#.
Ts 2:1 Porque vós mesmos sabeis, irmãos, que a nossa entrada entre vós não foi vã;
1Ts 2:2 mas, havendo anteriormente padecido e sido maltratados em Filipos, como sabeis, tivemos a confiança em nosso Deus para vos falar o evangelho de Deus em meio de grande combate.
1Ts 2:3 Porque a nossa exortação não procede de erro, nem de imundícia, nem é feita com dolo;
1Ts 2:4 mas, assim como fomos aprovados por Deus para que o evangelho nos fosse confiado, assim falamos, não para agradar aos homens, mas a Deus, que prova os nossos corações.
Referências: