Я выполняю простой расчет на C, для которого иногда результат равен нулю. Затем я печатаю эти результаты, используя что-то вроде printf("%0.4g", result)
. Если результат не равен 0, он делает то, что я хочу, например, вывод может быть 1.796e+04
. Однако, если результат ровно 0, что часто бывает, вывод будет 0
.
Мой вопрос: что я могу сделать, чтобы напечатать 0.0000
с 4 десятичными знаками, даже если число может быть ровно 0?
когда это 0, вы хотите показать 0,000?
Когда результат будет 1.0E-6, что вы видите (надеетесь увидеть)? IIRC, %g
по умолчанию удаляет нули в конце. Но POSIX говорит Наконец, если не используется флаг «#», все конечные нули должны быть удалены из дробной части результата, а символ десятичной точки должен быть удален, если не осталось дробной части., поэтому "%#0.4g"
должен выполнять свою работу.
Спецификатор %0.4g
указывает, что число должно быть с 3 знаками после запятой, т.е. 1.746e+04
. Чтобы получить 0.0000
с 4 знаками после запятой, вам нужно использовать .5g
Вы можете использовать
printf("%0.4f",YourVeriable);
Как это производит 1.796e+04
?
заявление
printf("%0.4e\n", res);
может решить вашу проблему!
отлично, это именно то, что я хотел, теперь я получаю 0.0000e+00, что даже лучше, чем я просил! Теперь, когда я печатаю несколько результатов подряд, все выглядит выровненным и чистым.
Чтобы иметь 4 десятичных знака, вы должны указать .5
. Чтобы 0
печаталось как 0.0
, вы должны добавить #
.
printf("%#.5g", 0.0);
Обратите внимание, что это напечатает 4
десятичных знаков, в отличие от %0.4g
, которое напечатает 3 десятичных знака.
0
перед точкой .
не нужен. Он используется для указания того, что поле должно начинаться с нулей, а не с пробелами при сопоставлении длины поля. Но вы не указываете длину поля, поэтому префикс не используется, поэтому 0
можно опустить.
Использование формата %g
с модификатором #
, вероятно, делает то, что вы хотите.
Спецификация POSIX для printf()
(которая обычно является надмножеством C11 §7.21.6.1 Функция printf()
, но здесь POSIX говорит то же, что и C11) требует:
g
,G
— The double argument representing a floating-point number shall be converted in the stylef
ore
(or in the styleF
orE
in the case of aG
conversion specifier), depending on the value converted and the precision. LetP
equal the precision if non-zero, 6 if the precision is omitted, or 1 if the precision is zero. Then, if a conversion with styleE
would have an exponent ofX
:
If
P > X >= -4
, the conversion shall be with stylef
(orF
) and precisionP-(X+1)
.Otherwise, the conversion shall be with style
e
(orE
) and precisionP -1
.Finally, unless the '
#
' flag is used, any trailing zeros shall be removed from the fractional portion of the result and the decimal-point character shall be removed if there is no fractional portion remaining.A double argument representing an infinity or NaN shall be converted in the style of an
f
orF
conversion specifier.
Таким образом, нужные нули в конце сохраняются, если указать #
в спецификации преобразования — "%#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
Вы признаете приближения к постоянной Планка и числу Авогадро, не так ли?
да, это очень хорошее решение, и оно делает именно то, о чем я просил. Тем не менее, кто-то еще указал на использование %0.4e, это не то, о чем я конкретно просил, но мне этот метод нравится даже больше. Однако, спасибо.
и нет, старый 6.022е23 не замечал, теперь замечаю!
Допустимо ли 5 пробелов с «0»? т.е.
" 0"
(комментарии сливают пробелы, поэтому не могу написать)