Итак, я получил ответ на мой последний вопрос (я не знаю, почему я не подумал об этом). Я печатал double
использование, cout
которое округлилось, когда я не ожидал этого. Как я могу сделать cout
печать с double
использованием полной точности?
332
fixed
? Сdouble h = 6.62606957e-34;
,fixed
дает мне0.000000000000000
иscientific
выводы6.626069570000000e-34
.cout.precision(numeric_limits<double>::digits10 + 2);
получаю только 16 ....max_digits10
чтобы обозначить то же самое. Исправлен ответ, чтобы отразить это.Используйте
std::setprecision
:источник
std::setprecision (17)
удвоен, см. Комментарии к ответу @Bill The Lizard.Вот что я бы использовал:
По сути, пакет limit имеет черты для всех встроенных типов.
Одной из особенностей чисел с плавающей запятой (float / double / long double) является атрибут digits10. Это определяет точность (я забыл точную терминологию) числа с плавающей запятой в базе 10.
См. Http://www.cplusplus.com/reference/std/limits/numeric_limits.html
Подробнее о других атрибутах.
источник
std::setprecision()
:#include <iomanip>
std::numeric_limits<double>
вместоnumberic_limits<double>
1
вstd::numeric_limits<double>::digits10
?max_digits10
вместо C + 11 . Смотрите это .max_digits10
, а не произвольноdigits10+2
. В противном случае, в случаеfloat
,long double
,boost::multiprecision::float128
это не получится , так как вы должны были бы+3
вместо+2
.Путь iostreams довольно неуклюж. Я предпочитаю использовать,
boost::lexical_cast
потому что он рассчитывает правильную точность для меня. И это тоже быстро .Вывод:
источник
Под полной точностью я предполагаю достаточную точность, чтобы показать наилучшее приближение к предполагаемому значению, но следует указать, что
double
оно хранится с использованием представления базы 2, а база 2 не может представлять что-то столь же тривиальное, как1.1
точное. Единственный способ получить полную-полную точность фактического двойного значения (без NO ROUND OFF ERROR) - это распечатать двоичные биты (или шестнадцатеричные биты). Один из способов сделать это - записать вdouble
a,union
а затем распечатать целочисленное значение битов.Это даст вам 100% точность двойного ... и будет совершенно нечитаемым, потому что люди не могут читать двойной формат IEEE! В Википедии есть хорошая статья о том, как интерпретировать двоичные биты.
В более новом C ++ вы можете сделать
источник
Вот как отобразить двойной с полной точностью:
Это отображает:
max_digits10 - количество цифр, необходимое для уникального представления всех различных двойных значений. max_digits10 представляет количество цифр до и после десятичной точки.
Не используйте set_precision (max_digits10) с std :: fixed.
В фиксированной записи set_precision () устанавливает количество цифр только после десятичной точки. Это неверно, так как max_digits10 представляет количество цифр до и после десятичной точки.
Это отображает неверный результат:
Примечание. Требуются заголовочные файлы.
источник
100.0000000000005
не представляется точно какdouble
. (Может показаться, что так и должно быть, но это не так, потому что он нормализуется , т.е. его двоичное представление). Чтобы убедиться в этом, попробуйте:100.0000000000005 - 100
. Мы получаем4.973799150320701e-13
.Используйте
hexfloat
илииспользуйте
scientific
и установите точностьСлишком много ответов касаются только одного из 1) основ 2) фиксированной / научной схемы или 3) точности. Слишком много ответов с точностью не дают нужного значения. Отсюда и ответ на старый вопрос.
A
double
, безусловно, кодируется с использованием базы 2. Прямой подход к C ++ 11 заключается в печати с использованиемstd::hexfloat
.Если не десятичный вывод приемлем, мы закончили.
fixed
илиscientific
?A
double
- это тип с плавающей запятой , а не с фиксированной запятой .Как не использовать ,
std::fixed
как это не удается напечатать маленький ,double
как угодно , но0.000...000
. В целомdouble
он печатает много цифр, возможно, сотни сомнительной информативности.Для печати с полной точностью сначала используйте команду,
std::scientific
которая будет «записывать значения с плавающей запятой в научной нотации». Обратите внимание, что по умолчанию 6 цифр после десятичной точки, недостаточное количество, обрабатывается в следующей точке.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
:а) Используйте
N
так при преобразовании изdouble
текстового текста мы получаем один и тот же текст для всехdouble
.б) Используйте
N
так при преобразовании изdouble
-text-,double
мы получаем то же самоеdouble
для всехdouble
.Когда
max_digits10
недоступно, обратите внимание, что из-за атрибутов base 2 и base 10digits10 + 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
.Подобный C вопрос
источник
precision()
устанавливая количество знаков после запятой для научного режима. Без указанияscientific
он устанавливает общее количество цифр, исключая показатель степени. Вы все равно можете получить научный вывод, в зависимости от вашего числового значения, но тогда вы также можете получить меньше цифр, чем вы указали. Пример:cout.precision(3); cout << 1.7976931348623158e+308; // "1.8e+308"
результатыprintf
могут быть разными. Непонятные вещи, которые следует знать.char buf[DBL_DECIMAL_DIG + 3 + 5]; sprintf(buf, "%.*g", DBL_DECIMAL_DIG, d);
дополнительные символы для: знак, десятичная точка, завершающий ноль, e [+ | -], 3 цифры для показателя степени ( DBL_MAX_10_EXP = 308). Следовательно, общее количество необходимых символов - 25.% .12f означает с плавающей запятой с точностью до 12 цифр.
источник
Наиболее переносимо ...
источник
С ostream :: precision (int)
даст
Почему вы должны сказать «+1», я понятия не имею, но дополнительная цифра, которую вы получаете из этого, правильна.
источник
Это покажет значение до двух десятичных знаков после точки.
Смотрите здесь: Запись с фиксированной точкой
станд :: фиксированной
станд :: setprecision
Если вы знакомы со стандартом IEEE для представления чисел с плавающей запятой, вы должны знать, что невозможно вывести числа с плавающей запятой с полной точностью вне области действия стандарта , то есть это всегда приведет к округление реальной стоимости.
Вы должны сначала проверить, находится ли значение в области , если да, тогда используйте:
станд :: defaultfloat
Это также поведение по умолчанию
cout
, что означает, что вы не используете его явно.источник