508 votes

Quelle est la différence entre float et double ?

J'ai lu sur la différence entre la double précision et la simple précision. Cependant, dans la plupart des cas, float y double semblent être interchangeables, c'est-à-dire que l'utilisation de l'un ou l'autre ne semble pas affecter les résultats. Est-ce vraiment le cas ? Quand les flottants et les doubles sont-ils interchangeables ? Quelles sont les différences entre eux ?

615voto

KennyTM Points 232647

Une énorme différence.

Comme son nom l'indique, un double a deux fois la précision de float [1] . En général, un double a une précision de 15 chiffres décimaux, alors que float a 7.

Voici comment le nombre de chiffres est calculé :

double a 52 bits de mantisse + 1 bit caché : log(2 53 )÷log(10) = 15,95 chiffres

float a 23 bits de mantisse + 1 bit caché : log(2 24 )÷log(10) = 7,22 chiffres

Cette perte de précision pourrait entraîner l'accumulation d'erreurs de troncature plus importantes lorsque des calculs répétés sont effectués, par exemple

float a = 1.f / 81;
float b = 0;
for (int i = 0; i < 729; ++ i)
    b += a;
printf("%.7g\n", b); // prints 9.000023

tandis que

double a = 1.0 / 81;
double b = 0;
for (int i = 0; i < 729; ++ i)
    b += a;
printf("%.15g\n", b); // prints 8.99999999999996

De même, la valeur maximale du flotteur est d'environ 3e38 mais double est à peu près 1.7e308 donc en utilisant float peut atteindre "l'infini" (c'est-à-dire un nombre spécial à virgule flottante) beaucoup plus facilement que double pour quelque chose de simple, par exemple calculer la factorielle de 60.

Pendant les tests, il se peut que quelques cas de test contiennent ces énormes nombres, ce qui peut faire échouer vos programmes si vous utilisez des flottants.


Bien sûr, parfois, même double n'est pas assez précis, c'est pourquoi nous avons parfois des long double [1] (l'exemple ci-dessus donne 9.000000000000000066 sur Mac), mais tous les types de virgule flottante souffrent du problème suivant erreurs d'arrondi Donc, si la précision est très importante (par exemple, pour le traitement de l'argent), vous devez utiliser la méthode suivante int ou une classe de fractionnement.


En outre, n'utilisez pas += pour additionner beaucoup de nombres à virgule flottante, car les erreurs s'accumulent rapidement. Si vous utilisez Python, utilisez fsum . Sinon, essayez de mettre en œuvre la Algorithme de sommation de Kahan .


[1] : Les standards C et C++ ne spécifient pas la représentation de float , double y long double . Il est possible que les trois soient implémentés en double-précision IEEE. Néanmoins, pour la plupart des architectures (gcc, MSVC ; x86, x64, ARM) float es en effet, un nombre à virgule flottante IEEE à simple précision (binary32), et double es un nombre à virgule flottante IEEE à double précision (binaire64).

18 votes

Le conseil habituel pour la sommation est de trier vos nombres en virgule flottante par ordre de grandeur (le plus petit en premier) avant de faire la somme.

2 votes

Notez que, alors que les flottants et les doubles C/C++ sont presque toujours en simple et double précision IEEE respectivement, les longs doubles C/C++ sont beaucoup plus variables en fonction de votre CPU, compilateur et OS. Parfois c'est la même chose que le double, parfois c'est un format étendu spécifique au système, parfois c'est de la quadruple précision IEEE.

0 votes

@R..GitHubSTOPHELPINGICE : pourquoi ? Pouvez-vous expliquer ?

61voto

Gregory Pakosz Points 35546

Voici ce que disent les normes C99 (ISO-IEC 9899 6.2.5 §10) ou C++2003 (ISO-IEC 14882-2003 3.1.9 §8) :

Il existe trois types de virgule flottante : float , double y 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 des valeurs du type float est un sous-ensemble de l'ensemble des valeurs du type double ; l'ensemble des valeurs du type double est un sous-ensemble de l'ensemble des valeurs du type long double .

La norme C++ ajoute :

La représentation de la valeur des types à virgule flottante est définie par l'implémentation.

Je vous suggère de jeter un coup d'œil à l'excellent Ce que tout informaticien devrait savoir sur l'arithmétique à virgule flottante qui couvre en profondeur la norme IEEE de la virgule flottante. Vous apprendrez les détails de la représentation et vous réaliserez qu'il existe un compromis entre la magnitude et la précision. La précision de la représentation en virgule flottante augmente au fur et à mesure que la magnitude diminue, c'est pourquoi les nombres en virgule flottante compris entre -1 et 1 sont ceux qui ont le plus de précision.

0 votes

Est-ce que c'est juste moi ou le lien ne fonctionne pas pour quelqu'un d'autre ?

1 votes

Mise à jour du lien. Je crois que vous avez déjà trouvé le document en cherchant le titre.

30voto

Alok Singhal Points 33073

Étant donné une équation quadratique : x 2  - 4.0000000  x  + 3.9999999 = 0, les racines exactes à 10 chiffres significatifs sont , r 1  = 2.000316228 et r 2  = 1.999683772.

Utilisation de float y double nous pouvons écrire un programme de test :

#include <stdio.h>
#include <math.h>

void dbl_solve(double a, double b, double c)
{
    double d = b*b - 4.0*a*c;
    double sd = sqrt(d);
    double r1 = (-b + sd) / (2.0*a);
    double r2 = (-b - sd) / (2.0*a);
    printf("%.5f\t%.5f\n", r1, r2);
}

void flt_solve(float a, float b, float c)
{
    float d = b*b - 4.0f*a*c;
    float sd = sqrtf(d);
    float r1 = (-b + sd) / (2.0f*a);
    float r2 = (-b - sd) / (2.0f*a);
    printf("%.5f\t%.5f\n", r1, r2);
}   

int main(void)
{
    float fa = 1.0f;
    float fb = -4.0000000f;
    float fc = 3.9999999f;
    double da = 1.0;
    double db = -4.0000000;
    double dc = 3.9999999;
    flt_solve(fa, fb, fc);
    dbl_solve(da, db, dc);
    return 0;
}  

L'exécution du programme me donne :

2.00000 2.00000
2.00032 1.99968

Notez que les nombres ne sont pas importants, mais vous obtenez quand même des effets d'annulation en utilisant float .

(En fait, la méthode ci-dessus n'est pas la meilleure façon de résoudre les équations quadratiques en utilisant des nombres à virgule flottante à simple ou double précision, mais la réponse reste inchangée même si l'on utilise un méthode plus stable .)

19voto

graham.reeds Points 9363
  • Un double est de 64 et une précision simple (float) est de 32 bits.
  • Le double a une mantisse plus grande (les bits entiers du nombre réel).
  • Toute inexactitude sera plus petite dans le double.

9voto

N 1.1 Points 7687

Les flottants ont moins de précision que les doubles. Bien que vous le sachiez déjà, lisez Ce que nous devons savoir sur l'arithmétique à virgule flottante pour une meilleure compréhension.

0 votes

Par exemple, tous les doubles AVR sont des flottants (quatre octets).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X