By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,185 Members | 1,271 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,185 IT Pros & Developers. It's quick & easy.

precise string representation of float number

P: n/a
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.

Nov 15 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a
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."
Nov 15 '05 #2

P: n/a
In article <11**********************@g14g2000cwa.googlegroups .com>,
A. L. <ba*****@gmail.com> wrote:
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!
--
I was very young in those days, but I was also rather dim.
-- Christopher Priest
Nov 15 '05 #3

P: n/a
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.
Walter Roberson wrote:
In article <11**********************@g14g2000cwa.googlegroups .com>,
A. L. <ba*****@gmail.com> wrote:
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!
--
I was very young in those days, but I was also rather dim.
-- Christopher Priest


Nov 15 '05 #4

P: n/a
A. L. wrote:
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..
--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 15 '05 #5

P: n/a

"A. L." <ba*****@gmail.com> wrote

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.

Nov 15 '05 #6

P: n/a
Joe Wright <jw*****@comcast.net> writes:
A. L. wrote:
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.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #7

P: n/a
Keith Thompson wrote:
Joe Wright <jw*****@comcast.net> writes:
A. L. wrote:
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.

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 15 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.