Quand utilisez-vous float et quand utilisez-vous le double

194

Dans mon expérience en programmation, je dois souvent décider si je dois utiliser des nombres flottants ou doubles pour mes nombres réels. Parfois, je privilégie le double, parfois le double, mais cela semble plus subjectif. Si je devais être confronté pour défendre ma décision, je ne donnerais probablement pas de bonnes raisons.

Quand utilisez-vous float et quand utilisez-vous double? Utilisez-vous toujours double, uniquement lorsque des contraintes de mémoire sont présentes, vous optez pour float? Ou utilisez-vous toujours float, sauf si l'exigence de précision vous oblige à utiliser double? Existe-t-il des différences substantielles en ce qui concerne la complexité de calcul des arithémétiques de base entre float et double? Quels sont les avantages et les inconvénients de l'utilisation de float ou double? Et avez-vous même utilisé long double?

Jakub Zaverka
la source
28
Dans de nombreux cas, vous ne souhaitez utiliser ni l'un ni l'autre, mais plutôt un type décimal à virgule flottante ou à point fixe. Les types à virgule flottante binaire ne peuvent pas représenter exactement la plupart des nombres décimaux.
CodesInChaos
3
Relié à Quelles sont les causes des erreurs d'arrondi en virgule flottante? . @CodesInChaos Ma réponse suggère des ressources pour vous aider à prendre cette décision. Il n’existe pas de solution unique .
Mark Booth
Très bonne réponse trouvée à: Stack Overflow
Haris
5
Qu'entendez-vous exactement par "décimales"? Si vous devez représenter des valeurs telles que 0,01 exactement (par exemple, pour de l'argent), la virgule flottante (binaire) n'est pas la solution. Si vous voulez simplement dire des nombres non entiers, alors la virgule flottante convient probablement - mais le terme "décimales" n'est pas le meilleur mot pour décrire ce dont vous avez besoin.
Keith Thompson
1
Tu n'as pas toujours le choix. Par exemple, sur la plate-forme Arduino, double et float équivalent à float. Vous devez trouver une bibliothèque de compléments pour gérer les doubles réels.
Kiwiron

Réponses:

187

Le choix par défaut pour un type à virgule flottante devrait être double. Ceci est aussi le type que vous obtenez avec littéraux à virgule flottante sans suffixe ou (en C) des fonctions standard qui fonctionnent sur les nombres à virgule flottante (par exemple exp, sinetc.).

float ne doit être utilisé que si vous devez utiliser un grand nombre de nombres à virgule flottante (de l'ordre de milliers ou plus) et si l'analyse de l'algorithme a montré que la portée réduite et la précision ne posaient pas de problème.

long doublepeut être utilisé si vous avez besoin d'une portée ou d'une précision supérieures à double, et si cela est prévu sur votre plate-forme cible.

En résumé, floatet long doubledoit être réservé à l'usage des spécialistes, avec doubleune utilisation "au quotidien".

Bart van Ingen Schenau
la source
10
Je n’envisagerais probablement pas de laisser flotter quelques milliers de valeurs, sauf en cas de problème de performances lié à la mise en cache à virgule flottante et au transfert de données. L'analyse implique généralement un coût substantiel pour montrer que le flottant est suffisamment précis.
Patricia Shanahan
4
En complément, si vous avez besoin de compatibilité avec d'autres systèmes, il peut être avantageux d'utiliser les mêmes types de données.
ZzzzBov
15
J'utiliserais des floats pour des millions de nombres, pas des milliers. De plus, certains GPU fonctionnent mieux avec des flotteurs, dans ce cas spécialisé, utilisez des flottants. Sinon, comme vous le dites, utilisez des doubles.
user949300
4
@PatriciaShanahan - 'problème de performance lié à ..' Un bon exemple est que si vous prévoyez d'utiliser SSE2 ou des instructions vectorielles similaires, vous pouvez effectuer 4 opérations / vecteur en float (vs 2 par double), ce qui peut permettre une amélioration significative de la vitesse ( moitié moins d’opérations et moitié moins de données à lire et à écrire). Cela peut réduire considérablement le seuil lorsque l'utilisation de flottants devient attrayante et vaut la peine de résoudre les problèmes numériques.
Gregory
12
Je souscris à cette réponse avec un conseil supplémentaire: lorsque l’on utilise des valeurs RVB pour l’affichage, il est acceptable d’utiliser float(et parfois une demi-précision) car ni l’œil humain, ni l’affichage, ni le système de couleur n’ont autant de précision. . Ce conseil s’applique par exemple à OpenGL, etc. Ce conseil supplémentaire ne s’applique pas aux images médicales, qui ont des exigences de précision plus strictes.
Rwong
42

Il y a rarement lieu d'utiliser float au lieu de doubler dans le code ciblant les ordinateurs modernes. La précision supplémentaire réduit (mais n'élimine pas) le risque d'erreur d'arrondi ou autre imprécision causant des problèmes.

Les principales raisons pour lesquelles je peux penser à utiliser float sont:

  1. Vous stockez de grands tableaux de nombres et devez réduire la consommation de mémoire de votre programme.
  2. Vous ciblez un système qui ne prend pas nativement en charge la virgule flottante double précision. Jusqu'à récemment, de nombreuses cartes graphiques ne prenaient en charge que les points flottants à simple précision. Je suis certain que de nombreux processeurs à faible consommation et embarqués prennent également en charge une virgule flottante limitée.
  3. Vous ciblez du matériel où la simple précision est plus rapide que la double précision et votre application utilise beaucoup l'arithmétique en virgule flottante. Sur les processeurs Intel modernes, je pense que tous les calculs en virgule flottante sont effectués en double précision, vous ne gagnez donc rien ici.
  4. Vous effectuez une optimisation de bas niveau, par exemple en utilisant des instructions spéciales de la CPU qui agissent sur plusieurs numéros à la fois.

Donc, en gros, la solution est double sauf si vous avez des limitations matérielles ou si l'analyse n'a pas montré que le stockage de nombres en double précision contribue de manière significative à l'utilisation de la mémoire.

utilisateur611910
la source
2
"Ordinateurs modernes" signifie processeurs Intel x86. Certaines des machines utilisées par les Anciens fournissaient une précision parfaitement adéquate avec le type à flotteur de base. (Le CDC 6600 utilisait un mot de 60 bits, 48 ​​bits de mantisse normalisée à virgule flottante, 12 bits d'exposant. C'est à peu près ce que le x86 vous donne pour la double précision.)
John R. Strohm
@ John.R.Strohm: accepté, mais les compilateurs C n'existaient pas sur CDC6600. C'était Fortran IV ...
Basile Starynkevitch
Par "ordinateurs modernes", j'entends tout processeur construit au cours des deux ou trois dernières décennies, ou réellement, puisque la norme de virgule flottante IEEE a été largement mise en œuvre. Je suis tout à fait au courant qu'il existe des architectures non x86 et je le pensais dans ma réponse: j'ai mentionné les GPU et les processeurs intégrés, qui ne sont généralement pas x86.
user611910
Ce n'est tout simplement pas vrai, cependant. SSE2 peut manipuler 4 flotteurs ou 2 doubles en une opération, AVX peut manipuler 8 flotteurs ou 4 doubles, AVX-512 peut manipuler 16 flotteurs ou 8 doubles. Pour tout type d’informatique haute performance, les calculs sur flotteurs doivent être considérés comme deux fois plus rapides que les mêmes opérations sur les doubles sur x86.
Larry Gritz
1
Et c'est encore pire, car vous pouvez placer deux fois plus de flottants dans le cache du processeur que de doubler, et la latence de la mémoire sera probablement le principal goulot d'étranglement de nombreux programmes. Garder au chaud tout un ensemble de flotteurs de travail dans le cache peut être littéralement d'un ordre de grandeur plus rapide que d'utiliser des doublons et de les renverser dans la mémoire vive.
Larry Gritz
10

Utilisez doublepour tous vos calculs et variables temporaires. À utiliser floatlorsque vous devez gérer un tableau de nombres float[](si la précision est suffisante) et que vous avez affaire à des dizaines de milliers de floatnombres.

La plupart / la plupart des fonctions mathématiques ou des opérateurs convertissent / retournent double, et vous ne souhaitez pas rediffuser les numéros vers floatpour des étapes intermédiaires.

Par exemple, si vous avez saisi 100 000 nombres dans un fichier ou un flux et que vous devez les trier, mettez les nombres dans un float[].

Fai Ng
la source
5

Certaines plates-formes (ARM Cortex-M2, Cortex-M4, etc.) ne prennent pas en charge double (cela peut toujours être vérifié dans le manuel de référence de votre processeur. S'il n'y a pas d'avertissement ou d'erreur de compilation, cela ne signifie pas que le code est optimal. double peut être imité.). C'est pourquoi vous devrez peut-être vous en tenir à int ou float .

Si ce n'est pas le cas, j'utiliserais le double .

Vous pouvez consulter le célèbre article de D. Goldberg ("Ce que tout informaticien devrait savoir sur l'arithmétique en virgule flottante"). Vous devriez réfléchir à deux fois avant d'utiliser l'arithmétique en virgule flottante. Il y a de grandes chances qu'ils ne soient pas du tout nécessaires dans votre situation particulière.

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

staroselskii
la source
3
Cette question a déjà été assez bien posée il y a un an ... laisser le compilateur l'émuler au lieu de tirer parti d'une FPU avec virgule flottante uniquement (notez que les FPU ne sont pas nécessaires sur toutes les plateformes, en fait, une architecture Cortex-M4 les définit comme une fonctionnalité facultative [M2 était-il une faute de frappe?] ).
Selali Adobor
La clé de cette logique est qu’il est vrai que l’on doit être fatigué de l’arithmétique en virgule flottante, et que ce sont de nombreux "bizarreries" qui ne prennent certainement pas la présence du support FPU pour les doubles comme signifiant simplement d’utiliser des doublons au lieu de flottants. Les flotteurs sont généralement plus rapides que les doubles et utilisent moins de mémoire (les fonctionnalités des FPU varient). Le volume d'utilisation empêche ce point d'être optimisé prématurément. De plus, les doubles sont manifestement excessifs pour beaucoup (peut-être même la plupart) des applications. Les éléments de cette page doivent-ils vraiment avoir leurs positions et tailles relatives calculées à 13 décimales?
Selali Adobor
2
Lorsque vous incluez un lien vers une page ou un document hors site, veuillez copier les informations pertinentes, ou le résumé, du document dans votre réponse. Les liens hors site ont tendance à disparaître avec le temps.
Adam Zuckerman
3

Pour les problèmes du monde réel, le seuil d'échantillonnage de vos données est important pour répondre à cette question. De même, le bruit de fond est également important. Si votre sélection de type de données dépasse l'un ou l'autre, la précision ne vous apportera aucun avantage.

La plupart des échantillonneurs du monde réel sont limités aux CNA 24 bits. Suggérer que 32 bits de précision sur des calculs du monde réel devrait convenir lorsque la signification est de 24 bits de précision.

La double précision coûte 2x la mémoire. Par conséquent, limiter l’utilisation de doublons par rapport aux flottants pourrait réduire considérablement l’empreinte mémoire / la bande passante des applications en cours d’exécution.

utilisateur3034617
la source
-3

Le choix de la variable à utiliser entre float et double dépend de la précision des données requises. Si une réponse doit avoir une différence négligeable par rapport à la réponse réelle, le nombre de décimales requises sera donc conséquent, ainsi le double sera utilisé. Float coupera certaines parties de la décimale, réduisant ainsi la précision.

David Monyancha
la source
3
Cette réponse n'ajoute rien de nouveau à la question et omet de dire quoi que ce soit d'utilisation réelle.
Martijn Pieters
-5

D'habitude, j'utilise le floattype quand je n'ai pas besoin de beaucoup de précision - par exemple pour l'argent - ce qui est faux, mais c'est ce que j'ai l'habitude de faire.

Par contre, j'utilise doublequand j'ai besoin de plus de précision, par exemple pour des algorithmes mathématiques complexes.

La norme C99 dit ceci:

Il existe trois types de virgule flottante: float, double et long double. Le type double fournit au moins autant de précision que float, et le type long double fournit au moins autant de précision que double. L'ensemble de valeurs du type float est un sous-ensemble de l'ensemble des valeurs du type double; l'ensemble de valeurs du type double est un sous-ensemble de l'ensemble des valeurs du type long double.

Je n'ai jamais vraiment utilisé long double, mais je n'utilise pas beaucoup le C / C ++. D'habitude, j'utilise des langages à typage dynamique comme Python, dans lesquels vous n'avez pas à vous soucier des types.

Pour plus d'informations sur Double vs Float , consultez cette question à l'adresse SO .

Addison Montgomery
la source
25
L'utilisation de la virgule flottante pour les calculs d'argent sérieux est probablement une erreur.
Bart van Ingen Schenau
17
float est exactement le mauvais type pour de l'argent. Vous devez utiliser la plus grande précision possible.
ChrisF
8
@BartvanIngenSchenau Un point flottant pour de l'argent n'est généralement pas grave, pas un point flottant binaire . Par exemple, .net Decimalest un type à virgule flottante et constitue généralement un bon choix pour les calculs d'argent.
CodesInChaos
13
@ChrisF Vous n'avez pas besoin de "haute précision" pour de l'argent, vous avez besoin de valeurs exactes.
Sean McSomething
2
@SeanMcSomething - Bon point. Cependant, les flottants sont toujours du type incorrect et, étant donné les types à virgule flottante disponibles dans la plupart des langues, vous avez besoin de "haute précision" pour obtenir les "valeurs exactes".
ChrisF