Как напечатать значение double
с полной точностью, используя cout?
Используйте hexfloat
или
используйте scientific
и установите точность
std::cout.precision(std::numeric_limits<double>::max_digits10 - 1);
std::cout << std::scientific << 1.0/7.0 << '\n';
// C++11 Typical output
1.4285714285714285e-01
Слишком много ответов касаются только одного из 1) базовых 2) фиксированных / научных схем или 3) точности. Слишком много ответов с точность не дают нужного значения. Отсюда и ответ на старый вопрос.
- Какая база?
A double
определенно кодируется с использованием базы 2. Прямой подход к C ++ 11 заключается в печати с использованием std::hexfloat
.
Если допустим недесятичный вывод, все готово.
std::cout << "hexfloat: " << std::hexfloat << exp (-100) << '\n';
std::cout << "hexfloat: " << std::hexfloat << exp (+100) << '\n';
// output
hexfloat: 0x1.a8c1f14e2af5dp-145
hexfloat: 0x1.3494a9b171bf5p+144
- В противном случае:
fixed
или scientific
?
A double
- это тип с плавающей точкой , а не с фиксированной точкой .
Не , не , используйте std::fixed
, поскольку это не позволяет печатать маленькие double
как что-либо, кроме 0.000...000
. Для больших double
он печатает много цифр, возможно сотен сомнительной информативности.
std::cout << "std::fixed: " << std::fixed << exp (-100) << '\n';
std::cout << "std::fixed: " << std::fixed << exp (+100) << '\n';
// output
std::fixed: 0.000000
std::fixed: 26881171418161356094253400435962903554686976.000000
Чтобы печатать с полной точностью, сначала используйте std::scientific
, который будет «записывать значения с плавающей точкой в научной нотации». Обратите внимание, что по умолчанию 6 цифр после десятичной точки, недостаточное количество, обрабатывается в следующей точке.
std::cout << "std::scientific: " << std::scientific << exp (-100) << '\n';
std::cout << "std::scientific: " << std::scientific << exp (+100) << '\n';
// output
std::scientific: 3.720076e-44
std::scientific: 2.688117e+43
- Сколько точности (сколько всего цифр)?
A double
, закодированный с использованием двоичной базы 2, кодирует одинаковую точность между различными степенями 2. Часто это 53 бита.
[1.0 ... 2.0) есть 2 53 разные double
,
[2.0 ... 4.0) есть 2 53 разные double
,
[4.0 ... 8.0) Есть 2 53 разные double
,
[8,0 ... 10,0) 2/8 * 2 53 разные double
.
Тем не менее, если код печатается в десятичном виде с N
значащими цифрами, количество комбинаций [1,0 ... 10,0) составляет 9/10 * 10 N .
Независимо от выбранной N
(точности) не будет однозначного сопоставления между double
и десятичным текстом. Если выбран фиксированный N
, иногда это будет быть немного больше или меньше, чем нужно для определенных значений double
. Мы можем ошибиться из-за слишком малого (a)
ниже) или слишком большого количества (b)
ниже).
3 кандидата N
:
a) Используйте N
, чтобы при преобразовании из текстового текста double
мы получали один и тот же текст для всех double
.
std::cout << dbl::digits10 << '\n';
// Typical output
15
b) Используйте N
, поэтому при конвертации из double
-text- double
мы получаем одинаковое double
для всех double
.
// C++11
std::cout << dbl::max_digits10 << '\n';
// Typical output
17
Когда max_digits10
недоступен, обратите внимание, что из-за атрибутов base 2 и base 10, digits10 + 2 <= max_digits10 <= digits10 + 3
, мы можем использовать digits10 + 3
, чтобы обеспечить печать достаточного количества десятичных цифр.
в) Используйте N
, который зависит от значения.
Это может быть полезно, когда код хочет отобразить минимальный текст (N == 1
) или точное значение double
(N == 1000-ish
в случае denorm_min
). Тем не менее, поскольку это «работа» и маловероятная цель ОП, она будет отложена.
Обычно б) используется для «печати значения double
с полной точностью». Некоторые приложения могут предпочесть а) ошибку из-за не слишком большого количества информации.
С помощью .scientific
, .precision()
устанавливает количество цифр для печати после десятичной точки, поэтому печатаются 1 + .precision()
цифры. Коду нужно max_digits10
всего цифр, поэтому .precision()
вызывается с max_digits10 - 1
.
typedef std::numeric_limits< double > dbl;
std::cout.precision(dbl::max_digits10 - 1);
std::cout << std::scientific << exp (-100) << '\n';
std::cout << std::scientific << exp (+100) << '\n';
// Typical output
3.7200759760208361e-44
2.6881171418161356e+43
Аналогичный вопрос C