Как напечатать двойное значение с полной точностью с помощью cout?
Итак, я получил ответ на мой последний вопрос (Я не знаю, почему я не подумал об этом). Я печатал double
используя cout
Это было округлено, когда я этого не ожидал. Как я могу сделать cout
print a double
используя полную точность?
11 ответов:
вы можете установить точность непосредственно на
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;
использовать
std::setprecision
:std::cout << std::setprecision (15) << 3.14159265358979 << std::endl;
вот что я бы использовал:
std::cout << std::setprecision (std::numeric_limits<double>::digits10 + 1) << 3.14159265358979 << std::endl;
в основном пакет limits имеет черты для всех типов сборки.
Одним из признаков для чисел с плавающей запятой (float/double/long double) является атрибут digits10. Это определяет точность (я забыл точную терминологию) числа с плавающей запятой в базе 10.см.:http://www.cplusplus.com/reference/std/limits/numeric_limits.html
Для получения подробной информации о других атрибутах.
путь 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
вот как отобразить двойник с полной точностью:
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
по полной точности я предполагаю, что достаточно точности, чтобы показать лучшее приближение к предполагаемому значению, но следует отметить, что
double
хранится с использованием представления базы 2 и база 2 не может представлять что-то столь же тривиальное, как1.1
точно. Единственный способ получить полное полное точность фактического двойного (без ошибки округления) заключается в том, чтобы распечатать двоичные биты (или шестнадцатеричные nybbles). Один из способов сделать это-написатьdouble
доunion
и затем распечатка целочисленного значения битов.union { double d; uint64_t u64; } x; x.d = 1.1; std::cout << std::hex << x.u64;
это даст вам 100% точную точность двойника... и быть совершенно нечитаемым, потому что люди не могут читать двойной формат IEEE ! Википедия имеет хорошую запись о том, как интерпретировать двоичные биты.
в новом C++, вы можете сделать
std::cout << std::hexfloat << 1.1;
cout-это объект, который имеет кучу методов, которые вы можете вызвать, чтобы изменить точность и форматирование печатных материалов.
есть setprecision(...) деятельность, но вы можете также установить другие вещи как ширина печати, ЕТК.
посмотрите cout в ссылке вашей IDE.
наиболее переносимым...
#include <limits> using std::numeric_limits; ... cout.precision(numeric_limits<double>::digits10 + 1); cout << d;
С ostream:: precision (int)
cout.precision( numeric_limits<double>::digits10 + 1); cout << M_PI << ", " << M_E << endl;
даст
3.141592653589793, 2.718281828459045
почему вы должны сказать "+1 " я понятия не имею, но дополнительная цифра, которую вы получаете из него, правильна.
как мне напечатать
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
это с плавающей точкой тип, а не фиксированная точка.Do не использовать
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) есть 253 разные
double
,
[2.0...4.0) есть 253 разныеdouble
,
[4.0...8.0) есть 253 разныеdouble
,
[8.0...10.0) есть 2/8 * 253 другойdouble
.но если код печатается в десятичном виде с
N
значащие цифры, количество комбинаций [1.0...10.0) - это 9/10 * 10N.все
N
(точность) выбирается, не будет взаимно однозначного отображения междуdouble
и десятичных текст. если фиксированныйN
выбирается, иногда это будет немного больше или меньше, чем действительно необходимо для некоторыхdouble
значения. Мы могли бы ошибиться на слишком мало (a)
ниже) или слишком многие (b)
ниже).кандидат 3
N
:a) используйте
N
поэтому при преобразовании из текстаdouble
-текст мы приходим к одному и тому же тексту для всехdouble
.std::cout << dbl::digits10 << '\n'; // Typical output 15
b) используйте
N
так что при конвертации изdouble
текст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
). Но поскольку это "работа" и вряд ли цель ОП, она будет отложена.
обычно это b), который используется для "печати a
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