Convert Float to Std::String in C++

Convert float to std::string in C++

Unless you're worried about performance, use string streams:

#include <sstream>
//..

std::ostringstream ss;
ss << myFloat;
std::string s(ss.str());

If you're okay with Boost, lexical_cast<> is a convenient alternative:

std::string s = boost::lexical_cast<std::string>(myFloat);

Efficient alternatives are e.g. FastFormat or simply the C-style functions.

How to simply convert a float to a string in c?

The second parameter is the format string after which the format arguments follow:

fprintf(fPointer, "%f", amount);

%f tells fprintf to write this argument (amount) as string representation of the float value.

A list of possible format specifiers can (for example) be found here.

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.

How to speed up this code when converting float to string?

If using an external library to achieve this goal is possible, you can go with fmtlib (this library will probably make it into the standard), which claims to be faster than other approaches (see their benchmarks).

#include <fmt/format.h>

std::string FloatToScientificString(float val, int width, int precision)
{
return fmt::format("{:>{}.{}e}", val, width, precision);
}

This should return an identical string as your original function, and you don't sacrifice type safety as with std::*printf approaches. When using abseil instead (they claim to be notably faster than the printf-family here), the function looks like this:

#include <absl/strings/str_format.h>

std::string FloatToScientificString(float val, int width, int precision)
{
return absl::StrFormat("%*.*e", width, precision, val);
}

There is also boost format, which does not allow for width or precision specifier to be passed as arguments, but this works equally well:

#include <boost/format.hpp>

std::string FloatToScientificString(float val, int width, int precision)
{
const std::string fmt = "%" + std::to_string(width) + "." +
std::to_string(precision) + "e";

return boost::str(boost::format(fmt) % val);
}

and finally, without any external dependencies other than the standard library (note that using std::snprintf is superior to std::sprintf as the buffer size is checked, but neither function is type safe):

#include <cstdio>

std::string FloatToScientificString(float val, int width, int precision)
{
static const int bufSize = 100;
static char buffer[bufSize];

std::snprintf(buffer, bufSize, "%*.*e", width, precision, val);

return std::string(buffer);
}

A correct performance analysis of these options is probably a topic on its own. Any of these options should be notably faster than the original approach using std::stringstream, though, and all snippets except the std::snprintf one are type safe.

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 to fixed.

When floatfield is set to fixed, 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
}

I have an issue converting a float variable into a string in C++

strlen() is for calculating length of C-style string.

To obtain the length of std::string, you should use the size() or length() member function.

cout<<threshold.length()<<endl;

In case you want to stick to use strlen(), you can use c_str() member function to obtain C-style string from std::string.

cout<<strlen(threshold.c_str())<<endl;

Converting a float to string in a subroutine in C

You're trying to use sprintf to write data to a char. Look at the declaration of the sprintf function, as your compiler suggests:

int sprintf(char*, const char*, ...)

It takes a char* as first argument, that is: a pointer to a buffer where to store the formatted string that is generated.

You should use it like this (please pay attention to all the changes I made):

// Return the allocated buffer, which is char*, not char.
char *test_subroutine(float x,float y)
{
float a=105.252342562324;
float b=108.252234256262;
float d;
float e;

char *var = malloc(100); // Allocate a buffer of the needed size.

d=x*a;
e=y*b;

sprintf(var,"%0.2f %0.2f",d,e); // Sprintf to that buffer

return var;
}

int main()
{
char *variable;
variable = test_subroutine(2.5,3.5);
free(variable); // Free the buffer allocated by test_subroutine()
}

C++ How do I format a float with std::string?

Found a way using stringstream :) Then it uses the default ostream float format and pushes it to a string :)

std::stringstream ss;
std::string s;
ss << 3.4;
ss >> s;
std::cout << s.append("f") << std::endl;

generates the following output:

3.4f

Convert float to string with precision and without tolerance

The problem is that you're using a float data type which only has a precision of at most 7.22 total digits and sometimes as little as 6 digits, and you're trying to display 8 total digits (2 before the decimal and 6 after). As noted in the comments, the closest possible binary float to 40.432 is 40.43199920654296875, the second closest would be 40.432003021240234375.

You can get more digits by converting to the larger double type. Once you've done that you can round to the nearest 6-digit number. Note that if the float was generated by a calculation, rounding may actually create a less accurate result.

If you always know your numbers will be between 10 and 100, this simple code will work. Otherwise you'll need a more complex process to determine the appropriate amount of rounding.

float f = 40.432;
double d = f;
double r = std::round(d * 10000.0) / 10000.0; // 2 digits before the decimal, 4 after
std::cout << std::fixed << std::setprecision(6) << r;

Note that the last 2 digits will always be zero because of the rounding.

See it in action: http://coliru.stacked-crooked.com/a/f085e56c03ebeb73



Related Topics



Leave a reply



Submit