Alguém já tentou fazer um array de floats e um array de doubles e ver se de fato há 4 bytes entre membros em floats e 8 bytes entre membros em doubles? É possível que um compilador / computador de 64 bits ainda reserve 8 bytes por membro para floats, embora eles não precisem de tanto.
Em suma, embora doublepermita maior precisão em sua representação, para certos cálculos produziria erros maiores . A escolha "certa" é: use a precisão necessária, mas não mais, e escolha o algoritmo certo .
Muitos compiladores fazem matemática de ponto flutuante estendida no modo "não estrito" de qualquer maneira (ou seja, usam um tipo de ponto flutuante mais amplo disponível em hardware, por exemplo, flutuante de 80 e 128 bits), isso também deve ser levado em consideração. Na prática, você dificilmente pode ver qualquer diferença na velocidade - eles são nativos do hardware de qualquer maneira.
Sim. Com CPUs modernas pré-buscando porções cada vez maiores de memória, unidades de processamento numérico paralelo e arquiteturas em pipeline, o problema de velocidade não é realmente um problema. Se você estiver lidando com grandes quantidades de números, então talvez a diferença de tamanho entre um float de 4 bytes e um double de 8 bytes possa fazer uma diferença no consumo de memória.
lavinio 02 de
5
Bem, SSE (ou qualquer unidade de ponto flutuante vertor) será capaz de processar duas vezes o número de flops em precisão simples em comparação com precisão dupla. Se você estiver fazendo apenas x87 (ou qualquer ponto flutuante escalar), provavelmente não fará diferença.
Greg Rogers
1
@Greg Rogers: os compiladores não são tão espertos no momento. A menos que você esteja escrevendo um assembly raw, não há grandes diferenças. E sim, isso pode mudar conforme o compilador evolui.
J-16 SDiZ
Uma observação adicional: Se você não tem absolutamente nenhuma ideia de como os dados se parecem (ou simplesmente não tem nenhuma pista de matemática nos links), apenas use double- é mais seguro na maioria dos casos.
J-16 SDiZ
@jokoon, não há nada simples em ponto flutuante e em toda a área de problemas de precisão / estabilidade numérica.
vonbrand de
45
A menos que você tenha algum motivo específico para fazer o contrário, use double.
Talvez surpreendentemente, é duplo e não flutuante que é o tipo de ponto flutuante "normal" em C (e C ++). As funções matemáticas padrão, como sin e log, recebem duplicatas como argumentos e retornam duplas. Um literal de ponto flutuante normal, como quando você escreve 3.14 em seu programa, tem o tipo double. Não flutuar.
Em computadores modernos típicos, os duplos podem ser tão rápidos quanto os flutuadores, ou até mais rápidos; portanto, o desempenho geralmente não é um fator a ser considerado, mesmo para cálculos grandes. (E esses teriam que ser grandes cálculos, ou o desempenho nem deveria passar pela sua mente. Meu novo computador desktop i7 pode fazer seis bilhões de multiplicações de duplas em um segundo.)
Esta pergunta é impossível de responder, pois não há contexto para a pergunta. Aqui estão algumas coisas que podem afetar a escolha:
Implementação do compilador de floats, doubles e long doubles. O padrão C ++ afirma:
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 tanta precisão quanto double.
Portanto, todos os três podem ter o mesmo tamanho na memória.
Presença de FPU. Nem todas as CPUs têm FPUs e às vezes os tipos de ponto flutuante são emulados e às vezes os tipos de ponto flutuante simplesmente não são suportados.
Arquitetura FPU. A FPU do IA32 é de 80 bits internamente - 32 bits e 64 bits são expandidos para 80 bits na carga e reduzidos na loja. Há também o SIMD que pode fazer quatro floats de 32 bits ou dois floats de 64 bits em paralelo. O uso de SIMD não está definido no padrão, portanto, seria necessário um compilador que faça análises mais complexas para determinar se o SIMD pode ser usado ou requer o uso de funções especiais (bibliotecas ou intrínsecas). O resultado do formato interno de 80 bits é que você pode obter resultados ligeiramente diferentes dependendo da frequência com que os dados são salvos na RAM (assim, perdendo a precisão). Por esse motivo, os compiladores não otimizam o código de ponto flutuante muito bem.
Largura de banda de memória. Se um double exigir mais armazenamento do que um float, demorará mais para ler os dados. Essa é a resposta ingênua. Em um IA32 moderno, tudo depende da origem dos dados. Se estiver no cache L1, a carga será insignificante, desde que os dados venham de uma única linha de cache. Se abranger mais de uma linha de cache, haverá uma pequena sobrecarga. Se for do L2, demora um pouco mais, se estiver na RAM então fica mais longo e finalmente, se estiver no disco é um tempo enorme. Portanto, a escolha de float ou double é menos importante do que a forma como os dados são usados. Se você deseja fazer um pequeno cálculo em muitos dados sequenciais, um pequeno tipo de dados é preferível. Fazer muitos cálculos em um pequeno conjunto de dados permitiria que você use tipos de dados maiores com qualquer efeito significativo. Se vocês' Ao acessar os dados de forma muito aleatória, a escolha do tamanho dos dados não é importante - os dados são carregados nas páginas / linhas de cache. Portanto, mesmo se você quiser apenas um byte da RAM, poderá obter 32 bytes transferidos (isso depende muito da arquitetura do sistema). Além de tudo isso, a CPU / FPU poderia ser superescalar (também conhecida como pipeline). Portanto, mesmo que uma carga possa levar vários ciclos, a CPU / FPU pode estar ocupada fazendo outra coisa (uma multiplicação, por exemplo) que oculta o tempo de carregamento até certo ponto.
O padrão não impõe nenhum formato específico para valores de ponto flutuante.
Se você tiver uma especificação, isso o guiará para a escolha ideal. Caso contrário, depende da experiência sobre o que usar.
Double é mais preciso, mas é codificado em 8 bytes. float tem apenas 4 bytes, portanto, menos espaço e menos precisão.
Você deve ter muito cuidado se tiver double e float em sua aplicação. Eu tive um bug devido a isso no passado. Uma parte do código estava usando float enquanto o resto do código estava usando double. Copiar duplo para flutuar e, em seguida, flutuar para dobrar pode causar um erro de precisão que pode ter um grande impacto. No meu caso, era uma fábrica de produtos químicos ... espero que não tenha consequências dramáticas :)
Acho que é por causa desse tipo de bug que o foguete Ariane 6 explodiu alguns anos atrás !!!
Pense cuidadosamente sobre o tipo a ser usado para uma variável
Note que 4/8 bytes para float / double nem é garantido, vai depender da plataforma. Pode até ser do mesmo tipo ...
sleske
2
O código do Ariane 5 tentou converter um ponto flutuante de 64 bits, cujo valor era maior que 32.767, em um inteiro assinado de 16 bits. Isso gerou uma exceção de estouro que fez com que o foguete iniciasse sua sequência de autodestruição. O código em questão era um código que foi reutilizado de um foguete menor e mais antigo.
cmwt
5
Eu pessoalmente procuro o dobro até ver alguns gargalos. Então eu considero mover para flutuar ou otimizar alguma outra parte
Isso depende de como o compilador implementa o double. É legal que double e float sejam do mesmo tipo (e é em alguns sistemas).
Dito isso, se eles são de fato diferentes, o principal problema é a precisão. Um duplo tem uma precisão muito maior devido à diferença de tamanho. Se os números que você está usando normalmente excederem o valor de um float, use um double.
Várias outras pessoas mencionaram problemas de desempenho. Isso seria exatamente o último da minha lista de considerações. A correção deve ser sua consideração número 1.
Acho que independentemente das diferenças (que como todos apontam, os flutuadores ocupam menos espaço e são em geral mais rápidos) ... alguém já teve problemas de desempenho usando o double? Eu digo usar o dobro ... e se mais tarde você decidir "uau, isso é muito lento" ... encontre seu gargalo de desempenho (que provavelmente não é o fato de você ter usado o dobro). ENTÃO, se ainda for muito lento para você, veja onde você pode sacrificar alguma precisão e usar float.
Depende muito da CPU e as compensações mais óbvias são entre precisão e memória. Com GBs de RAM, a memória não é um grande problema, então geralmente é melhor usar doubles.
Quanto ao desempenho, depende muito da CPU. floats geralmente obterá melhor desempenho do que doubles em uma máquina de 32 bits. Em 64 bits, doubles às vezes são mais rápidos, pois é (geralmente) o tamanho nativo. Ainda assim, o que importará muito mais do que sua escolha de tipos de dados é se você pode ou não tirar proveito das instruções SIMD em seu processador.
double tem maior precisão, enquanto floats ocupam menos memória e são mais rápidos. Em geral, você deve usar float, a menos que haja um caso em que não seja preciso o suficiente.
Respostas:
Se quiser saber a resposta verdadeira, você deve ler O que todo cientista da computação deve saber sobre aritmética de ponto flutuante .
Em suma, embora
double
permita maior precisão em sua representação, para certos cálculos produziria erros maiores . A escolha "certa" é: use a precisão necessária, mas não mais, e escolha o algoritmo certo .Muitos compiladores fazem matemática de ponto flutuante estendida no modo "não estrito" de qualquer maneira (ou seja, usam um tipo de ponto flutuante mais amplo disponível em hardware, por exemplo, flutuante de 80 e 128 bits), isso também deve ser levado em consideração. Na prática, você dificilmente pode ver qualquer diferença na velocidade - eles são nativos do hardware de qualquer maneira.
fonte
double
- é mais seguro na maioria dos casos.A menos que você tenha algum motivo específico para fazer o contrário, use double.
Talvez surpreendentemente, é duplo e não flutuante que é o tipo de ponto flutuante "normal" em C (e C ++). As funções matemáticas padrão, como sin e log, recebem duplicatas como argumentos e retornam duplas. Um literal de ponto flutuante normal, como quando você escreve 3.14 em seu programa, tem o tipo double. Não flutuar.
Em computadores modernos típicos, os duplos podem ser tão rápidos quanto os flutuadores, ou até mais rápidos; portanto, o desempenho geralmente não é um fator a ser considerado, mesmo para cálculos grandes. (E esses teriam que ser grandes cálculos, ou o desempenho nem deveria passar pela sua mente. Meu novo computador desktop i7 pode fazer seis bilhões de multiplicações de duplas em um segundo.)
fonte
Esta pergunta é impossível de responder, pois não há contexto para a pergunta. Aqui estão algumas coisas que podem afetar a escolha:
Implementação do compilador de floats, doubles e long doubles. O padrão C ++ afirma:
Portanto, todos os três podem ter o mesmo tamanho na memória.
Presença de FPU. Nem todas as CPUs têm FPUs e às vezes os tipos de ponto flutuante são emulados e às vezes os tipos de ponto flutuante simplesmente não são suportados.
Arquitetura FPU. A FPU do IA32 é de 80 bits internamente - 32 bits e 64 bits são expandidos para 80 bits na carga e reduzidos na loja. Há também o SIMD que pode fazer quatro floats de 32 bits ou dois floats de 64 bits em paralelo. O uso de SIMD não está definido no padrão, portanto, seria necessário um compilador que faça análises mais complexas para determinar se o SIMD pode ser usado ou requer o uso de funções especiais (bibliotecas ou intrínsecas). O resultado do formato interno de 80 bits é que você pode obter resultados ligeiramente diferentes dependendo da frequência com que os dados são salvos na RAM (assim, perdendo a precisão). Por esse motivo, os compiladores não otimizam o código de ponto flutuante muito bem.
Largura de banda de memória. Se um double exigir mais armazenamento do que um float, demorará mais para ler os dados. Essa é a resposta ingênua. Em um IA32 moderno, tudo depende da origem dos dados. Se estiver no cache L1, a carga será insignificante, desde que os dados venham de uma única linha de cache. Se abranger mais de uma linha de cache, haverá uma pequena sobrecarga. Se for do L2, demora um pouco mais, se estiver na RAM então fica mais longo e finalmente, se estiver no disco é um tempo enorme. Portanto, a escolha de float ou double é menos importante do que a forma como os dados são usados. Se você deseja fazer um pequeno cálculo em muitos dados sequenciais, um pequeno tipo de dados é preferível. Fazer muitos cálculos em um pequeno conjunto de dados permitiria que você use tipos de dados maiores com qualquer efeito significativo. Se vocês' Ao acessar os dados de forma muito aleatória, a escolha do tamanho dos dados não é importante - os dados são carregados nas páginas / linhas de cache. Portanto, mesmo se você quiser apenas um byte da RAM, poderá obter 32 bytes transferidos (isso depende muito da arquitetura do sistema). Além de tudo isso, a CPU / FPU poderia ser superescalar (também conhecida como pipeline). Portanto, mesmo que uma carga possa levar vários ciclos, a CPU / FPU pode estar ocupada fazendo outra coisa (uma multiplicação, por exemplo) que oculta o tempo de carregamento até certo ponto.
O padrão não impõe nenhum formato específico para valores de ponto flutuante.
Se você tiver uma especificação, isso o guiará para a escolha ideal. Caso contrário, depende da experiência sobre o que usar.
fonte
Double é mais preciso, mas é codificado em 8 bytes. float tem apenas 4 bytes, portanto, menos espaço e menos precisão.
Você deve ter muito cuidado se tiver double e float em sua aplicação. Eu tive um bug devido a isso no passado. Uma parte do código estava usando float enquanto o resto do código estava usando double. Copiar duplo para flutuar e, em seguida, flutuar para dobrar pode causar um erro de precisão que pode ter um grande impacto. No meu caso, era uma fábrica de produtos químicos ... espero que não tenha consequências dramáticas :)
Acho que é por causa desse tipo de bug que o foguete Ariane 6 explodiu alguns anos atrás !!!
Pense cuidadosamente sobre o tipo a ser usado para uma variável
fonte
Eu pessoalmente procuro o dobro até ver alguns gargalos. Então eu considero mover para flutuar ou otimizar alguma outra parte
fonte
Isso depende de como o compilador implementa o double. É legal que double e float sejam do mesmo tipo (e é em alguns sistemas).
Dito isso, se eles são de fato diferentes, o principal problema é a precisão. Um duplo tem uma precisão muito maior devido à diferença de tamanho. Se os números que você está usando normalmente excederem o valor de um float, use um double.
Várias outras pessoas mencionaram problemas de desempenho. Isso seria exatamente o último da minha lista de considerações. A correção deve ser sua consideração número 1.
fonte
Use a precisão necessária para obter os resultados apropriados . Se você descobrir que seu código não está funcionando tão bem quanto gostaria (você usou a criação de perfil correta?), Dê uma olhada em:
fonte
Acho que independentemente das diferenças (que como todos apontam, os flutuadores ocupam menos espaço e são em geral mais rápidos) ... alguém já teve problemas de desempenho usando o double? Eu digo usar o dobro ... e se mais tarde você decidir "uau, isso é muito lento" ... encontre seu gargalo de desempenho (que provavelmente não é o fato de você ter usado o dobro). ENTÃO, se ainda for muito lento para você, veja onde você pode sacrificar alguma precisão e usar float.
fonte
A principal diferença entre float e double é a precisão. A Wikipedia tem mais informações sobre precisão simples (float) e precisão dupla .
fonte
Depende muito da CPU e as compensações mais óbvias são entre precisão e memória. Com GBs de RAM, a memória não é um grande problema, então geralmente é melhor usar
double
s.Quanto ao desempenho, depende muito da CPU.
float
s geralmente obterá melhor desempenho do quedouble
s em uma máquina de 32 bits. Em 64 bits,double
s às vezes são mais rápidos, pois é (geralmente) o tamanho nativo. Ainda assim, o que importará muito mais do que sua escolha de tipos de dados é se você pode ou não tirar proveito das instruções SIMD em seu processador.fonte
double tem maior precisão, enquanto floats ocupam menos memória e são mais rápidos. Em geral, você deve usar float, a menos que haja um caso em que não seja preciso o suficiente.
fonte