I'm trying to convert a double number to a std::string, the conversion should print either in the decimal format with 2 decimal digits or in the exponential form:
1 -> 1.00
0.1 -> 0.10
0.01 -> 0.01
0.015 -> 1.5e-2
10 -> 10.00
100 -> 100.00
15000 -> 1.5e4
I tried to use the boost::format function with the %g type, but while it is possible to set the number of significant digits, it's not possible to set the number of printed digits after the decimal point:
1 -> 1
0.1 -> 0.1
0.01 -> 0.01
10 -> 10
100 -> 100
Is there a better way of doing this kind of conversion/formatting? I would preferably use the Standard Library or Boost.
Choose scientific or fixed depending on the size of the number.
It's that easy.
Cheers & hth.,
No boost needed although there should be a way to do this with boost::format or sprintf if you want.
#include <iostream>
#include <iomanip>
int main()
{
std::string numStr("3.14159265");
double num(atof(numStr.c_str()));
std::cout
<< std::setprecision(2)
<< std::scientific << num
<< std::fixed << num;
return 0;
}
Edit: Misread the question if you want to go from double to std::string I'd use a std::ostringstream which supports the same iostream manipulators and insertion operator. Then you can call str() to get a string out of it.
You can use ostringstream, like so
#include <sstream>
#include <string>
std::string FloatToString(float fNumber)
{
std::ostringstream os;
os << fNumber;
return os.str();
}
I'm not sure if this is what you are looking for but...
You can control the number of printed digits using cout with using the setprecision function.
#include <iomanip>
#include <iostream>
using namespace std;
int main()
{
double d = 123123.23234234;
cout << setprecision(15) << d;
system("pause");
return 0;
}
sprintf() ; should be easy to help you print double into a string/char array .
Plain old C sprintf supports # of decimals like so: "%.3g"
You can turn the char* output into a std::string easily enough.
Related
how would I make it so when i enter 2.785 for the input question the output will display the variable question as 2.79?
I tried using setprecision but for some reason it is not working unless i am doing it wrong
here is the user input question and what it should be:
Enter positive daily growth % (.1 must be entered as 10):
user enters "2.785"
output -> 0.02785
My desired output should look like:
desired output-> 2.79%
Any help is appreciated. I know it may seem simple to others but I have already tried looking online and everything I find just isn't making sense or doesn't work and I dont know what I am doing wrong.
Floating point arithmetic
The reason why it is challenging is that floating point cannot be represented accurately when you perform operations on them. See wikipedia article
It is a very intesting topic, if you have a bit of time, take a look at explanations about floating point and how its representation inside the computer.
If you are looking for the display only (only works for small decimals)
If you are just looking to display a small value you can use below code:
#include <cmath>
#include <iostream>
#include <iomanip>
#include <limits>
#include <sstream>
using namespace std;
string truncateAsString(double n, int precision) {
stringstream ss;
double remainder = static_cast<double>((int)floor((n - floor(n)) * precision) % precision);
ss << setprecision(numeric_limits<double> ::max_digits10 + __builtin_ctz(precision))<< floor(n);
if (remainder)
ss << "." << remainder;
cout << ss.str() << "%" << endl;
return ss.str();
}
int main(void) {
double a = 0.02785;
int precision = 100; // as many digits as you add zeroes. 3 zeroes means precision of 3.
string s = truncateAsString(a*100 + 0.5 / 100, precision);
return 0;
}
Looking for the true value?
Maybe you are looking for true value for your floating point, you can use boost multiprecision library
The Boost.Multiprecision library can be used for computations requiring precision exceeding that of standard built-in types such as float, double and long double. For extended-precision calculations, Boost.Multiprecision supplies a template data type called cpp_dec_float. The number of decimal digits of precision is fixed at compile-time via template parameter.
You need to use a custom library like boost/multiprecision because of the lack of precision for floating points, see my code below:
#include <boost/math/constants/constants.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <iostream>
#include <limits>
#include <cmath>
#include <iomanip>
using namespace std;
using boost::multiprecision::cpp_dec_float_50;
cpp_dec_float_50 truncate(cpp_dec_float_50 n, int precision) {
cpp_dec_float_50 remainder = static_cast<cpp_dec_float_50>((int)floor((n - floor(n)) * precision) % precision) / static_cast<cpp_dec_float_50>(precision);
return floor(n) + remainder;
}
int main(void) {
int precision = 100; // as many digits as you add zeroes. 5 zeroes means precision of 5.
cpp_dec_float_50 n = 0.02785 * 100;
n = truncate(n + 0.5/precision, precision); // first part is remainder, floor(n) is int value truncated.
cout << setprecision(numeric_limits<cpp_dec_float_50> ::max_digits10 + __builtin_ctz(precision)) << n << "%" << endl; // __builtin_ctz(precision) will equal the number of trailing 0, exactly the precision we need!
return 0;
}
Output (both cases)
2.79%
NB: I add 0.5 / precision to the truncate function to force it to act like a rounding.
I have a code where i can get digit upto 9 digits after decimal point so say something like 0.123456789. Now we can have a case where i get the value 10.123 or say 1001.12. Now there are only 3 digits after decimal point and 2 digits in e.g 10.123 and 1001.12. I am using
#include <iostream>
#include <iomanip>
#include <sstream>
#include <stdio.h>
using namespace std;
int main()
{
std:stringstream ss;
double val = 1.234;
ss.str(std::string());
ss << std::fixed;
ss << std::setprecision(9);
ss << val;
string number= ss.str();
std::cout << number <<"\n";
return 0;
}
Above would give output as 1.234000000 . Note that i would want the precision to be handled automatically depending on the length of the digits after decimal point. One way is for me to find number of digits after decimal point and set precision evverytime , is there some other standard method provided, that takes care of it ?
Thanks
how to print specific number of digits in c++?For example ,printing 8 digits totally(before and after decimal point combined)
Edit: For further clarification, setprecision sets the digits when i have decimal digits to display.I want to display integer 30 also as 30.000000 ,in 8 digits.
The setprecision command puts fixed no. of digits after decimal and i don't want that.
In short , I want an alternative of c command printf("%8d",N) in C++.
You can do it using setprecision() function from include iomanip and fixed like:
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
double d = 1000;
double t = d;
int dc=0;
while(t>0.9)
{
dc++;
t= t/10;
}
cout<<"dc:"<<dc<<endl;
cout << fixed;
std::cout << std::setprecision(dc);
std::cout << d;
return 0;
}
The setprecision() will not work fine every time So you have to use fixed as well.
You should use the c++ header iomanip what you want is the setprecision() function:
std::cout << std::setprecision(5) << 12.3456789 << std::endl;
outputs 12.346. It also has other modifiers you can find here
EDIT
If you want to print trailing 0s, you need to also use std::fixed. This says to use that number of digits, regardless of whether or not they are significant. If you want that to be the total number, you could figure out the size of the number, then change the precision you set it to based on that, so something like:
#include <iostream>
#include <iomanip>
#include <cmath>
int main()
{
double input = 30;
int magnitude = 0;
while(input / pow(10, magnitude))
{
++magnitude;
}
std::cout << std::fixed << std::setprecision(8 - magnitude) << input << std::endl;
return 0;
}
This returns 30.000000. You can also do something similar by outputting to a string, then displaying that string.
I have been trying to convert a double into string without the C++11 (ToString) but it only accepts the number of decimals to be 5 as default. How can I change that?
The command is:
string a = static_cast<ostringstream*>( &(ostringstream()<<digits) )->str();
but it keeps 5 decimals while I want to create a string which has all the decimals (e.g. 100)
I know that, that many decimals dont matter. This is one point of the exercise I was doing.
Any suggestions?
Thank you very much for your time
Cheers!
Use IO manipulators setprecision here on std::cout but works on stringstream:
// setprecision example from cplusplus.com
#include <iostream> // std::cout, std::fixed
#include <iomanip> // std::setprecision
int main () {
double f =3.14159;
std::cout << std::fixed << std::setprecision(9) << f << '\n';
return 0;
}
By the way, no double will have 100 meaningfull digit, it's 15 or 17, I forgot exactly how many.
EDIT: I forgot, if you can use C++11... You can (and should) use to_string
#include <string>
// ....
std::string f_str = std::to_string(f);
This worked for me finally
digits = 1.12345123451234;
char buff[100];
sprintf(buff, "%1.14f", digits);
string a(buff);
Thanks for checking it in any case
Cheers
I have a string that looks like this:
"0.4794255386042030002732879352156"
which is approximately the sin(0.5). I would like to format the string to look a much nicer
"4.794255386042e-1"
How can I achieve this? Remember I am dealing with strings and not numbers (float, double). Also I need to round to keep the number as accurate as possible, I can't just truncate. If I need to convert to a different data type I would prefer a long double because a regular double doesn't have enough precision. I'd like at least 12 decimal digits before rounding. Perhaps there is a simple sprintf() conversion I could do.
Something like this:
#include<iostream>
using namespace std;
int main()
{
char *s = "0.4794255386042030002732879352156";
double d;
sscanf(s,"%lf",&d);
printf("%.12e\n",d);
return EXIT_SUCCESS;
}
Output:
# g++ a.cpp && ./a.out
4.794255386042e-01
Are you looking for something like this?
Here is a sample:
// modify basefield
#include <iostream>
#include <sstream>
using namespace std;
int main () {
std::string numbers("0.4794255386042030002732879352156");
std::stringstream stream;
stream << numbers;
double number_fmt;
stream >> number_fmt;
cout.precision(30);
cout << number_fmt << endl;
cout.precision(5);
cout << scientific << number_fmt << endl;
return 0;
}
Output:
0.479425538604203005377257795772
4.79426e-01
In highly portable C the working example below outputs:
result is 4.794255386042E-01
#include <stdio.h>
int main()
{
char *str = "0.4794255386042030002732879352156";
double f;
char newstr [50];
// convert string in `str` to float
sscanf (str, "%le", &f);
sprintf (newstr, "%.12E", f);
printf ("result is %s\n", newstr);
return 0;
}
Looking at the strings in your question, it would seem you are using base-10 logarithms. In that case wouldn't it be relatively easy to just count the leading or trailing zeros and put that in an exponent, by scanning the strings directly?
Maybe i'm missing something..
An IEEE 754 64 bit float (i.e. double precision), is good for 15 decimal significant figures, so you should have no problem converting to double. You are more likely to run into the problem of getting the format specifier to display all available digits. Although from the examples posted, this seems not to be the case.
Convert to long double using sscanf(), then use sprintf() to print it back out as a string, using the scientific formatter:
long double x;
char num[64];
if(sscanf(string, "%Lf", &x) == 1)
sprintf(num, "%.12Le", x);
Not sure if even long double actually gives you 12 significant digits, though. On my system, this generates "4.79425538604e-01".
There is no standard function in either C or C++ to do this. The normal approach is either to convert to a number (and then use standard functions to format the number) or write your own custom output function.
#include <iostream>
using namespace std;
...
double dd = strtod( str );
cout << scientific << dd << endl;
Depending on how many decimal places you want (12 in this case) you could do something like this:
int main() {
char buff[500];
string x = "0.4794255386042030002732879352156";
double f = atof(x.c_str());
sprintf(buff,"%.12fe-1",f*10);
cout<<buff<<endl;
return 0;
}
Result:
---------- Capture Output ----------
"c:\windows\system32\cmd.exe" /c c:\temp\temp.exe
4.794255386042e-1
Terminated with exit code 0.