printf и длинный двойной

я использую последнюю версию gcc с Netbeans в Windows. Почему не long double работы? Это printf спецификатор %lf не так?

код:

#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 %en", aboat, aboat);
    printf("%f can be written %en", abet, abet);
    printf("%lf can be written %len", dip, dip);

    return 0;
}

выход:

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 ...

8 ответов


в дополнение к неправильному модификатору, какой порт gcc для Windows? mingw использует библиотеку Microsoft C, и я, кажется, помню, что эта библиотека не поддерживает 80bits long double (компилятор microsoft C использует 64 бит long double по разным причинам).


из manpage printf:

l (ell) следующее целое число преобразование соответствует длинному int или беззнаковый long int аргумент, или следующее преобразование n соответствует указатель на длинный аргумент int или после c преобразование соответствует аргументу wint_t или следующему s преобразование соответствует указателю на аргумент тип wchar_t.

и

л А, А, Е, Е, ф, ф, G, или преобразование G соответствует a долгий двойной спор. (С99 позволяет %LF, но SUSv2-нет.)

Итак, вы хотите %Le , а не %le

Edit: некоторые дальнейшие исследования, похоже, указывают, что Mingw использует среду выполнения MSVC/win32(для таких вещей, как printf), которая отображает long double в double. Таким образом, смешивание компилятора (например, gcc), который предоставляет собственный long double со средой выполнения, которая не кажется .. будет бардак.


Да -- для long double, вы должны использовать %Lf (т. е. верхний регистр 'L').


если вы используете MinGW, проблема в том, что по умолчанию MinGW использует resp ввода-вывода. функции форматирования из среды выполнения Microsoft C, которая не поддерживает 80-битные числа с плавающей запятой (long double ==double в Microsoft land).

однако MinGW также поставляется с набором альтернативных реализаций, которые do правильно поддерживать длинные дубли. Чтобы использовать их, префикс имена функций с __mingw_ (например,__mingw_printf). В зависимости от характера вашего проекта, вы можете также хочу глобально #define printf __mingw_printf или использовать -D__USE_MINGW_ANSI_STDIO (который включает версии MinGW всех printf-семейных функций).


была эта проблема тестирования длинных двойников, и, увы, я наткнулся на исправление! Вы должны скомпилировать свой проект с помощью-D _ _ USE_MINGW_ANSI_STDIO:

Jason Huntley@centurian /главная/разработчик / зависимости/Python-2.7.3/тест $ основным ССЗ.c

Jason Huntley@centurian /главная/разработчик / зависимости/Python-2.7.3/тест $ a.exe c=0.000000

Jason Huntley@centurian /главная/разработчик / зависимости/Python-2.7.3/тест $ основным ССЗ.с -Д__У_ПО MINGW_ANSI В_С STDIO

Jason Huntley@centurian /главная/разработчик / зависимости/Python-2.7.3/тест $ a.exe c=42.000000

код:

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;
}

в C99 модификатор длины для long double кажется L, а не l. man fprintf (или эквивалент для windows) должен сказать вам для вашей конкретной платформы.


как было сказано в других ответах, правильным спецификатором преобразования является "%Lf".

вы можете включить предупреждение о формате, используя -Wformat (или -Wall, которая включает -Wformat) в вызове gcc

$ gcc source.c
$ gcc -Wall source.c
source.c: In function `main`:
source.c:5: warning: format "%lf" expects type `double`, but argument 2 has type `long double`
source.c:5: warning: format "%le" expects type `double`, but argument 3 has type `long double`
$

правильный разговор Printf в Java :-

  double pi = Math.PI;

  System.out.format("%f%n", pi);       // -->  "3.141593"
  System.out.format("%.3f%n", pi);     // -->  "3.142"
  System.out.format("%10.3f%n", pi);   // -->  "     3.142"
  System.out.format("%-10.3f%n", pi);  // -->  "3.142"
  System.out.format(Locale.FRANCE,
                    "%-10.4f%n%n", pi); // -->  "3,1416"

  Calendar c = Calendar.getInstance();
  System.out.format("%tB %te, %tY%n", c, c, c); // -->  "May 29, 2006"

  System.out.format("%tl:%tM %tp%n", c, c, c);  // -->  "2:34 am"

  System.out.format("%tD%n", c);    // -->  "05/29/06"