sprintf% g спецификатор дает слишком мало цифр после точки

Я пытаюсь записать переменные с плавающей запятой в мой INI-файл, и я столкнулся с проблемой со спецификаторами формата.
У меня есть значение с плавающей точкой, пусть это будет 101,9716. Теперь я хочу записать его в свой INI-файл, но проблема в том, что у меня есть другие значения с плавающей точкой, которые имеют меньший приоритет (например, 15,85), и что значения записываются в INI-файл в том же цикле.
так что я делаю:

sprintf(valLineY, "%g", grade[i].yArr[j]);

Все мои другие переменные становятся хорошими символами, такими как «20» (если это было 20.00000), «13.85» (если это было 13.850000) и так далее. Но 101.9716 становится «101.972» по некоторым причинам.
Подскажите, пожалуйста, почему это происходит и как сделать это «101.9716», не разрушая мою идеологию (которая касается удаления конечных нулей и ненужных представлений).
Спасибо за любую помощь.

1

Решение

Почему это происходит?

Я проверял:

double f = 101.9716;
printf("%f\n", f);
printf("%e\n", f);
printf("%g\n", f);

И это вывод:

101.971600
1.019716e+02 // Notice the exponent +02
101.972

Вот что говорит стандарт C (N1570 7.21.6.1) о спецификаторе преобразования g:

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

— если P> X ≥ −4, преобразование со стилем f (или же F) а также точность
P — (X + 1)
.

— в противном случае, конверсия со стилем e (или же E) и точность П — 1.

Итак, учитывая выше, п будет равно 6, потому что точность не указана, и Икс будет равно 2, потому что это показатель степени по стилю e,

формула 6> 2> = -4 Это правда, и стиль f выбран. А также точность будет тогда 6 — (2 + 1) = 3.

Как исправить?

В отличие от f, стиль g удалит ненужные нули, даже когда точность установлена.

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

Итак, установите достаточно высокую точность:

printf("%.8g\n", f);

печатает:

101.9716
2

Другие решения

Других решений пока нет …