Подтвердить что ты не робот

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 %e\n", aboat, aboat);
    printf("%f can be written %e\n", abet, abet);
    printf("%lf can be written %le\n", 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 ...
4b9b3361

Ответ 1

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

Ответ 2

Из справочной страницы printf:

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

и

L Следующие a, A, e, E, f, F, g или G, соответствует длинный двойной аргумент. (C99 допускает % LF, но SUSv2 этого не делает.)

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

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

Ответ 3

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

Ответ 4

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

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

Ответ 5

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

Джейсон Хунтли @centurian/home/developer/dependencies/Python-2.7.3/test $gcc main.c

Джейсон Хунтли @centurian/home/developer/dependencies/Python-2.7.3/test $a.exe c = 0.000000

Джейсон Хунтли @centurian/home/developer/dependencies/Python-2.7.3/test $gcc main.c -D__USE_MINGW_ANSI_STDIO

Джейсон Хунтли @centurian/home/developer/dependencies/Python-2.7.3/test $a.exe c = 42.000000

код:

Jason [email protected] /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

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

Ответ 7

Как было сказано в других ответах, правильный спецификатор преобразования "%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`
$

Ответ 8

Функции printf и scanf в C/C++ используют библиотеку Microsoft C, и эта библиотека не поддерживает двойной дубль длиной 10 байт. Поэтому, когда вы используете функции printf и scanf в своем коде C/C++ для печати длинного двойного в качестве вывода и для некоторого ввода в качестве длинного двойного, это всегда даст вам неверный результат.

Если вы хотите использовать long double, тогда вы должны использовать функции "__mingw_printf" и "__mingw_scanf" вместо printf и scanf. Он поддерживает двойную длину 10 байт.

Или вы можете определить два макроса следующим образом: "#define printf __mingw_printf" и "#define scanf __mingw_scanf"

Используйте стандартный формат для long double:% Lf

Ответ 9

Правильный диалог 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"