Tipos numéricos de ponto flutuante (Referência de C#)

Os tipos numéricos de ponto flutuante representam números reais. Todos os tipos numéricos de ponto flutuante são tipos de valor. Eles também são tipos simples e podem ser inicializados com literais. Todos os tipos numéricos de ponto flutuante dão suporte a operadores aritméticos, de comparação e de igualdade.

Características dos tipos de ponto flutuante

O C# é compatível com os seguintes tipos de pontos flutuantes predefinidos:

palavra-chave/tipo C# Intervalo aproximado Precisão Tamanho Tipo .NET
float ±1,5 x 10−45 para ±3,4 x 1038 ~6 a 9 dígitos 4 bytes System.Single
double ±5.0 × 10−324 to ±1.7 × 10308 ~15 a 17 dígitos 8 bytes System.Double
decimal ±1,0 x 10-28 para ±7,9228 x 1028 28 a 29 dígitos 16 bytes System.Decimal

Na tabela anterior, cada palavra-chave do tipo C# da coluna mais à esquerda é um alias do tipo .NET correspondente. Eles são intercambiáveis. Por exemplo, as declarações a seguir declaram variáveis do mesmo tipo:

double a = 12.3;
System.Double b = 12.3;

O valor padrão de cada tipo de ponto flutuante é zero, 0. Cada um dos tipos de ponto flutuante possui as constantes MinValue e MaxValue que fornecem o valor mínimo e máximo desse tipo. Os tipos float e double também fornecem constantes que representam valores não numéricos e infinitos. Por exemplo, o tipo double fornece as seguintes constantes: Double.NaN, Double.NegativeInfinity e Double.PositiveInfinity.

O tipo decimal é apropriado quando o grau de precisão necessário é determinado pelo número de dígitos à direita do ponto decimal. Esses números são comumente usados em aplicativos financeiros, para valores de moeda (por exemplo, US$ 1,00), taxas de juros (por exemplo, 2,625%) e assim por diante. Mesmo os números com apenas uma casa decimal são tratados com mais precisão pelo tipo decimal: 0,1, por exemplo, pode ser representado com exatidão por meio de uma instância decimal, ao passo que não há instância double ou float que representem 0,1 com exatidão. Devido a essa diferença em tipos numéricos, erros de arredondamento inesperados podem ocorrer em cálculos aritméticos quando você usa double ou float para dados decimais. Você pode usar double em vez de decimal quando otimizar o desempenho for mais importante do que garantir a precisão. No entanto, qualquer diferença no desempenho passaria despercebida por todos, exceto pelos aplicativos com maior uso de cálculo. Outro motivo possível a ser evitado decimal é minimizar os requisitos de armazenamento. Por exemplo, ML.NET usa float porque a diferença entre 4 bytes e 16 bytes se soma para cada conjuntos de dados muito grandes. Para obter mais informações, consulte System.Decimal.

Você pode misturar tipos integrais e os tipos float e double em uma expressão. Nesse caso, os tipos integrais são convertidos implicitamente em um dos tipos de ponto flutuante e, se necessário, o tipo float é convertido implicitamente em double. A expressão é avaliada como segue:

  • Se houver os tipo double na expressão, ela será avaliada como double, ou como bool em comparações relacionais e de igualdade.
  • Se não houver nenhum tipo double na expressão, ela será avaliada como float, ou como bool em comparações relacionais e de igualdade.

Você também pode misturar tipos integrais e o tipo decimal em uma expressão. Nesse caso, os tipos integrais são convertidos implicitamente no tipo decimal e a expressão é avaliada como decimal, ou como bool em comparações relacionais e de igualdade.

Não é possível misturar o tipo decimal com os tipos float e double em uma expressão. Nesse caso, se você quiser executar operações aritméticas, de comparação ou de igualdade, deverá converter explicitamente os operandos de/para o tipo decimal, como mostra o seguinte exemplo:

double a = 1.0;
decimal b = 2.1m;
Console.WriteLine(a + (double)b);
Console.WriteLine((decimal)a + b);

É possível usar cadeias de caracteres de formato numérico padrão ou cadeias de caracteres de formato numérico personalizado para formatar um valor de ponto flutuante.

Literais reais

O tipo de literal real é determinado pelo sufixo da seguinte maneira:

  • O literal sem sufixo ou com os sufixos d ou D é do tipo double
  • O literal com os sufixos f ou F é do tipo float
  • O literal com os sufixos m ou M é do tipo decimal

O seguinte código demonstra um exemplo de cada um:

double d = 3D;
d = 4d;
d = 3.934_001;

float f = 3_000.5F;
f = 5.4f;

decimal myMoney = 3_000.5m;
myMoney = 400.75M;

O exemplo anterior também mostra o uso de _ como separador de dígitos. Você pode usar o separador de dígitos com todos os tipos de literais numéricos.

Você também pode usar notação científica, ou seja, especificar uma parte expoente de um literal real, como mostra o seguinte exemplo:

double d = 0.42e2;
Console.WriteLine(d);  // output 42

float f = 134.45E-2f;
Console.WriteLine(f);  // output: 1.3445

decimal m = 1.5E6m;
Console.WriteLine(m);  // output: 1500000

Conversões

Há apenas uma conversão implícita entre tipos numéricos de ponto flutuante: de float para double. No entanto, você pode converter qualquer tipo de ponto flutuante em qualquer outro tipo de ponto flutuante com a conversão explícita. Para obter mais informações, confira Conversões numéricas internas.

Especificação da linguagem C#

Para obter mais informações, confira as seguintes seções da especificação da linguagem C#:

Confira também