web-dev-qa-db-fra.com

printf et long double

J'utilise le dernier gcc avec Netbeans sur Windows. Pourquoi ne pas long double travail? Le spécificateur printf est-il %lf faux?

Code:

#include <stdio.h>

int main(void)
{
    float aboat = 32000.0;
    double abet = 5.32e-5;
    long double dip = 5.32e-5;

    printf("%f can be written %e\n", aboat, aboat);
    printf("%f can be written %e\n", abet, abet);
    printf("%lf can be written %le\n", dip, dip);

    return 0;
}

Sortie:

32000.000000 can be written 3.200000e+004
0.000053 can be written 5.320000e-005
-1950228512509697500000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000.000000
can be written 2.725000e+002
Press [Enter] to close the terminal ...
52
gameboy

En plus du mauvais modificateur, quel port de gcc pour Windows? mingw utilise la bibliothèque Microsoft C et il me semble que cette bibliothèque ne prend pas en charge le double double (le compilateur Microsoft C utilise un double double de 64 bits pour diverses raisons).

14
AProgrammer

De la page de manuel printf:

l (ell) Une conversion entière suivante correspond à un argument long int ou non signé long, ou une conversion n suivante correspond à un pointeur sur un argument long int, ou une conversion c suivante correspond à un argument wint_t ou une conversion s suivante correspond à un pointeur sur l'argument wchar_t.

et

L A suivant une conversion A, e, E, f, F, g ou G correspond à un long double argument. (C99 autorise% LF, mais pas SUSv2.)

Alors vous voulez %Le , ne pas %le

Edit: Une enquête plus poussée semble indiquer que Mingw utilise le runtime MSVC/win32 (pour des choses comme printf) - qui mappe long double à double. Donc, mélanger un compilateur (comme gcc) qui fournit un double long natif avec une exécution qui ne semble pas être un désordre.

42
nos

Oui pour long double, vous devez utiliser %Lf (c'est-à-dire 'L' majuscule).

37
Jerry Coffin

Si vous utilisez MinGW, le problème est que, par défaut, MinGW utilise les entrées/sorties, respectivement. fonctions de formatage à partir du runtime Microsoft C, qui ne prend pas en charge les nombres à virgule flottante 80 bits (long double == double dans Microsoft land).

Cependant, MinGW est également livré avec un ensemble d'implémentations alternatives qui do prennent en charge correctement les doubles longs. Pour les utiliser, préfixez les noms de fonction avec __mingw_ (par exemple. __mingw_printf). Selon la nature de votre projet, vous pouvez également vouloir globalement #define printf __mingw_printf Ou utiliser -D__USE_MINGW_ANSI_STDIO (qui active les versions MinGW de toutes les fonctions de la famille printf-).

23
klickverbot

Avoir ce problème en testant les doubles en double, et hélas, je suis tombé sur une solution! Vous devez compiler votre projet avec -D__USE_MINGW_ANSI_STDIO:

Jason Huntley @ centurian /home/developer/dependencies/Python-2.7.3/test $ gcc main.c

Jason Huntley @ centurian /home/developer/dependencies/Python-2.7.3/test $ a.exe c = 0.000000

Jason Huntley @ centurian /home/developer/dependencies/Python-2.7.3/test $ gcc main.c -D__USE_MINGW_ANSI_STDIO

Jason Huntley @ centurian /home/developer/dependencies/Python-2.7.3/test $ a.exe c = 42.000000

Code:

Jason Huntley@centurian /home/developer/dependencies/Python-2.7.3/test
$ cat main.c
#include <stdio.h>

int main(int argc, char **argv)
{
   long double c=42;

   c/3;

   printf("c=%Lf\n",c);

   return 0;
}
6
Jason Huntley

En C99, le modificateur de longueur pour long double semble être L et non l. man fprintf (ou l’équivalent pour Windows) devrait vous indiquer votre plate-forme particulière.

4
Jens Gustedt

Comme cela a été dit dans d'autres réponses, le spécificateur de conversion correct est "%Lf".

Vous voudrez peut-être activer l'avertissement de format en utilisant -Wformat (ou -Wall, qui inclut -Wformat) dans l'invocation gcc

 $ gcc source.c 
 $ gcc -Wall source.c 
 source.c: Dans la fonction `main`: 
 source.c: 5: avertissement: le format "% lf" attend le type `double`, mais l'argument 2 a le type 'long double` 
 source.c: 5: warning: le format"% le "attend le type` double`, mais l'argument 3 a le type ` double long 
 $ 
2
pmg

la fonction printf et scanf en C/C++ utilise la bibliothèque Microsoft C et cette bibliothèque ne prend pas en charge le double de 10 octets. Ainsi, lorsque vous utilisez les fonctions printf et scanf dans votre code C/C++ pour imprimer un double long en sortie et utiliser certaines entrées sous forme de double long, vous obtiendrez toujours un résultat erroné.

Si vous voulez utiliser long double, vous devez utiliser les fonctions "__mingw_printf" et "__mingw_scanf" au lieu de printf et scanf. Il prend en charge 10 octets de longueur double.

Ou vous pouvez définir deux macros comme ceci: "#define printf __mingw_printf" et "#define scanf __mingw_scanf"

Utilisez le format standard pour les doubles longs:% Lf

0
Rupak Paul