Quais são as vantagens e desvantagens de usar um em vez do outro em C ++?
Quais são as vantagens e desvantagens de usar um em vez do outro em C ++?
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.
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.)
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
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.
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:
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.
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 .
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 que double
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.
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.