precise string representation of float number

A

A. L.

Consider following code segment:

#1: double pi = 3.141592653589;
#2: printf("%lf\n", pi);
#3: printf("%1.12lf\n", pi);
#4: printf("%1.15lf\n", pi);

The above code outputs as following:

3.141593
3.141592653589
3.141592653589000

The default output precision of printf is 6, so #2 outputs '3.141593'
with the effect of rounding error. To get the complete string
representation of pi, the precision should be explicitly specified as a
number equal or greater than pi's real precision, e.g., 12 in '%1.12lf'
of #3. But when specified precision is greater than real precision,
just like #4, the annoying trailing zeros are padded.

My question is that how to get the complete/precise string
representation of a float number using C standard library, but not in a
style of printf in which the output precision should be specified as a
great number (it will bring out superfluous trailing zeros).

Could somebody here give me some advices?

Thank you very much.
 
E

Emmanuel Delahaye

A. L. wrote on 17/09/05 :
Consider following code segment:

#1: double pi = 3.141592653589;
#2: printf("%lf\n", pi);
#3: printf("%1.12lf\n", pi);
#4: printf("%1.15lf\n", pi);

The above code outputs as following:

3.141593
3.141592653589
3.141592653589000

The default output precision of printf is 6, so #2 outputs '3.141593'
with the effect of rounding error. To get the complete string
representation of pi, the precision should be explicitly specified as a
number equal or greater than pi's real precision, e.g., 12 in '%1.12lf'
of #3. But when specified precision is greater than real precision,
just like #4, the annoying trailing zeros are padded.

My question is that how to get the complete/precise string
representation of a float number using C standard library, but not in a
style of printf in which the output precision should be specified as a
great number (it will bring out superfluous trailing zeros).

Use "%g". The 'l' is useless.

#include <stdio.h>
int main (void)
{
double pi = 3.141592653589;
printf ("%g\n", pi);
printf ("%1.12g\n", pi);
printf ("%1.15g\n", pi);
return 0;
}

3.14159
3.14159265359
3.141592653589

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"There are 10 types of people in the world today;
those that understand binary, and those that dont."
 
W

Walter Roberson

My question is that how to get the complete/precise string
representation of a float number using C standard library, but not in a
style of printf in which the output precision should be specified as a
great number (it will bring out superfluous trailing zeros).
Could somebody here give me some advices?

There is no way to do that with the standard library. It requires
extra information about the "real" precision of a number is.

Your Pi example dealt with stripping off trailing 0's, but
if I use const double Foo = 1.234567890; then the 0 *is* part of the
precision and stripping it off would be incorrect.

If you do any arithmetic manipulation of numbers, such as Pi + Foo
or Pi / Foo then "something" needs to know how to figure out the
correct precision of the result. C doesn't do that for you.

Any discussion of the "precise" string representation of a float is
doomed to failure if you use the standard machine representations
instead of indefinite-precision libraries and numeric analysis to
figure out how many digits you ought to be calculating.

For example, if you have 4.5678901 then it could happen that
the closest that a 'float' could get to representing that is
4.5678904875 which by the usual rounding rules would round down to
4.567890 and your remove-trailing-zeroes approach would output that as
4.56789 which would not be correct!
 
A

A. L.

I guess the only way could be machine-dependent. In fact, what I want
is complete/precise conversion of float number to string, acting like
some sort of inverse function of atoi, atol, etc.

In Python, there is repr() that can well serve the above job.

You are right. It seems no way to rely on standard library or some
'standard' method in C.
 
J

Joe Wright

A. L. said:
I guess the only way could be machine-dependent. In fact, what I want
is complete/precise conversion of float number to string, acting like
some sort of inverse function of atoi, atol, etc.

In Python, there is repr() that can well serve the above job.

You are right. It seems no way to rely on standard library or some
'standard' method in C.
[ much snipping ]

I have found after much testing that using the *printf functions, the
format string "%.8e" will represent 32-bit floats exactly. Also, the
format "%.16e" will represent 64-bit doubles exactly.

3.14159274e+00 is the float version and

3.1415926535897931e+00 is the double version.

The representations are as precise as the types allow. I have tested
this with gcc compiler on both Intel (little endian) and Sparc (big
endian) boxes.

I'll bet you money that either of these strings, if such they are, when
presented to any C implementation on any platform and evaluated by
strtod() will 'do the right thing' on that platform.

YMMV of course, but..
 
M

Malcolm

A. L. said:
My question is that how to get the complete/precise string
representation of a float number using C standard library, but not in a
style of printf in which the output precision should be specified as a
great number (it will bring out superfluous trailing zeros).
As a general rule

printf("%.*g\n", DBL_DIG, x);

(Note the decimal point - we are not interested in the width but the
precison.) DBL_DIG, defined in limits.h, gives a platform-specific number of
digits precision. Note it is almost always 15 because almost everyone uses
the IEEE 64-bit format.

This should get rid of trailing zeroes, but if it doesn't and my Microsoft
docs are wrong simply call sprintf() and then chop them off by hnad.
 
K

Keith Thompson

Joe Wright said:
A. L. said:
I guess the only way could be machine-dependent. In fact, what I want
is complete/precise conversion of float number to string, acting like
some sort of inverse function of atoi, atol, etc.
In Python, there is repr() that can well serve the above job.
You are right. It seems no way to rely on standard library or some
'standard' method in C.
[ much snipping ]

I have found after much testing that using the *printf functions, the
format string "%.8e" will represent 32-bit floats exactly. Also, the
format "%.16e" will represent 64-bit doubles exactly.

3.14159274e+00 is the float version and

3.1415926535897931e+00 is the double version.

To be precise, it won't represent the values *exactly*, but it will
(I presume) represent them with enough precision that you can get the
original value back.
 
J

Joe Wright

Keith said:
Joe Wright said:
A. L. said:
I guess the only way could be machine-dependent. In fact, what I want
is complete/precise conversion of float number to string, acting like
some sort of inverse function of atoi, atol, etc.
In Python, there is repr() that can well serve the above job.
You are right. It seems no way to rely on standard library or some
'standard' method in C.

[ much snipping ]

I have found after much testing that using the *printf functions, the
format string "%.8e" will represent 32-bit floats exactly. Also, the
format "%.16e" will represent 64-bit doubles exactly.

3.14159274e+00 is the float version and

3.1415926535897931e+00 is the double version.


To be precise, it won't represent the values *exactly*, but it will
(I presume) represent them with enough precision that you can get the
original value back.
That is *precisely* what I meant, *exactly*. :)

Further, the precision of a floating point value is limited by the width
of its mantissa. A float on my system here has a 24-bit mantissa. That
means its precision about 1 in 16 million. Please note precision is not
about value range or computational accuracy. Representing a float value
beyond nine significant decimal digits is meaningless.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top