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 comodouble
, ou comobool
em comparações relacionais e de igualdade. - Se não houver nenhum tipo
double
na expressão, ela será avaliada comofloat
, ou comobool
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
ouD
é do tipodouble
- O literal com os sufixos
f
ouF
é do tipofloat
- O literal com os sufixos
m
ouM
é do tipodecimal
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#: