Я хочу преобразовать значение double
в std::string
. В настоящее время я пишуdouble to std :: string with dynamic precisicion (без конечных нулей)
return std::to_string(double_value);
Но это только возвращает 7 цифр, потому что внутренне to_string()
просто использует std::vsnprintf
с форматом %f
спецификатора (смотри также here).
Теперь я могу просто позвонить std::vsnprintf
с помощью %.15f
в качестве спецификатора формата, но это приведет к завершающим нулям.
My (в моих глазах очень очевидно) цель сейчас иметь такой подход, как это:
string o1 = to_string(3.14)
string o2 = to_string(3.1415926536)
assert(o1 == "3.14")
assert(o2 == "3.1415926536")
Here является хорошей разработкой на подрезки завершающих нулей из %.20
выхода, но этот ответ около 8 лет ,
Возможно, все изменилось? Можно ли преобразовать double
с двойной точностью без конечных нулей в C++ сегодня?
Решение:
Основываясь на 2man сек ответ вы можете написать обобщенную функцию следующим образом:
template<typename T>
inline std::string tostr(T value) {
std::ostringstream s;
s.precision(std::numeric_limits<T>::digits10);
s << value;
return s.str();
}
, который ведет себя, как требуется для числовых типов. Обратите внимание, что я взял digits10
, а не max_digits10
в пользу хороший десятичное представление, а не более цифр и задней ..0000001
Также ИМХО стоит добавить, что [v][s][n]printf()
вместе с форматом строки «% +0,15 г» (а не " f ') также будет обрезать конечные нули (не будет работать с большим количеством цифр, потому что они не могут быть представлены с 64 бит, что приведет к вещам вроде «1», например, 3.12 -> «3.1200000000000001»)
Still странный:
Может быть, кто-то может мне сказать, почему std::to_string(double)
, который был введен с C++ - 11 жесткими кодами для vsnprintf(..., "%f", ...)
, а не чем-то вроде vsnprintf("%.15g")
, что приведет к более точному представлению без влияния на код C?
Одна хорошая вещь о C заключается в том, что она * чрезвычайно * обратная совместимость. То, что код C в связанном ответе составляет восемь лет, не имеет значения, он все равно будет работать, и ничто релевантное не изменилось со стандартом C11. Не следует также переводить на C++. Без чего-то подобного это невозможно, если вы действительно не знаете количество значащих цифр заранее. –
Неважно, 8 лет или восемь часов: хороший код - хороший код. (Кроме того, это C++ ... Это не сильно меняется). – Ellis
Как вы планируете обрабатывать округление с плавающей запятой? Я попытался сделать что-то простое добавление символов в строку, но '3.14' может быть не точно« 3.14 »при сохранении в памяти. Без ограничения цифр вы можете получить '2.12000000005', если хотите' 2.12'. – Matt