Какова цель max_digits10 и чем она отличается от цифр10?

Я смущен тем, что представляет max_digits10. Согласно его документации, это 0 для всех интегральных типов. Формула для типов с плавающей точкой для max_digits10 похожа на int digits10.

Ответы

Ответ 1

Проще говоря,

  • digits10 - количество десятичных цифр, гарантированных для сохранения текста → float → text round-trip.
  • max_digits10 - количество десятичных цифр, необходимых для обеспечения правильного поплавка → текст → поплавок в оба конца.

Будут исключения для обоих, но эти значения дают минимальную гарантию. Прочтите оригинальное предложение на max_digits10 для ясного примера, слова профессора У. Кахана и дальнейшие подробности. Большинство реализаций на С++ соответствуют IEEE 754 для их типов данных с плавающей точкой. Для IEEE 754 float, digits10 - 6 и max_digits10 - 9; для a double это 15 и 17. Обратите внимание, что обе эти цифры не следует путать с фактической десятичной точностью чисел с плавающей запятой.

Пример digits10

char const *s1 = "8.589973e9";
char const *s2 = "0.100000001490116119384765625";
float const f1 = strtof(s1, nullptr);
float const f2 = strtof(s2, nullptr);
std::cout << "'" << s1 << "'" << '\t' << std::scientific << f1 << '\n';
std::cout << "'" << s2 << "'" << '\t' << std::fixed << std::setprecision(27) << f2 << '\n';

Печать

'8.589973e9'      8.589974e+009
'0.100000001490116119384765625'   0.100000001490116119384765625

Все цифры до знака 6 th были сохранены, а цифра 7 th не сохранилась для первого номера. Однако все 27 цифр второго сохранились; this является исключением. Однако большинство номеров становятся не более 7 цифр, и все числа будут одинаковыми в пределах 6 цифр.

Таким образом, digits10 дает количество значимых цифр, на которые вы можете рассчитывать в заданном float, как те же, что и исходное действительное число в его десятичной форме, из которой оно было создано, т.е. цифры, которые сохранились после преобразование в float.

Пример max_digits10

void f_s_f(float &f, int p) {
    std::ostringstream oss;
    oss << std::fixed << std::setprecision(p) << f;
    f = strtof(oss.str().c_str(), nullptr);
}

float f3 = 3.145900f;
float f4 = std::nextafter(f3, 3.2f);
std::cout << std::hexfloat << std::showbase << f3 << '\t' << f4 << '\n';
f_s_f(f3, std::numeric_limits<float>::max_digits10);
f_s_f(f4, std::numeric_limits<float>::max_digits10);
std::cout << f3 << '\t' << f4 << '\n';
f_s_f(f3, 6);
f_s_f(f4, 6);
std::cout << f3 << '\t' << f4 << '\n';

Печать

0x1.92acdap+1   0x1.92acdcp+1
0x1.92acdap+1   0x1.92acdcp+1
0x1.92acdap+1   0x1.92acdap+1

Здесь два разных float s, когда они печатаются с цифрами точности max_digits10, они дают разные строки, и эти строки при чтении вернут исходный float, из которого они сделаны. При печати с меньшей точностью они дают один и тот же результат из-за округления и, следовательно, при чтении обратно приводят к тому же float, когда на самом деле они имеют разные значения.

Таким образом, max_digits10, по крайней мере, требуется для двукратного смещения двух поплавков в их десятичной форме, так что при обратном обращении к двоичному поплавку мы получаем исходные биты снова, а не немного, до или после него из-за ошибки округления.

Ответ 2

По-моему, это достаточно объяснено на связанном сайте (и сайте для цифр10):

digits10 - это (максимальное) количество "десятичных" цифр, где числа могут быть представлены типом в любом случае, независимо от их фактического значения.
Обычное 4-байтовое целое число без знака в качестве примера: как всем известно, оно имеет ровно 32 бит,
это 32 цифры двоичного числа.
Но в терминах десятичных чисел?
Вероятно 9.
Потому что он может хранить 100000000, а также 999999999.
Но если взять цифры с 10 цифрами: 4000000000 можно сохранить, но 5000000000 нет.
Итак, если нам нужна гарантия на минимальную десятичную разрядность, то она равна 9.
И это результат цифр10.

max_digits10 интересен только для float/double... и дает число десятичных цифр которые мы должны выводить/сохранять/обрабатывать..., чтобы взять всю точность
тип с плавающей точкой. Теоретический пример: переменная с контентом 123.112233445566
Если вы показываете пользователю 123.11223344, это не так точно, как может быть. Если вы показываете пользователю 123.1122334455660000000, это не имеет смысла, потому что
вы можете опустить конечные нули (потому что ваша переменная не может так много удерживать)
Поэтому max_digits10 говорит, сколько цифр вы имеете в типе.