459,185 Members | 1,271 Online 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
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 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. wrote:My question is that how to get the complete/precise stringrepresentation of a float number using C standard library, but not in astyle of printf in which the output precision should be specified as agreat 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. wrote:My question is that how to get the complete/precise stringrepresentation of a float number using C standard library, but not in astyle of printf in which the output precision should be specified as agreat 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." 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 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 San Diego Supercomputer Center <*> We must do something. This is something. Therefore, we must do this. Nov 15 '05 #7

 P: n/a Keith Thompson wrote: Joe Wright writes:A. L. wrote:I guess the only way could be machine-dependent. In fact, what I wantis complete/precise conversion of float number to string, acting likesome 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, theformat string "%.8e" will represent 32-bit floats exactly. Also, theformat "%.16e" will represent 64-bit doubles exactly.3.14159274e+00 is the float version and3.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. 