Подтвердить что ты не робот

Печать очень больших чисел с плавающей запятой

#include <stdio.h>
#include <float.h>

int main()
{
    printf("%f\n", FLT_MAX);
}

Выход из GNU:

340282346638528859811704183484516925440.000000

Выход из Visual Studio:

340282346638528860000000000000000000000.000000

Соответствуют ли стандарты C и С++ для обоих результатов? Или они задают конкретный результат?

Обратите внимание, что FLT_MAX = 2^128-2^104 = 340282346638528859811704183484516925440.

4b9b3361

Ответ 1

Я думаю, что соответствующая часть стандарта C99 - это "Рекомендуемая практика" из 7.19.6.1 с .13:

Для преобразований e, e, f, f, g и g, если число значащих десятичных цифр не больше DECIMAL_DIG, то результат должен быть правильно округлен. Если количество Значительные десятичные цифры больше, чем DECIMAL_DIG, но исходное значение точно представляемый с цифрами DECIMAL_DIG, тогда результат должен быть точным представление с конечными нулями. В противном случае значение источника ограничено двумя смежные десятичные строки L < U, причем оба имеют DECIMAL_DIG значащие цифры; Значение результирующей десятичной строки D должно удовлетворять L <= D <= U, с дополнительным условием, что ошибка должна иметь правильный знак для текущего направления округления.

У меня сложилось впечатление, что это допускает некоторую свободу действий в том, что можно напечатать в этом случае; поэтому я пришел к выводу, что VS и GCC совместимы здесь.

Ответ 2

Оба разрешены стандартом C (С++ просто поддерживает стандарт C)

Из черновик версии в разделе 5.2.4.2.2 часть 10

Значения, приведенные в следующем списке, должны быть заменены постоянными выражениями с значения, определенные при реализации, которые больше или равны показанным:
 - максимальное представимое конечное число точек флексирования, (1 - b -p) b emax

FLT_MAX 1E+37

и визуальный С++ 2012 имеет

#define FLT_MAX         3.402823466e+38F        /* max value */

Ответ 3

Сам код ошибочен, где он использует %f для значения, большего, чем значение, содержащееся в float или double. Поступая таким образом, вы просите увидеть "за занавесом" относительно бессмысленных битов защиты или другого шума с плавающей точкой, генерируемого при преобразовании в десятичный.

Ясно, что вы не должны ожидать какой-либо согласованности в металлических документах, созданных после создания двигателя в Honda против Toyota. Никогда не думайте о каком-либо разумном ожидании такой последовательности.

Правильный способ отображения таких чисел - использование одного из "научных" форматов, таких как %g при условии, что точность не переопределена. В реализациях IEEE-754 7 десятичных цифр значимы для float, 15-16 для double, около 19 для long double и 34 для __float128. Итак, для примера, который вы указали, %.15g будет правильным, если предположить, что он реализован в IEEE-754.