Спецификатор %g
, похоже, не ведет себя так, как большинство источников документирует его как поведение.
Согласно большинству источников, которые я обнаружил, для нескольких языков, использующих спецификаторы printf
, спецификатор %g
должен быть эквивалентен либо %f
, либо %e
- в зависимости от того, что произвело бы более короткий вывод для предоставленного значение. Например, во время написания этого вопроса cplusplus.com сообщает , что спецификатор g
означает:
Используйте кратчайшее представление: %e
или %f
А в руководстве PHP написано , что означает:
g - короче % e и % f .
И вот ответ на переполнение стека , в котором утверждается, что
%g
использует кратчайшее представление.
И ответ Quora , в котором утверждается, что:
%g
печатает число в самом коротком из этих двух представлений
Но это поведение не то, что я вижу в реальности. Если я компилирую и запускаю эту программу (как C или C ++ - это допустимая программа с одинаковым поведением в обоих случаях):
#include <stdio.h>
int main(void) {
double x = 123456.0;
printf("%e\n", x);
printf("%f\n", x);
printf("%g\n", x);
printf("\n");
double y = 1234567.0;
printf("%e\n", y);
printf("%f\n", y);
printf("%g\n", y);
return 0;
}
... тогда я вижу этот вывод:
1.234560e+05
123456.000000
123456
1.234567e+06
1234567.000000
1.23457e+06
Очевидно, что вывод %g
не совсем соответствует или выводу %e
или %f
для x
или y
выше. Более того, не похоже, что %g
также минимизирует длину вывода; y
можно было бы отформатировать более кратко, если бы, как и x
, в научной нотации было напечатано , а не .
Все ли источники, которые я цитировал выше, лгут мне?
Я вижу идентичное или похожее поведение в других языках, которые поддерживают эти спецификаторы формата, возможно, потому, что они скрытно обращаются к семейству функций printf
. Например, я вижу этот вывод в Python:
>>> print('%g' % 123456.0)
123456
>>> print('%g' % 1234567.0)
1.23457e+06
В PHP:
php > printf('%g', 123456.0);
123456
php > printf('%g', 1234567.0);
1.23457e+6
в рубине:
irb(main):024:0* printf("%g\n", 123456.0)
123456
=> nil
irb(main):025:0> printf("%g\n", 1234567.0)
1.23457e+06
=> nil
Какая логика управляет этим выводом?