Diferença entre decimal, float e double em .NET?
-
03-07-2019 - |
Pergunta
O que é a diferença entre decimal
, float
e double
em .NET?
Quando você usaria um desses?
Solução
float
e double
são flutuante binário tipos de ponto . Em outras palavras, eles representam um número como este:
10001.10010110011
O número binário ea localização do ponto binário são ambas codificadas dentro do valor.
decimal
é um flutuante decimal tipo de ponto . Em outras palavras, eles representam um número como este:
12345.65789
Mais uma vez, o número ea localização do decimal ponto são ambas codificadas dentro do valor -. É isso que faz decimal
ainda um tipo de ponto flutuante em vez de um tipo de ponto fixo
O importante a notar é que os seres humanos são usados ??para representar não-inteiros de forma decimal, e esperar resultados exatos em representações decimais; nem todos os números decimais são exatamente representável em ponto flutuante binário - 0,1, por exemplo - por isso, se você usar um binário valor de ponto flutuante você vai realmente obter uma aproximação a 0,1. Você ainda vai ter aproximações ao usar um ponto decimal flutuante, bem como -. O resultado da divisão 1 por 3 não pode ser exatamente representada, por exemplo
Como para o que usar quando:
-
Para valores que são "naturalmente exata decimais" É bom uso
decimal
. Isso geralmente é adequado para qualquer conceitos inventados pelo homem: os valores financeiros são o exemplo mais óbvio, mas há outros também. Considere a pontuação dada aos mergulhadores ou patinadores no gelo, por exemplo. -
Para valores que são mais artefactos da natureza que não pode realmente ser medidos exatamente de qualquer maneira,
float
/double
são mais apropriadas. Por exemplo, dados científicos geralmente seriam representados nesta forma. Aqui, os valores originais não será "decimalmente precisas" para começar, por isso não é importante para os resultados esperados para manter a "precisão decimal". Flutuante tipos de ponto binários são muito mais rápidos do que trabalhar com números decimais.
Outras dicas
A precisão é a principal diferença.
Float - 7 dígitos (32 bits)
Duplo -15-16 dígitos (64 bits)
decimal -28-29 algarismos significativos (de 128 bits )
Decimals têm muito maior precisão e são normalmente utilizados em aplicações financeiras que exigem um alto grau de precisão. Decimais são muito mais lentos (até 20x vezes em alguns testes) do que um / float dupla.
Decimals e flutua / Duplas não pode ser comparado, sem um elenco enquanto flutua e Duplas pode. Decimais também permitir a codificação ou zeros à direita.
float flt = 1F/3;
double dbl = 1D/3;
decimal dcm = 1M/3;
Console.WriteLine("float: {0} double: {1} decimal: {2}", flt, dbl, dcm);
Resultado:
float: 0.3333333
double: 0.333333333333333
decimal: 0.3333333333333333333333333333
O Decimal é estritamente voltado para cálculos financeiros que exigem precisão, que são relativamente intolerantes com arredondamento. Decimais não são adequados para aplicações científicas, no entanto, por várias razões:
- Uma certa perda de precisão é aceitável em muitos cálculos científicos por causa dos limites práticos do problema físico ou artefato que está sendo medido. Perda de precisão não é aceitável em finanças.
- Decimal é muito (muito) mais lento do que float e double para a maioria das operações, principalmente por causa de operações de ponto flutuante são feitas em binário, enquanto Decimal material é feito na base 10 (ou seja, carros alegóricos e duplas são tratados pelo hardware FPU, como MMX / SSE, enquanto decimais são calculados no software).
- Decimal tem uma faixa de valor inaceitavelmente menor do que o dobro, apesar do fato de que ele suporta mais dígitos de precisão. Portanto, Decimal não pode ser usado para representar muitos valores científicos.
+---------+----------------+---------+----------+---------------------------------------------+
| C# | .Net Framework | Signed? | Bytes | Possible Values |
| Type | (System) type | | Occupied | |
+---------+----------------+---------+----------+---------------------------------------------+
| sbyte | System.Sbyte | Yes | 1 | -128 to 127 |
| short | System.Int16 | Yes | 2 | -32768 to 32767 |
| int | System.Int32 | Yes | 4 | -2147483648 to 2147483647 |
| long | System.Int64 | Yes | 8 | -9223372036854775808 to 9223372036854775807 |
| byte | System.Byte | No | 1 | 0 to 255 |
| ushort | System.Uint16 | No | 2 | 0 to 65535 |
| uint | System.UInt32 | No | 4 | 0 to 4294967295 |
| ulong | System.Uint64 | No | 8 | 0 to 18446744073709551615 |
| float | System.Single | Yes | 4 | Approximately ±1.5 x 10-45 to ±3.4 x 1038 |
| | | | | with 7 significant figures |
| double | System.Double | Yes | 8 | Approximately ±5.0 x 10-324 to ±1.7 x 10308 |
| | | | | with 15 or 16 significant figures |
| decimal | System.Decimal | Yes | 12 | Approximately ±1.0 x 10-28 to ±7.9 x 1028 |
| | | | | with 28 or 29 significant figures |
| char | System.Char | N/A | 2 | Any Unicode character (16 bit) |
| bool | System.Boolean | N/A | 1 / 2 | true or false |
+---------+----------------+---------+----------+---------------------------------------------+
Para obter mais informações, consulte:
http: //social.msdn .microsoft.com / Fórum / pt-bR / csharpgeneral / thread / 921a8ffc-9829-4145-bdc9-a96c1ec174a5
float
7 dígitos de precisão
double
tem cerca de 15 dígitos de precisão
decimal
tem cerca de 28 dígitos de precisão
Se você precisar de uma melhor precisão, utilize casal em vez de float. Em processadores modernos ambos os tipos de dados têm quase o mesmo desempenho. O único benifit de usar float é que eles ocupam menos espaço. Praticamente só importa se você tem muitos deles.
Eu achei isso é interessante. O que cada cientista computador deve saber sobre Floating-Point Arithmetic
Eu não vou reiterar toneladas de bom (e algumas más) informações já respondeu em outras respostas e comentários, mas vou responder a sua pergunta de acompanhamento com uma ponta:
Em que alguém usar uma dessas?
Use decimal para contados valores
Use float / duplo para medido valores
Alguns exemplos:
-
dinheiro (nós contar dinheiro ou dinheiro medida?)
-
distância (fazer contamos distância ou medida de distância? *)
-
pontuação (fazer contamos pontuações ou pontuações medida?)
Nós sempre contar dinheiro e nunca deve medi-la. Costumamos medir a distância. Nós muitas vezes contar pontuações.
* Em alguns casos, o que eu chamaria distância nominal , podemos de fato quer 'count' distância. Por exemplo, talvez estamos a lidar com sinais de país que mostram distâncias para cidades, e sabemos que essas distâncias nunca tem mais de um dígito decimal (xxx.x km).
Ninguém mencionou que
Em configurações padrão, carros alegóricos (System.Single) e duplas (System.Double) nunca uso verificação de estouro enquanto Decimal (System.Decimal) usará sempre verificação de estouro.
I média
decimal myNumber = decimal.MaxValue;
myNumber += 1;
joga OverflowException .
Mas estes não fazer:
float myNumber = float.MaxValue;
myNumber += 1;
&
double myNumber = double.MaxValue;
myNumber += 1;
Inteiros, como foi mencionado, são números inteiros. Eles não podem armazenar o ponto de algo, como 0,7, 0,42 e 0,007. Se você precisar armazenar números que não são números inteiros, você precisa de um tipo diferente de variável. Você pode usar o tipo de casal ou do tipo float. Você definir esses tipos de variáveis-se exatamente da mesma maneira: em vez de usar a palavra int
, você digita double
ou float
. Como esta:
float myFloat;
double myDouble;
(float
é a abreviação de "ponto flutuante", e significa apenas um número com um ponto alguma coisa no final.)
A diferença entre os dois está no tamanho dos números que eles podem segurar. Para float
, você pode ter até 7 dígitos do seu número. Para double
s, você pode ter até 16 dígitos. Para ser mais preciso, aqui é o tamanho oficial:
float: 1.5 × 10^-45 to 3.4 × 10^38
double: 5.0 × 10^-324 to 1.7 × 10^308
float
é um número de 32 bits, e double
é um número de 64 bits.
Dê um duplo clique no novo botão para obter o código. Adicione os seguintes três linhas para o código do botão:
double myDouble;
myDouble = 0.007;
MessageBox.Show(myDouble.ToString());
Halt seu programa e retornar à janela de codificação. Altere esta linha:
myDouble = 0.007;
myDouble = 12345678.1234567;
Execute o programa e clique no botão de casal. A caixa de mensagem exibe corretamente o número. Adicionar um outro número no final, porém, e C # se será novamente rodada ou para baixo. A moral é se você quiser precisão, ter o cuidado de arredondamento!
- Double e flutuador pode ser dividido por inteiro zero, sem uma exceção, tanto compilação e tempo de execução.
- Decimal não pode ser dividido por inteiro zero. Compilação sempre falhará se você fizer isso.
Este tem sido um tópico interessante para mim, como hoje, só tivemos um pequeno bug desagradável, sobre decimal
ter menos precisão do que um float
.
Em nosso código C #, estamos lendo valores numéricos de uma planilha do Excel, convertendo-os em um decimal
, em seguida, enviar essa decimal
volta a um serviço para salvar em um SQL Server banco de dados.
Microsoft.Office.Interop.Excel.Range cell = …
object cellValue = cell.Value2;
if (cellValue != null)
{
decimal value = 0;
Decimal.TryParse(cellValue.ToString(), out value);
}
Agora, para quase todos dos nossos valores do Excel, isso funcionou muito bem. Mas para alguns, valores muito pequenos Excel, usando decimal.TryParse
perdeu o valor completamente. Um exemplo é
-
CellValue = 0,00006317592
-
Decimal.TryParse (cellValue.ToString (), o valor); // voltaria 0
A solução, curiosamente, era converter os valores do Excel em um double
primeiro, e depois em um decimal
:
Microsoft.Office.Interop.Excel.Range cell = …
object cellValue = cell.Value2;
if (cellValue != null)
{
double valueDouble = 0;
double.TryParse(cellValue.ToString(), out valueDouble);
decimal value = (decimal) valueDouble;
…
}
Mesmo que double
tem menos precisão do que um decimal
, este pequeno número realmente assegurada continuaria a ser reconhecido. Por alguma razão, double.TryParse
foi realmente capaz de recuperar esses números pequenos, enquanto que decimal.TryParse
seria configurá-los para zero.
Odd. Muito estranho.
- flutuador: ± 1,5 x 10 ^ -45 a ± 3,4 x 10 ^ 38 (~ 7 algarismos significativos
- duplo: ± 5,0 x 10 ^ -324 a ± 1,7 x 10 ^ 308 (15-16 algarismos significativos)
- decimal: ± 1,0 x 10 ^ -28 a ± 7,9 x 10 ^ 28 (28-29 algarismos significativos)
Para aplicações como jogos e sistemas embarcados, onde memória e desempenho são críticos, flutuador é geralmente o tipo numérico de escolha, pois é mais rápido e metade do tamanho de um duplo. Inteiros costumava ser a arma de escolha, mas o desempenho de ponto flutuante ultrapassou inteiro em processadores modernos. Decimal está fora certo!
O Decimal, dobro, e tipos de variáveis ??Float são diferentes na maneira que eles armazenam os valores. A precisão é a principal diferença em que a flutuação é uma única precisão (32 bits) de dados ponto flutuante tipo, duplo é uma precisão dupla (64 bits) de dados ponto flutuante tipo e decimal é uma flutuante tipo de dados de ponto de 128 bits.
Float - 32 bit (7 dígitos)
Duplo - 64 bits (15-16 dígitos)
Decimal - 128 bits (28-29 dígitos significativos)
Mais sobre ... a diferença entre decimal, Float e Double
O problema com todos esses tipos é que uma certa imprecisão subsiste E que este problema pode ocorrer com números decimais pequenas como no exemplo a seguir
Dim fMean as Double = 1.18
Dim fDelta as Double = 0.08
Dim fLimit as Double = 1.1
If fMean - fDelta < fLimit Then
bLower = True
Else
bLower = False
End If
Pergunta: qual o valor que Blower variável conter
Resposta: Em uma máquina de 32 bits Blower contém VERDADEIRO !!!
Se eu substituir o dobro por Decimal, ventilador contém FALSE que é a boa resposta.
Em dupla, o problema é que fMean-fDelta = 1,09999999999 que é menor que 1.1.
Cuidado: Eu acho que mesmo problema pode certamente existe para outro número porque Decimal é apenas uma de casal com maior precisão e a precisão tem sempre um limite
.Na verdade, Double, Float e Decimal correspondem a BINÁRIO decimal em COBOL!
É lamentável que outros tipos numéricos implementados em COBOL não existem em .Net. Para aqueles que não sabem COBOL, existem em COBOL seguinte tipo numérico
BINARY or COMP like float or double or decimal
PACKED-DECIMAL or COMP-3 (2 digit in 1 byte)
ZONED-DECIMAL (1 digit in 1 byte)
Em palavras simples:
- O Decimal, duplos, e variáveis ??Float tipos são diferentes na maneira que eles armazenam os valores.
- A precisão é a principal diferença (Note que esta não é a única diferença), onde flutuador é um único precisão (32 bit) flutuante tipo de dados ponto,
duplo é uma precisão dupla (64 bits) tipo de flutuação e de dados de pontodecimal é um tipo de dados de ponto flutuante de 128 bits. - A tabela resumo:
/==========================================================================================
Type Bits Have up to Approximate Range
/==========================================================================================
float 32 7 digits -3.4 × 10 ^ (38) to +3.4 × 10 ^ (38)
double 64 15-16 digits ±5.0 × 10 ^ (-324) to ±1.7 × 10 ^ (308)
decimal 128 28-29 significant digits ±7.9 x 10 ^ (28) or (1 to 10 ^ (28)
/==========================================================================================
Você pode ler mais aqui , Float , duplo , e decimal .
A principal diferença entre cada uma delas é a precisão.
float
é um número 32-bit
, double
é um número 64-bit
e decimal
é um número 128-bit
.