Convert a number from stringstream to string with a set precision - c++

I would like to obtain a number from stringstream and set it to 5 significant figures. How do I do this? So far, this is what I have managed to come up with:
double a = 34.34566535
std::stringstream precisionValue;
precisionValue.precision(6) << a << std::endl;
However, this is not compiling. Thanks.

It doesn't compile because ios_base::precision() returns streamsize (it's an integral type).
You can use stream manipulators:
precisionValue << std::setprecision(6) << a << std::endl;
You'll need to include <iomanip>.

std::stringstream::precision() returns a streamsize, not a reference to the stream itself, which is required if you want to sequence << operators. This should work:
double a = 34.34566535;
std::stringstream precisionValue;
precisionValue.precision(6);
precisionValue << a << std::endl;

The precision member function returns current precision, not a reference to the stringstream, so you cannot chain the calls as you've done in the snippet.
precisionValue.precision(6);
precisionValue << a;
std::cout << precisionValue.str() << std::endl;
Or use the setprecision IO manipulator to chain the calls:
precisionValue << setprecision(6) << a;
std::cout << precisionValue.str() << std::endl;

You can use std::setprecision from header <iomanip>
#include <string>
#include <sstream>
#include <iomanip>
#include <iostream>
int main()
{
double a = 34.34566535;
std::stringstream precisionValue;
precisionValue << std::setprecision(6);
precisionValue << a << std::endl;
std::cout << precisionValue.str();
}

Related

How to remove trailing zeros with scientific notation when convert double to string?

Live On Coliru
FormatFloat
I try to implement one conversion of Golang strconv.FormatFloat() in C++.
#include <sstream>
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
std::string convert_str(double d)
{
std::stringstream ss;
if (d >= 0.0001)
{
ss << std::fixed << std::setprecision(4); // I know the precision, so this is fine
ss << d;
return ss.str();
}
else
{
ss << std::scientific;
ss << d;
return ss.str();
}
}
int main()
{
std::cout << convert_str(0.002) << std::endl; // 0.0020
std::cout << convert_str(0.00001234560000) << std::endl; // 1.234560e-05
std::cout << convert_str(0.000012) << std::endl; // 1.200000e-05
return 0;
}
Output:
0.0020
1.234560e-05 // should be 1.23456e-05
1.200000e-05 // should be 1.2e-05
Question> How can I setup the output modifier so that the trailing zero doesn't show up?
strconv.FormatFloat(num, 'e', -1, 64)
The special precision value (-1) is used for the smallest number of
digits necessary such that ParseFloat() will return f exactly.
At the risk of being heavily downvoted criticised for posting a C answer to a C++ question ... you can use the %lg format specifier in a call to sprintf.
From cpprefernce:
Unless alternative representation is requested the trailing zeros are
removed, also the decimal point character is removed if no fractional
part is left.
So, if you only want to remove the trailing zeros when using scientific notation, you can change your convert_str function to something like the following:
std::string convert_str(double d)
{
if (d >= 0.0001) {
std::stringstream ss;
ss << std::fixed << std::setprecision(4); // I know the precision, so this is fine
ss << d;
return ss.str();
}
else {
char cb[64];
sprintf(cb, "%lg", d);
return cb;
}
}
For the three test cases in your code, this will give:
0.0020
1.23456e-05
1.2e-05
From C++20 and later, the std::format class may offer a more modern alternative; however, I'm not (yet) fully "up to speed" with that, so I cannot present a solution using it. Others may want to do so.
Yes, std::scientific don't remove trailing zeros from scientific notation. The good news, for your specific case, is that cout already format values below 0.0001 using scientific notation, and removing trailing zeros. So you can let your code like this:
#include <sstream>
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
std::string convert_str(double d)
{
std::stringstream ss;
if (d >= 0.0001)
{
ss << std::fixed << std::setprecision(4); // I know the precision, so this is fine
ss << d;
return ss.str();
}
else
{
ss << d;
return ss.str();
}
}
int main()
{
std::cout << convert_str(0.002) << std::endl; // 0.0020
std::cout << convert_str(0.00001234560000) << std::endl; // 1.23456e-05
std::cout << convert_str(0.000012) << std::endl; // 1.2e-05
return 0;
}
The wanted output can be generated with a combination of the std::setprecision and std::defaultfloat manipulators:
std::cout << std::setprecision(16) << std::defaultfloat
<< 0.002 << '\n'
<< 0.00001234560000 << '\n'
<< 0.000012 << '\n';
Live at: https://godbolt.org/z/67fWa1seo

Printing an 8-bit number in hexadecimal with IO manipulators

I have a uint8_t and want to convert it to a two-digit hex string in C++ in the same way that the format string %02x would.
To do this, I've enlisted the help of a stringstream and IO manipulators to configure how the stream should format numbers:
#include <iomanip>
#include <iostream>
#include <sstream>
int main()
{
uint8_t x = 3;
std::cout << std::hex << std::setw(2) << std::setfill('0')
<< x << std::endl;
return 0;
}
So this should print 03 right? No, it prints 0.
Your Standard Libraries implementation of <cstdint> (btw. ... you didn't include it and uint8_t is in the namespace std) uses a typedef for uint8_t:
namespace std {
// ...
typedef char unsigned `uint8_t`
// ...
};
so std::ostream interprets it as character, not as an integer type. To make sure it gets interpreted as an integer just cast it explicitly:
#include <cstdint>
#include <iomanip>
#include <iostream>
int main()
{
std::uint8_t x{ 3 };
std::cout << std::hex << std::setw(2) << std::setfill('0')
<< static_cast<int>(x) << '\n';
}
Actually, it prints 0\0x03. That's right, it interprets the variable x as a character, not as a number.
The correct way to do this is to use the unary plus operator:
std::cout << std::hex << std::setw(2) << std::setfill('0')
<< +x << std::endl;

C++ stream iomanip equivalent to sprintf "%5.3f"

I am trying to convert an sprintf statement into C++ stream statement.
The sprintf formatting statement I am trying to replicate is "%5.3f"
I am using namespace std and have included and
I have:
double my_double = GetMyDoubleFromSomewhere();
stringstream ss;
ss << ??? << my_double;
I have been looking at the fixed and setprecision, but can't quite figure out how to set the 5 and the 3 of the original formatting specifier?
setprecision and setw would help you.
Don't forget including iomanip
#include <iostream>
#include <iomanip>
#include <stdio.h>
int main(void) {
using namespace std;
double target = 1.2345;
cout << fixed << setw(5) << setprecision(3) << target << endl;;
printf("%5.3f\n", target);
}
You want to use the io manipulators std::setw and std::setprecision, something like:
ss << std::setw(5) << std::setprecision(3) << my_double;

c++ String is shortening double when printing

This string operation prints out a double in short-hand, and I can't work out why. Why is this happening, and how can I get the full output like the first line of output?
string myString = "The value is ";
ss.str(""); // stringstream from ealier
ss.clear();
ss << myDouble; // Double with value 0.000014577
myString.append(ss.str());
cout << myDouble << endl;
cout << myString << endl;
$ ./myapp
0.000014577
The value is 1.4577e-05
its default behaviour you should use precision to use fixed precision
#include <string>
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
double v = 0.000014577;
cout << fixed << v << endl;
}
Try this:
using std::fixed;
...
ss.setf(fixed);
ss << myDouble;
...
That is because this is the default formatting, you can override it with precision.

how to format out in c++?

I know how to use printf() to format output of float, for example:
float i = 1;
printf("%.2f", i);
but how to format the output using cout to output 2 digits after "."?
Following will do:
std::cout<<std::fixed<<std::setprecision(2)<<i;
You will also need to include iomanip
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
cout << setprecision(2) << setiosflags(ios::fixed) << 3.141592 << endl;
}
use setprecision().
A red herring is to use std::setprecision on its own:
float f = 3.1415;
std::cout << std::setprecision(2) << f;
However, "precision" is not the same as "number of decimal places", as shown in this example.
Fortunately, and somewhat confusingly, switching the stream to "fixed-point" display changes the meaning of std::setprecision to something more akin to "setDecimalPlaces".
So, you can write this:
float f = 3.1415;
std::cout << std::fixed << std::setprecision(2) << f;
Boost format helps:
std::cout << boost::format("%.2f") % i;
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
double x = 800000.0/81.0;
cout << setiosflags(ios::fixed) << setprecision(2) << x;
return 0;
}
hope this helps.........
#include <iostream>
#include <iomanip>
using namespace std;
int main () {
double f =3.14159;
cout << setprecision (5) << f << endl;
cout << setprecision (9) << f << endl;
cout << fixed;
cout << setprecision (5) << f << endl;
cout << setprecision (9) << f << endl;
return 0;
}
output..
> 3.1416
> 3.14159
> 3.14159
> 3.141590000
cout << ffmt(0, 2) << i;
Where ffmt is defined as:
class ffmt
{
int width;
int precision;
public:
ffmt( int width, int precision )
: width( width )
, precision( precision )
{
}
friend std::ostream& operator<<(
std::ostream& dest,
ffmt const& manip )
{
dest.setf( std::ios_base::fixed, std::ios_base::floatfield );
dest.width( width );
dest.precision( precision );
}
};
You can also extend this to restore format state at the end of the full
expression; it's not too important for floating point, because most of
the time, you'll use the manipulator in front of each output, but a
manipulator which leaves the stream outputting hex is likely to lead to
surprising output later.
As a general rule, except for quicky demo or test programs, you almost
never use the standard manipulators, other that std::setw. For that
matter, in a lot of applications, you'll even avoid things like ffmt,
in favor of specific manipulators for each semantic value you have.