Итак, я получил ответ на мой последний вопрос (я не знаю, почему я об этом не думал). Я печатал double
с помощью cout
, который был округлен, когда я этого не ожидал. Как я могу сделать cout
распечатать a double
с полной точностью?
Как напечатать двойное значение с полной точностью с помощью cout?
Ответ 1
Вы можете установить точность непосредственно в std::cout
и использовать спецификатор формата std::fixed
.
double d = 3.14159265358979;
cout.precision(17);
cout << "Pi: " << fixed << d << endl;
Вы можете #include <limits>
чтобы получить максимальную точность типа float или double.
#include <limits>
typedef std::numeric_limits< double > dbl;
double d = 3.14159265358979;
cout.precision(dbl::max_digits10);
cout << "Pi: " << d << endl;
Ответ 2
Используйте std::setprecision
:
std::cout << std::setprecision (15) << 3.14159265358979 << std::endl;
Ответ 3
Вот что я хотел бы использовать:
std::cout << std::setprecision (std::numeric_limits<double>::digits10 + 1)
<< 3.14159265358979
<< std::endl;
В принципе, пакет ограничений имеет черты для всех типов сборки.
Одной из характеристик чисел с плавающей запятой (float/double/long double) является атрибут digits10. Это определяет точность (я забываю точную терминологию) числа с плавающей запятой в базе 10.
Смотрите: http://www.cplusplus.com/reference/std/limits/numeric_limits.html
Подробнее о других атрибутах.
Ответ 4
Способ iostreams является довольно неуклюжим. Я предпочитаю использовать boost::lexical_cast
, потому что он вычисляет правильную точность для меня. И он быстро.
#include <string>
#include <boost/lexical_cast.hpp>
using boost::lexical_cast;
using std::string;
double d = 3.14159265358979;
cout << "Pi: " << lexical_cast<string>(d) << endl;
Вывод:
Pi: 3.14159265358979
Ответ 5
Вот как отобразить двойной с полной точностью:
double d = 100.0000000000005;
int precision = std::numeric_limits<double>::max_digits10;
std::cout << std::setprecision(precision) << d << std::endl;
Это отображает:
+100,0000000000005
max_digits10 - количество цифр, необходимое для уникального представления всех различных двойных значений. max_digits10 представляет количество цифр до и после десятичной точки.
Не используйте set_precision (max_digits10) с std :: fixed.
В фиксированной записи set_precision() устанавливает количество цифр только после десятичной точки. Это неверно, так как max_digits10 представляет количество цифр до и после десятичной точки.
double d = 100.0000000000005;
int precision = std::numeric_limits<double>::max_digits10;
std::cout << std::fixed << std::setprecision(precision) << d << std::endl;
Это отображает неверный результат:
+100,00000000000049738
Примечание. Требуются заголовочные файлы.
#include <iomanip>
#include <limits>
Ответ 6
По полной точности я предполагаю достаточно высокую точность, чтобы показать наилучшее приближение к предполагаемому значению, но следует отметить, что double
хранится с использованием представления base 2, а base 2 не может представлять что-то как тривиальное, как 1.1
точно. Единственный способ получить точность full-full фактического двойного (без NO ROUND OFF ERROR) - это распечатать двоичные биты (или шестнадцатеричные nybbles). Один из способов сделать это - записать double
в union
, а затем распечатать целочисленное значение бит.
union {
double d;
uint64_t u64;
} x;
x.d = 1.1;
std::cout << std::hex << x.u64;
Это даст вам 100% точную точность двойника... и будет совершенно нечитаемым, потому что люди не могут читать двойной формат IEEE! Wikipedia имеет хорошую запись о том, как интерпретировать двоичные биты.
В новом С++ вы можете сделать
std::cout << std::hexfloat << 1.1;
Ответ 7
Как напечатать значение
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) точности. Слишком много ответов с точностью не дают нужного значения. Отсюда и ответ на старый вопрос.
- Какая база?
double
определенно кодируется с использованием базы 2. Прямой подход к С++ 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
?
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
- Сколько точности (сколько всего цифр)?
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
, чтобы при преобразовании из text- double
-text мы получали одинаковый текст для всех 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
, чтобы обеспечить печать достаточного количества десятичных цифр.
c) Используйте 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
//1234567890123456 17 total digits
Ответ 8
printf("%.12f", M_PI);
%. 12f означает с плавающей запятой с точностью до 12 цифр.
Ответ 9
cout - это объект, который имеет множество методов, которые вы можете вызвать для изменения точности и форматирования печатных материалов.
Существует операция setprecision (...), но вы также можете установить другие параметры, такие как ширина печати и т.д.
Посмотрите cout в своей ссылке IDE.
Ответ 10
Наиболее портативно...
#include <limits>
using std::numeric_limits;
...
cout.precision(numeric_limits<double>::digits10 + 1);
cout << d;
Ответ 11
С ostream:: precision (int)
cout.precision( numeric_limits<double>::digits10 + 1);
cout << M_PI << ", " << M_E << endl;
даст
3.141592653589793, 2.718281828459045
Почему вы должны сказать "+1", я понятия не имею, но лишняя цифра, которую вы выберете, верна.