Subject: RE: Precision of doubles and stdio
From: "Dave Korn" <[email-masked]>
To: "'Roberto Bagnara'" <[email-masked]>, <[email-masked]>
Cc: <[email-masked]>, "'The Parma Polyhedra Library developers' list'" <[email-masked]>
Date: Mon, 6 Mar 2006 13:33:04 -0000

[  X-Posted and Followups set to newlib list; this is almost certainly not a
cygwin specific issue.  To recap:-  ]

On 03 March 2006 21:44, Roberto Bagnara wrote:

> Hi there,
> 
> the following little program
> 
> #include <stdio.h>
> 
> int main() {
>    double d;
>    scanf("%lf", &d);
>    printf("%.1000g\n", d);
>    return 0;
> }
> 
> does this on Linux/i686
> 
> $ gcc -W -Wall in.c
> $ a.out
> 70.9
> 70.900000000000005684341886080801486968994140625
> 
> and does the following under Cygwin on the same machine:
> 
> roberto@quark /tmp
> $ gcc -W -Wall in.c
> 
> roberto@quark /tmp
> $ ./a.exe
> 70.9
> 70.90000000000000568434188608080148696899414

On 03 March 2006 22:21, Tim Prince wrote:

> If you haven't gone out of your way to install similar printf() support
> libraries on cygwin and linux, they will definitely not be the same.  My
> past reading of various relevant documents convinced me that digits
> beyond the 17th in formatting of doubles are not required by any
> standard to be consistent between implementations.  They have no useful
> function, as 17 digits are sufficient to determine uniquely the
> corresponding binary value in IEEE 754 format.

> Jim Easton wrote:

> With all due respect, why would you want to?  With double you are
> guaranteed only 16 or so digits - the rest is noise.  Frankly I am
> amazed that it agrees as far as it does.

On 06 March 2006 09:30, Roberto Bagnara wrote:

> In our applications we systematically use controlled rounding
> on IEEE 754 floating point numbers.  In the end, what we obtain
> (in memory) are definite (i.e., provably correct) lower or upper
> bounds of some quantities.
> 
> Call `x' such a quantity, and suppose we have that our computed
> upper bound for `x' is the IEEE 754 Double Precision number
> 
>      0x4051b9999999999a,
> 
> that is (exactly!),
> 
>      70.900000000000005684341886080801486968994140625.
> 
> If that number is (wrongly!) printed as
> 
>      70.90000000000000568434188608080148696899414
> 
> then we lose correctness, since
> x <= 70.900000000000005684341886080801486968994140625
> does not imply
> x <= 70.90000000000000568434188608080148696899414.
> So, the final "0625" is not "noise" in our applications:
> it is what may make the difference between a correct statement
> and an incorrect one.
> 
> Notice also that any IEEE 754 number can be (exactly!) printed
> with a finite number of decimal digits.  Finally, notice that
> writing an algorithm to print them correctly is not rocket science.
> Hence my astonishment when Tim showed me that the C standard
> decided, instead, to allow blatant violations of the principle
> of least astonishment :-)

  I agree with you that the number is of course precisely representable.  Even
if Tim isn't onto a red herring (which I think he probably is) and the
standard really does give us leeway in this case, we could still do better
anyway.  Newlib has had a few glitches and corner cases in its fp support
before and probably will do again; we can look into this.  I notice, for
instance, that newlib doesn't define DECIMAL_DIG or the related symbols
AFAICT.

  Are the newlib-based cygwin system and the glibc-based linux system using
the same mode bits in the fpu control register?  That '0625' looks awfully
like a 1-lsb error, maybe they are using different rounding or guard bits or
something like that?

    cheers,
      DaveK
-- 
Can't think of a witty .sigline today....

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/