Использование формата %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
Вы узнаете приближения к константе Планка и числу Авогадро, не так ли?