Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ how to get "one digit exponent" with printf

Tags:

c++

wxwidgets

Is there a way to print in scientific notation less than 3 places for exponent part of number? The 6.1 formatting doesn't affect exponent but only the number part:

var=1.23e-9;
printf ("%e\n", var);
printf ("%6.1e\n", var);

gives

1.230000e-009
1.2e-009

I've also tried this in wxWidgets with formatting of string but the behavior is the same.

m_var->SetLabel(wxString::Format(wxT("%6.1e"),var));

What I'd like to have is 1.2e-9.

like image 790
Kris_R Avatar asked Jan 07 '12 21:01

Kris_R


2 Answers

According to Wikipedia:

The exponent always contains at least two digits; if the value is zero, the exponent is 00. In Windows, the exponent contains three digits by default, e.g. 1.5e002, but this can be altered by Microsoft-specific _set_output_format function.

_set_output_format

like image 113
Ilya Kogan Avatar answered Oct 03 '22 04:10

Ilya Kogan


I've had to do this a lot (I write file parsers and some file formats like NITF require you to store numeric values as strings).

What you do is an exploit based on what base-10 math (scientific notation) really means: It means that for all real numbers y, y = (x) * 10^(N) for some integer N and some x in the range (-1, 1) exclusive.

So, you do the following

void PrintScientific(double d)
{
   int exponent  = (int)floor(log10( fabs(d)));  // This will round down the exponent
   double base   = d * pow(10, -1.0*exponent);

   printf("%lfE%+01d", base, exponent);
}

You can add all the format specifiers you need to control the # of chars before, after the "." decimal place.

Do NOT forget the rounding step! This is how it works, using the properties of base10 and logarithms (base 10 here):

Let y = x * 10^N =>
log(y) = log(x*10^N) =>
log(y) = log(x) + log(10^N) => // From Log "product" rule
log(y) = log(x) + N

Since x is in the range (-10, 10) -"()" means exclusive(exclusive), that implies log(x) is in the range (-1, 1). So when we round down for integer conversion, we're dropping "log(x)" contribution. You can then get the "x" portion from the original number, which lets you output the original in any scientific notation you want to use.

like image 24
Zack Yezek Avatar answered Oct 03 '22 05:10

Zack Yezek