Как преобразовать число с плавающей запятой в строку в C ++, указав точность и количество десятичных цифр?
Например: 3.14159265359 -> "3.14"
Как преобразовать число с плавающей запятой в строку в C ++, указав точность и количество десятичных цифр?
Например: 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флаг формата для потока str равнымfixed.Если
floatfieldзадано значениеfixed, значения с плавающей запятой записываются с использованием записи с фиксированной запятой: значение представляется с точно таким количеством цифр в десятичной части, как указано в поле точности (precision), и без экспоненты.
Для преобразований технического назначения , таких как хранение данных в файле 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бы лучше в этом случае? Пожалуйста, объясните ... Это, конечно, не будет быстрее, меньше кода [Я написал реализацию 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, который похож на printfs, но используется в {}качестве разделителей вместо %.
Здесь решение, использующее только 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();
}