Reputation: 2392
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.
Upvotes: 9
Views: 17834
Reputation: 5080
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
Upvotes: 7
Reputation: 400109
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"
.
Upvotes: 2
Reputation: 93566
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.
Upvotes: 2
Reputation: 5256
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..
Upvotes: 3
Reputation: 57794
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;
}
Upvotes: 3
Reputation: 55467
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.
Upvotes: 0
Reputation: 6426
#include <iostream>
using namespace std;
...
double dd = strtod( str );
cout << scientific << dd << endl;
Upvotes: 0
Reputation: 455400
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
Upvotes: 10
Reputation:
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.
Upvotes: 0