формат boost устанавливает максимальную точность с плавающей запятой

#c #boost #boost-format

#c #boost #boost-format

Вопрос:

По сути, у меня есть следующее:

 typedef TFp double;
boost::format fmt("Floating point: %2$f");
TFp v = 0.000000001;
fmt % v;
std::cout << fmt.str();
  

Согласно руководству по формату boost, по умолчанию выводится 6 цифр точности, поэтому отображается 0.000000, что мои пользователи интерпретируют как 0 (и я даже не могу винить их за то, что они так думают). Я мог бы изменить свою строку формата и добавить точку, а затем число после знака доллара, чтобы зафиксировать количество цифр, но это число может варьироваться в зависимости от того, насколько велико значение в float, и из-за некоторых особенностей моего кода typedef, который у меня есть в моем примере (для double), иногда является float, поэтому тогда мне снова пришлось бы использовать другое число в моей строке формата.

В основном я ищу способ сообщить boost format ‘дайте мне столько цифр, сколько необходимо, чтобы показать значение любого типа с плавающей запятой, но не больше (т. Е., когда значение равно 0.003, оно не должно печатать 0.003000 или что-то еще).

Я бы подумал, что это очевидная вещь, и мне потребовалось дважды очень внимательно прочитать документацию, чтобы выяснить, что это не значение по умолчанию (на что намекают в некоторых местах), но я не могу найти способ это сделать.

Ответ №1:

Я не думаю, что это возможно с f спецификатором формата, потому что последний всегда выдает конечные нули. Однако вы могли бы использовать g спецификатор и точность 17 для double , которые удалят конечные нули и не потеряют точность (при условии IEE754 double ). Это имеет неприятный побочный эффект, заключающийся в том, что в некоторых случаях получается больше цифр, чем необходимо, например, 0.1 будет отформатировано как 0.10000000000000001 .

Если вы не ограничены форматом Boost, то вы могли бы использовать средство форматирования, которое дает вам наименьшее десятичное представление. Например, библиотека {fmt} делает это по умолчанию:

 auto s1 = fmt::format("{}", 0.000000001);
// s1 == "1e-9"
auto s2 = fmt::format("{}", 0.1);
// s2 == "0.1"
  

Отказ от ответственности: Я автор {fmt}.