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

Я запутался в том, что max_digits10 представляет собой. В соответствии с его документация, это 0 для всех целочисленных типов. Формула для типов с плавающей точкой для max_digits10 выглядит как int«s digits10«S.

11

Решение

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

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

Будут исключения для обоих, но эти значения дают минимальную гарантию. Прочитайте оригинальное предложение на max_digits10 для ясного примера, слова профессора В. Кэхана и дальнейшие детали. Большинство реализаций C ++ следуют IEEE 754 для своих типов данных с плавающей точкой. Для IEEE 754 float, digits10 является 6 а также max_digits10 является 9; для 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го значительная цифра сохранилась, а 7го цифра не сохранилась для первого числа. Тем не менее, все 27 цифр второй выжили; этот исключение Тем не менее, большинство цифр становится разным после 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

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

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

22

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

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

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

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

2

По вопросам рекламы [email protected]