Как мне напечатать двойное значение с полной точностью, используя cout?

StackOverflow https://stackoverflow.com/questions/554063

Вопрос

Итак, я получил ответ на свой последний вопрос (Не знаю, почему я об этом не подумал).я печатал double с использованием cout это округлилось, когда я этого не ожидал.Как я могу сделать cout распечатать double используя полную точность?

Это было полезно?

Решение

Вы можете установить точность непосредственно на 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;

По сути, пакет лимитов имеет характеристики для всех типов встроенных модулей.
Одной из характеристик чисел с плавающей запятой (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;

Выход:

Пи: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

Примечание:Требуются заголовочные файлы

#include <iomanip>
#include <limits>

Под полной точностью я подразумеваю достаточную точность, чтобы показать наилучшее приближение к предполагаемому значению, но следует отметить, что double хранится с использованием представления по основанию 2, а основание 2 не может представлять что-то столь же тривиальное, как 1.1 точно.Единственный способ получить полный-полный точность фактического двойного числа (без ОШИБКИ ОКРУГЛЕНИЯ) заключается в распечатке двоичных битов (или шестнадцатеричных полубайтов).Один из способов сделать это — написать 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;

Как мне распечатать 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) точности.Слишком много ответов с точность не обеспечивают нужное значение.Отсюда и этот ответ на старый вопрос.

  1. Какая база?

А 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

  1. В противном случае: 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

  1. Какая точность (сколько всего цифр)?

А double кодированный с использованием двоичной базы 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 * 10Н.

Что бы ни N (точность), взаимно однозначного соответствия между double и десятичный текст. Если фиксированный N выбран, иногда его будет немного больше или меньше, чем действительно необходимо double ценности.Мы могли ошибиться слишком мало (a) ниже) или слишком много (b) ниже).

3 кандидата N:

а) Используйте N поэтому при преобразовании из текста-double-text мы приходим к одному и тому же тексту для всех double.

std::cout << dbl::digits10 << '\n';
// Typical output
15

б) Используйте N поэтому при преобразовании из double-текст-double мы приходим к одному и тому же double для всех double.

// C++11
std::cout << dbl::max_digits10 << '\n';
// Typical output
17

Когда max_digits10 недоступен, обратите внимание, что из-за атрибутов по основанию 2 и 10, digits10 + 2 <= max_digits10 <= digits10 + 3, мы можем использовать digits10 + 3 чтобы гарантировать, что будет напечатано достаточное количество десятичных цифр.

в) Используйте N это зависит от стоимости.

Это может быть полезно, когда код хочет отображать минимальное количество текста (N == 1) или точный ценность double (N == 1000-ish в случае denorm_min).Однако, поскольку это «работа», а не цель ОП, она будет отложена.


Обычно это b) используется для «печати 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

printf("%.12f", M_PI);

%.12f означает плавающую запятую с точностью до 12 цифр.

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», я понятия не имею, но дополнительная цифра, которую вы получаете, правильная.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top