Как вы конвертируете float в строку на С++, указав точность и количество десятичных цифр?
Например: 3.14159265359 -> "3.14"
Как вы конвертируете float в строку на С++, указав точность и количество десятичных цифр?
Например: 3.14159265359 -> "3.14"
Типичным способом было бы использовать stringstream
:
#include <iomanip>
#include <sstream>
double pi = 3.14159265359;
std::stringstream stream;
stream << std::fixed << std::setprecision(2) << pi;
std::string s = stream.str();
Смотрите исправлено
Используйте фиксированную запись с плавающей точкой
Устанавливает
floatfield
флаг формата для потока, чтобы улfixed
.Если для
floatfield
с плавающей запятой заданоfixed
, значения с плавающей запятой записываются с использованием записи с фиксированной запятой: значение представляется с точно таким количеством цифр в десятичной части, которое указано в полеprecision
(precision
), и без экспоненты.
Для преобразований технического назначения, таких как хранение данных в файле XML или JSON, С++ 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
}
Обычным методом для выполнения такого рода является "print to string". В С++ это означает использование 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
.
Вы можете использовать функцию 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
но вместо %
использует {}
качестве разделителей.
Здесь я предоставляю отрицательный пример, где вы хотите избежать при преобразовании числа с плавающей точкой в строки.
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, вы получите тот же распечаток. Дело в том, чтобы избежать удобной функции С++ 11 "to_string". Мне потребовалось некоторое время, чтобы выбраться из этой ловушки. Лучший способ - методы stringstream и sprintf (язык C). С++ 11 или newer должен предоставить второй параметр в виде числа цифр после показания плавающей запятой. Сейчас по умолчанию - 6. Я полагаю, что другие не будут тратить время на эту тему.
Я написал свою первую версию, сообщите мне, если вы найдете какую-либо ошибку, которая должна быть исправлена. Вы можете контролировать точное поведение с помощью iomanipulator. Моя функция предназначена для отображения числа цифр после десятичной точки.
string ftos(float f, int nd) {
ostringstream ostr;
int tens = stoi("1" + string(nd, '0'));
ostr << round(f*tens)/tens;
return ostr.str();
}