Quando você usa float e quando usa double


194

Freqüentemente, na minha experiência em programação, preciso tomar uma decisão se devo usar float ou double para meus números reais. Às vezes eu vou flutuar, às vezes eu vou dobrar, mas isso realmente parece mais subjetivo. Se eu fosse confrontado para defender minha decisão, provavelmente não daria razões sólidas.

Quando você usa float e quando usa double? Você sempre usa o dobro, somente quando há restrições de memória que você usa para flutuar? Ou você sempre usa float, a menos que o requisito de precisão exija o uso duplo? Existem diferenças substanciais em relação à complexidade computacional da aritmética básica entre float e double? Quais são os prós e os contras do uso de float ou double? E você já usou long double?


28
Em muitos casos, você não deseja usar nenhum, mas sim um tipo de ponto flutuante ou ponto fixo decimal. Os tipos binários de ponto flutuante não podem representar exatamente a maioria dos decimais.
CodesInChaos

3
Relacionado a O que causa erros de arredondamento de ponto flutuante? . @CodesInChaos minha resposta lá sugere recursos para ajudá-lo a fazer essa determinação, não há uma solução única para todos .
Mark Booth

Resposta muito boa encontrada em: Stack Overflow
Haris

5
O que exatamente você quer dizer com "decimais". Se você precisa representar valores exatamente como 0,01 (digamos, por dinheiro), o ponto flutuante (binário) não é a resposta. Se você apenas significa números não inteiros, o ponto flutuante provavelmente está correto - mas "decimais" não são a melhor palavra para descrever o que você precisa.
30513 Keith Thompson

11
Você nem sempre tem escolha. Por exemplo, na plataforma Arduino, double e float equivalem a float. Você precisa encontrar uma biblioteca de suplementos para lidar com duplas reais.
Kiwiron

Respostas:


187

A opção padrão para um tipo de ponto flutuante deve ser double. Este é também o tipo que obtém com literais de ponto flutuante sem um sufixo ou (em C) funções padrão que operam em números de ponto flutuante (por exemplo exp, sin, etc.).

float só deve ser usado se você precisar operar com muitos números de ponto flutuante (pense na ordem de milhares ou mais) e a análise do algoritmo mostrou que o alcance e a precisão reduzidos não representam um problema.

long doublepode ser usado se você precisar de mais alcance ou precisão do que doublee se isso for fornecido na sua plataforma de destino.

Em resumo, floate long doubledeve ser reservado para uso dos especialistas, com doubleuso "diário".


10
Eu provavelmente não consideraria float por alguns milhares de valores, a menos que houvesse um problema de desempenho relacionado ao cache de ponto flutuante e à transferência de dados. Geralmente, há um custo substancial em fazer a análise para mostrar que a flutuação é precisa o suficiente.
Patricia Shanahan

4
Como adendo, se você precisar de compatibilidade com outros sistemas, pode ser vantajoso usar os mesmos tipos de dados.
ZzzzBov 28/02

15
Eu usaria carros alegóricos para milhões de números, não para milhares. Além disso, algumas GPUs se saem melhor com flutuadores, nesse caso especializado usam flutuadores. Senão, como você diz, use duplas.
user949300

4
@PatriciaShanahan - 'problema de desempenho relacionado a ...' Um bom exemplo é se você planeja usar o SSE2 ou instruções vetoriais semelhantes, pode fazer 4 operações / vetor no float (vs 2 por dobro), o que pode melhorar significativamente a velocidade ( metade do número de operações e metade do volume de dados para leitura e gravação). Isso pode reduzir significativamente o limite em que o uso de carros alegóricos se torna atraente e vale a pena resolver os problemas numéricos.
greggo 9/09/14

12
Aprovo esta resposta com um conselho adicional: quando alguém está operando com valores RGB para exibição, é aceitável usar float(e ocasionalmente meia precisão) porque nem o olho humano, a exibição ou o sistema de cores tem tantos bits de precisão . Este conselho é aplicável, por exemplo, OpenGL etc. Este conselho adicional não se aplica a imagens médicas, que possuem requisitos de precisão mais estritos.
rwong 17/11

42

Raramente há motivos para usar float em vez de duplicar no código destinado aos computadores modernos. A precisão extra reduz (mas não elimina) a chance de erros de arredondamento ou outra imprecisão causando problemas.

Os principais motivos pelos quais posso pensar em usar o float são:

  1. Você está armazenando grandes matrizes de números e precisa reduzir o consumo de memória do seu programa.
  2. Você está direcionando um sistema que não suporta nativamente o ponto flutuante de precisão dupla. Até recentemente, muitas placas gráficas suportavam apenas pontos flutuantes de precisão única. Tenho certeza de que há muitos processadores embarcados e de baixo consumo de energia que também têm suporte limitado a ponto flutuante.
  3. Você está alvejando hardware em que a precisão única é mais rápida que a precisão dupla e seu aplicativo faz uso pesado da aritmética de ponto flutuante. Nas modernas CPUs Intel, acredito que todos os cálculos de ponto flutuante são feitos em dupla precisão, para que você não ganhe nada aqui.
  4. Você está fazendo otimização de baixo nível, por exemplo, usando instruções especiais da CPU que operam em vários números por vez.

Portanto, basicamente, o dobro é o caminho a menos, a menos que você tenha limitações de hardware ou que a análise mostre que o armazenamento de números de precisão dupla está contribuindo significativamente para o uso da memória.


2
"Computadores modernos" significa processadores Intel x86. Algumas das máquinas usadas pelos Antigos forneciam precisão perfeitamente adequada com o tipo de flutuador básico. (O CDC 6600 usou uma palavra de 60 bits, 48 bits de mantissa normalizado de ponto flutuante, 12 bits de expoente que é quase o que o x86 dá para precisão dupla..)
John R. Strohm

@ John.R.Strohm: concordou, mas os compiladores C não existiam no CDC6600. Foi Fortran IV ...
Basile Starynkevitch

Por "computadores modernos", quero dizer qualquer processador construído na última década ou duas, ou realmente, desde que o padrão de ponto flutuante IEEE foi amplamente implementado. Estou perfeitamente ciente de que arquiteturas não x86 existem e tive isso em mente com a minha resposta - mencionei GPUs e processadores embarcados, que normalmente não são x86.
precisa saber é o seguinte

Isso simplesmente não é verdade, no entanto. O SSE2 pode manipular 4 flutuadores ou 2 duplos em uma operação, o AVX pode manipular 8 flutuadores ou 4 duplos, o AVX-512 pode manipular 16 flutuadores ou 8 duplos. Para qualquer tipo de computação de alto desempenho, a matemática nos carros alegóricos deve ser considerada duas vezes a velocidade das mesmas operações nas dobras no x86.
Larry Gritz

11
E é ainda pior do que isso, já que você pode colocar o dobro de flutuadores no cache do processador com o dobro, e a latência da memória provavelmente será o principal gargalo em muitos programas. Manter um conjunto inteiro de flutuadores aquecidos no cache pode ser literalmente uma ordem de magnitude mais rápida do que usar o dobro e fazer com que eles se espalhem para a RAM.
Larry Gritz

10

Use doublepara todos os seus cálculos e variáveis ​​temporárias. Use floatquando precisar manter uma matriz de números - float[](se a precisão for suficiente) e estiver lidando com dezenas de milhares de floatnúmeros.

Muitas / a maioria das funções ou operadores matemáticos convertem / retornam doublee você não deseja converter os números de volta floatpara nenhuma etapa intermediária.

Por exemplo, se você tiver uma entrada de 100.000 números de um arquivo ou fluxo e precisar classificá-los, coloque os números em a float[].


5

Algumas plataformas (ARM Cortex-M2, Cortex-M4 etc.) não suportam o dobro (sempre pode ser verificado no manual de referência do seu processador. Se não houver avisos ou erros de compilação, isso não significa que o código seja ideal. double pode ser emulado.). É por isso que você pode precisar manter int ou flutuar .

Se não for esse o caso, eu usaria o dobro .

Você pode conferir o famoso artigo de D. Goldberg ("O que todo cientista da computação deve saber sobre aritmética de ponto flutuante"). Você deve pensar duas vezes antes de usar a aritmética de ponto flutuante. Há uma grande chance de que eles não sejam necessários em sua situação específica.

http://perso.ens-lyon.fr/jean-michel.muller/goldberg.pdf


3
Esta pergunta já foi bastante bem respondida há um ano ... mas, de qualquer forma, eu diria que sempre que você estiver usando o dobro em plataformas com aceleração de FPU de precisão dupla, você deve usá-lo em qualquer outro, mesmo que isso signifique permitindo que o compilador o emule em vez de tirar vantagem de uma FPU apenas com ponto flutuante (observe que as FPU também não são necessárias em todas as plataformas, na verdade, uma arquitetura Cortex-M4 as define como um recurso opcional [M2 foi um erro de digitação?] )
Selali Adobor 22/09

A chave para essa lógica é que, embora seja verdade que uma pessoa deve estar cansada da aritmética de ponto flutuante e de muitas "peculiaridades", definitivamente não está presenciando o suporte da FPU para que as duplas signifiquem simplesmente usar duplas em vez de flutuações. Geralmente, os flutuadores são mais rápidos que o dobro e consomem menos memória (os recursos da FPU variam). O volume de uso impede que esse ponto seja otimizado prematuramente. Assim como o fato de o dobro ser claramente exagerado para muitas aplicações (talvez até a maioria). Os elementos desta página realmente precisam ter suas posições e tamanhos relativos calculados com 13 casas decimais?
Selali Adobor 22/09

2
Ao incluir um link para uma página ou documento externo, copie as informações relevantes ou o resumo do documento em sua resposta. Os links externos ao site tendem a desaparecer com o tempo.
Adam Zuckerman

3

Para problemas do mundo real, o limite de amostragem dos seus dados é importante ao responder a essa pergunta. Da mesma forma, o piso de ruído também é importante. Se qualquer um for excedido pela sua seleção de tipo de dados, nenhum benefício será obtido com o aumento da precisão.

A maioria dos samplers do mundo real é limitada a DACs de 24 bits. Sugerindo que 32 bits de precisão nos cálculos do mundo real sejam adequados onde o significando seja 24 bits de precisão.

A precisão dupla tem o custo de 2x memória. Portanto, limitar o uso de duplas sobre flutuadores pode reduzir drasticamente o espaço ocupado por memória / largura de banda dos aplicativos em execução.


-3

A escolha de qual variável usar entre float e double depende da precisão dos dados necessários. Se uma resposta precisar de uma diferença desprezível da resposta real, o número de casas decimais necessárias será grande, portanto, ditará que o dobro estará em uso. O flutuador cortará algumas partes das casas decimais, reduzindo assim a precisão.


3
Essa resposta não adiciona nada de novo à pergunta e não diz nada de uso real.
Martijn Pieters

-5

Normalmente, uso o floattipo quando não preciso de muita precisão - por exemplo, por dinheiro - o que está errado, mas é o que estou acostumado a fazer de maneira errada.

Por outro lado, uso doublequando preciso de mais precisão, por exemplo, para algoritmos matemáticos complexos.

O padrão C99 diz o seguinte:

Existem três tipos de ponto flutuante: float, double e long double. O tipo double fornece pelo menos tanta precisão quanto float, e o tipo long double fornece pelo menos a mesma precisão que double. O conjunto de valores do tipo float é um subconjunto do conjunto de valores do tipo double; o conjunto de valores do tipo double é um subconjunto do conjunto de valores do tipo long double.

Eu realmente nunca usei long double, mas não uso muito C / C ++. Normalmente eu uso linguagens dinamicamente tipadas como Python, onde você não precisa se preocupar com os tipos.

Para mais informações sobre Double vs Float , consulte esta pergunta em SO .


25
Usar ponto flutuante para cálculos sérios de dinheiro provavelmente é um erro.
Bart van Ingen Schenau

17
float é exatamente o tipo errado de dinheiro. Você precisa usar a maior precisão possível.
ChrisF

8
@BartvanIngenSchenau O ponto flutuante por dinheiro geralmente é bom, o ponto flutuante binário não é. Por exemplo, .net's Decimalé um tipo de ponto flutuante e geralmente é uma boa opção para cálculos de dinheiro.
CodesInChaos

13
@ ChrisF Você não precisa de "alta precisão" por dinheiro, precisa de valores exatos.
Sean McSomething

2
@SeanMcSomething - Fair point. No entanto, os flutuadores ainda são do tipo errado e, considerando os tipos de ponto flutuante disponíveis na maioria dos idiomas, você precisa de "alta precisão" para obter "valores exatos".
ChrisF
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.