John Scipione
John Scipione

Reputation: 2392

Format string into scientific notation

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

Answers (9)

coelhudo
coelhudo

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

unwind
unwind

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

Clifford
Clifford

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

S.C. Madsen
S.C. Madsen

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

wallyk
wallyk

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

dcp
dcp

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

Sanjaya R
Sanjaya R

Reputation: 6426

#include <iostream>
using namespace std;
...
double dd = strtod( str );
cout << scientific << dd << endl;

Upvotes: 0

codaddict
codaddict

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

anon
anon

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

Related Questions