Как преобразовать число с плавающей запятой в строку в C ++, указав точность и количество десятичных цифр?
Например: 3.14159265359 -> "3.14"
c++
string
floating-point
Шеннон Мэтьюз
источник
источник
Ответы:
Типичный способ - использовать
stringstream
:#include <iomanip> #include <sstream> double pi = 3.14159265359; std::stringstream stream; stream << std::fixed << std::setprecision(2) << pi; std::string s = stream.str();
Смотрите исправленные
и установите точность .
Для преобразований технического назначения , таких как хранение данных в файле XML или JSON, C ++ 17 определяет семейство функций to_chars .
Предполагая совместимый компилятор (которого нам не хватало на момент написания), можно рассмотреть что-то вроде этого:
#include <array> #include <charconv> double pi = 3.14159265359; std::array<char, 128> buffer; auto [ptr, ec] = std::to_chars(buffer.data(), buffer.data() + buffer.size(), pi, std::chars_format::fixed, 2); if (ec == std::errc{}) { std::string s(buffer.data(), ptr); // .... } else { // error handling }
источник
Обычный метод для этого - «печать в строку». В C ++ это означает использование
std::stringstream
чего-то вроде:std::stringstream ss; ss << std::fixed << std::setprecision(2) << number; std::string mystring = ss.str();
источник
Другой вариант
snprintf
:double pi = 3.1415926; std::string s(16, '\0'); auto written = std::snprintf(&s[0], s.size(), "%.2f", pi); s.resize(written);
Демо . Следует добавить обработку ошибок, т.е. проверку
written < 0
.источник
snprintf
бы лучше в этом случае? Пожалуйста, объясните ... Это, конечно, не будет быстрее, меньше кода [Я написал реализацию printf, он довольно компактен и содержит чуть меньше 2000 строк кода, но с расширениями макросов достигает примерно 2500 строк]__printf_fp
функциональность - довольно странно, что это занимает так много времениstringstream
, как это действительно не должно быть.Вы можете использовать
fmt::format
функцию из библиотеки {fmt} :#include <fmt/core.h> int main() std::string s = fmt::format("{:.2f}", 3.14159265359); // s == "3.14" }
где
2
точность.Это средство форматирования было предложено для стандартизации в C ++: P0645 . И P0645, и {fmt} используют синтаксис строки формата, подобный Python, который похож на
printf
s, но используется в{}
качестве разделителей вместо%
.источник
Здесь решение, использующее только std. Однако обратите внимание, что это только округление.
float number = 3.14159; std::string num_text = std::to_string(number); std::string rounded = num_text.substr(0, num_text.find(".")+3);
Ибо
rounded
дает:3.14
Код преобразует все число с плавающей запятой в строку, но вырезает все символы через 2 символа после "."
источник
number + 0.005
в моем случае.Здесь я привожу отрицательный пример, когда вы хотите избежать преобразования числа с плавающей запятой в строки.
float num=99.463; float tmp1=round(num*1000); float tmp2=tmp1/1000; cout << tmp1 << " " << tmp2 << " " << to_string(tmp2) << endl;
Вы получаете
99463 99.463 99.462997
Примечание: переменная num может иметь любое значение, близкое к 99,463, вы получите такую же распечатку. Дело в том, чтобы избежать удобной функции C ++ 11 "to_string". Мне потребовалось время, чтобы выбраться из этой ловушки. Лучше всего использовать методы stringstream и sprintf (язык C). C ++ 11 или новее должен предоставлять второй параметр в виде количества отображаемых цифр после плавающей запятой. Сейчас по умолчанию 6. Я утверждаю это, чтобы другие не тратили время на эту тему.
Я написал свою первую версию, дайте мне знать, если вы обнаружите ошибку, которую необходимо исправить. Вы можете контролировать точное поведение с помощью иоманипулятора. Моя функция - показать количество цифр после десятичной точки.
string ftos(float f, int nd) { ostringstream ostr; int tens = stoi("1" + string(nd, '0')); ostr << round(f*tens)/tens; return ostr.str(); }
источник