Set precision of std::to_string when converting floating point values
There is no way to change the precision via to_string()
but the setprecision
IO manipulator could be used instead:
#include <sstream>
template <typename T>
std::string to_string_with_precision(const T a_value, const int n = 6)
{
std::ostringstream out;
out.precision(n);
out << std::fixed << a_value;
return out.str();
}
The precision of std::to_string(double)
No.
Returns: Each function returns a string object holding the character representation of the value of
its argument that would be generated by callingsprintf(buf, fmt, val)
with a format specifier of"%d"
,"%u"
,"%ld"
,"%lu"
,"%lld"
,"%llu"
,"%f"
,"%f"
, or"%Lf"
, respectively, where buf designates
an internal character buffer of sufficient size.
How to use std::to_string function to format float as “x.0”
std::to_string
doesn't support this, and in fact is not generally great for arbitrary floating-point values.
Since your question is tagged c++11, there are two ways I'm aware of. Firstly, you have std::stringstream
, which is type safe and will work with arbitrary types:
#include <sstream>
// ...
float number = 30.0f;
std::ostringstream oss;
oss << std::setprecision(1) << number;
std::string result = oss.str();
Alternatively, you have std::snprintf
, which requires converting through a char
buffer of a given size:
float number = 30.0f;
char buffer[20]; // maximum expected length of the float
std::snprintf(buffer, 20, "%.1f", number);
std::string str(buffer);
From C++17 you may use std::to_chars
instead in a similar way to std::snprintf
, and from C++20 you may use std::format
.
How to avoid `std::to_string()` making a very small double number to 0?
No, the problem is not precision, but the format. You want to print in scientific format (with exponent) but std::to_string()
uses the fixed format by default and I'm not aware of any way to change this.
However, streams use scientific if appropriate or you can force it with std::scientific
:
std::ostringstream oss;
oss << 4.7816457028269855e-143;
std::string numberAsString = oss.str(); // stores "4.78165e-143"
Of course you can increae the precision in addition to this.
If for whatever reason you don't want to use scientific format, you can use the fixed format with a high enough precision. "High enough" meaning more than 142 in this case, because there will be 142 leading zeroes:
oss << std::fixed << std::setprecision(142 + x);
But the scientific format is better suited, I guess.
Loss of Precision when Converting Double to String in C++
You can use std::stringstream
.
#include <iostream>
#include <sstream>
#include <iomanip>
using namespace std;
int main(void) {
double var = 1.0000001;
cout << setprecision(10)<< var << endl;
stringstream ss;
ss << setprecision(10) << var;
string str;
ss >> str;
cout << str << endl;
return 0;
}
C++11 std::to_string(double) - No trailing zeros
The C++11 Standard explicitely says (21.5/7
):
Returns: Each function returns a string object holding the character representation of the value of its argument that would be generated by calling sprintf(buf, fmt, val) with a format specifier of "%d", "%u", "%ld", "%lu", "%lld", "%llu", "%f", "%f", or "%Lf", respectively, where buf designates an internal character buffer of sufficient size
for the functions declared in this order:
string to_string(int val);
string to_string(unsigned val);
string to_string(long val);
string to_string(unsigned long val);
string to_string(long long val);
string to_string(unsigned long long val);
string to_string(float val);
string to_string(double val);
string to_string(long double val);
Thus, you cannot control the formatting of the resulting string.
Convert float to std::string without losing precision. Also I don't want to use sprintf
I suggest you call snprintf
with format specifier "%.16g"
- that prints a double
in decimal with 16 significant digits of precision. See Number of Digits Required For Round-Trip Conversions for more details. E.g.:
inline std::string as_string(double value) {
char buf[32];
return std::string(buf, std::snprintf(buf, sizeof buf, "%.16g", value));
}
*printf
functions are fundamental conversion routines, everything else uses these.
std::to_string
in GNU C++ standard library does:
inline string to_string(double __val) {
const int __n = __gnu_cxx::__numeric_traits<double>::__max_exponent10 + 20;
return __gnu_cxx::__to_xstring<string>(&std::vsnprintf, __n, "%f", __val);
}
std::ostream
also calls *snprintf
under the hood to format numbers.
Also note that 3.14159267
is double
. A float
constant requires f
suffix, e.g. 3.14159267f
.
Convert float to string with precision & number of decimal digits specified?
A typical way would be to use stringstream
:
#include <iomanip>
#include <sstream>
double pi = 3.14159265359;
std::stringstream stream;
stream << std::fixed << std::setprecision(2) << pi;
std::string s = stream.str();
See fixed
Use fixed floating-point notation
Sets the
floatfield
format flag for the str stream tofixed
.When
floatfield
is set tofixed
, floating-point values are written using fixed-point notation: the value is represented with exactly as many digits in the decimal part as specified by the precision field (precision
) and with no exponent part.
and setprecision.
For conversions of technical purpose, like storing data in XML or JSON file, C++17 defines to_chars family of functions.
Assuming a compliant compiler (which we lack at the time of writing),
something like this can be considered:
#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
}
double to std::string with dynamic precisicion (without trailing zeros)
You can use string stream (sstring) with stream manipulators, see example below:
std::stringstream ss1;
std::stringstream ss2;
ss1.precision(15);
ss1 << 3.14;
std::cout << ss1.str()<<' '<<("3.14" == ss1.str())<<std::endl;
ss2.precision(15);
ss2 << 3.1415926536;
std::cout << ss2.str()<<' '<<("3.1415926536" == ss2.str())<<std::endl;
Or you can use boost format. Here's a link!
std::cout<<format("%.2f") % 3.14 <<std::endl;
std::cout<<format("%.10f") % 3.1415926536 <<std::endl;
Related Topics
Console Output in a Qt Gui App
Significance of Parentheses in Decltype((C))
Openmp Set_Num_Threads() Is Not Working
Where Are C/C++ Main Function's Parameters
What Is Dynamic Initialization of Object in C++
Reinterpret_Cast VS. C-Style Cast
What Are the Differences Between Overriding Virtual Functions and Hiding Non-Virtual Functions
Will Casting Around Sockaddr_Storage and Sockaddr_In Break Strict Aliasing
C++ Filehandling: Difference Between iOS::App and iOS::Ate
In C++11, Does 'I += ++I + 1' Exhibit Undefined Behavior
C++ Efficiently Calculating a Running Median
Pure Virtual Functions May Not Have an Inline Definition. Why
Implementing Multiple Interfaces in C++
When Does Opengl Get Finished with Pointers in Functions
Super High Performance C/C++ Hash Map (Table, Dictionary)