Как использовать printf, чтобы нули печатались с десятичными знаками - PullRequest
0 голосов
/ 13 мая 2019

Я выполняю простой расчет на C, для которого иногда результат равен точно 0. Затем я печатаю эти результаты, используя что-то вроде printf("%0.4g", result). Если результат не равен 0, он делает то, что я хочу, например, вывод может быть 1.796e+04. Однако, если результат равен именно 0, как это часто бывает, на выходе будет 0.

Мой вопрос: что я могу сделать, чтобы напечатать 0.0000, с 4 десятичными знаками, даже если число там может быть ровно 0?

Ответы [ 4 ]

3 голосов
/ 13 мая 2019

Использование формата %g с модификатором #, вероятно, делает то, что вы хотите.

Спецификация POSIX для printf() (которая обычно является надмножеством C11 §7.21.6.1 Функция printf() , но здесь POSIX говорит то же самое, что и C11) требует :

  • g, G - Аргумент double , представляющий число с плавающей запятой, должен быть преобразован в стиль f или e (или в стиль F или E в случае спецификатора преобразования G), в зависимости от преобразованного значения и точности. Пусть P равна точности, если она не равна нулю, 6, если точность не указана, или 1, если точность равна нулю. Тогда, если преобразование со стилем E будет иметь показатель степени X:

    • Если P > X >= -4, преобразование должно быть со стилем f (или F) и точностью P-(X+1).

    • В противном случае преобразование должно выполняться со стилем e (или E) и точностью P -1.

Наконец, если не используется флаг '#', любые дробные нули должны быть удалены из дробной части результата, а символ десятичной точки должен быть удален, если не осталось дробной части.

Аргумент double , представляющий бесконечность или NaN, должен быть преобразован в стиле спецификатора преобразования f или F.

Таким образом, желаемые конечные нули сохраняются путем указания # в спецификации преобразования - "%#0.4g".

Если вы хотите 4 цифры после десятичной точки, вам нужно использовать "%#0.5g".

Пример кода:

#include <stdio.h>

int main(void)
{
    double data[] = { 0.0, -0.0000001, +1.234E-6, 1.796e+04, 3.14159265, 6.022140857E+23, 6.62607004E-34 };
    enum { NUM_DATA = sizeof(data) / sizeof(data[0]) };
    for (int i = 0; i < NUM_DATA; i++)
        printf("%20.10g = %#0.4g\n", data[i], data[i]);
    return 0;
}

Вывод (Mac под управлением MacOS 10.14.4 Mojave - домашний компилятор GCC 9.1.0):

                   0 = 0.000
              -1e-07 = -1.000e-07
           1.234e-06 = 1.234e-06
               17960 = 1.796e+04
          3.14159265 = 3.142
     6.022140857e+23 = 6.022e+23
      6.62607004e-34 = 6.626e-34

Вы узнаете приближения к константе Планка и числу Авогадро, не так ли?

3 голосов
/ 13 мая 2019

Чтобы иметь 4 десятичных знака, вы должны указать .5. Чтобы 0 печаталось как 0.0, необходимо добавить #.

printf("%#.5g", 0.0);

Обратите внимание, что при этом будет напечатано 4 десятичных знаков, в отличие от %0.4g, при этом будут напечатаны 3 десятичных знака.

0 перед точкой . не требуется. Он используется для указания того, что поле должно начинаться с нуля, а не с пробелами при сопоставлении длины поля. Но вы не указываете длину поля, поэтому префикс не выполняется, поэтому 0 можно не указывать.

2 голосов
/ 13 мая 2019

заявление

printf("%0.4e\n", res);

может решить вашу проблему!

1 голос
/ 13 мая 2019

Вы можете использовать printf("%0.4f",YourVeriable);

...