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

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

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

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

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

Я тестировал:

 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 standard (N1570 7.21.6.1) о спецификаторе преобразования g :

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

– если P> X ≥ -4 , преобразование происходит со стилем f (или F ) и точностью P – (X + 1) .

– в противном случае преобразование осуществляется со стилем e (или E ) и точностью P – 1 .

Таким образом, приведенное выше, P будет равно 6, потому что точность не указана, а X будет равно 2, потому что это показатель степени в стиле e .

Формула 6> 2> = -4 , таким образом, верна, и выбран стиль f . Тогда точность будет равна 6 – (2 + 1) = 3 .

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

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

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

Поэтому установите достаточно высокую точность:

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

печатает:

 101.9716