Строковый поток setprecision и форматирование с плавающей запятой

double value = 02369.000133699;//acutally stored as 2369.000133698999900
const std::uint32_t left = std::uint32_t(std::abs(value) <  1 ? 1: (1 + std::log10(std::abs(value))));

std::ostringstream out;
out << std::setprecision(std::numeric_limits<T>::digits10 - left ) << std::fixed << value;
std::string str = out.str(); //str = "2369.00013369900"
std::ostringstream out2;
out2 << std::setprecision(std::numeric_limits<T>::digits10 ) << std::fixed << value;
std::string str2 = out2.str(); // str2 = "2369.000133698999900"

Мне интересно, как std :: stringstream / precision работает для форматирования чисел с плавающей точкой.
Кажется, что если аргумент точности превосходит 16 минус количество не дробных цифр, это приводит к форматированию формы "2369.000133698999900" вместо «приятно» "2369.00013369900"

как std::stringstream знать, что 8999900 должно быть резюме к одному 9 даже если я не скажу это сделать округление на 8 (как прохождение 12 в качестве аргумента setprecision функция)? но не делайте этого для аргумента выше 12

2

Решение

Форматирование двоичных чисел с плавающей точкой как десятичных значений довольно сложно. Основная проблема заключается в том, что двоичные числа с плавающей запятой не могут точно представлять десятичные значения. Даже простое число, такое как 0,1, не может быть точно представлено с помощью двоичных чисел с плавающей запятой. То есть фактическое значение немного отличается. При использовании умных алгоритмов для чтения («Bellerophon») и форматирования («Dragon4»; это имена из оригинальных статей и есть усовершенствования обоих алгоритмов, которые используются на практике), числа с плавающей запятой используются для переноса десятичных значений. Однако при запросе алгоритма отформатировать больше десятичных цифр, чем он может содержать, т. Е. Больше, чем std::numeric_limits<T>::digits10, он с радостью сделает это, [частично] раскрывая ценность, которую он на самом деле хранит.

Алгоритм форматирования («Dragon4») предполагает, что заданное значение является значением, наиболее близким к исходному представлению с типом с плавающей запятой. Он использует эту информацию вместе с оценкой ошибки для текущей позиции, чтобы определить правильные цифры. Сам алгоритм нетривиален, и я не до конца понял, как он работает. Это описано в статье «Как печатать числа с плавающей запятой точно» Гая Л. Стила-младшего и Джона Л. Уайта.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]