This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: SV: Bug in printf ?


I don't think there is any bug here. This is what I've seen from a
little digging:

1) cygwin strtod rounds to even, with about DECIMAL_DIG (==21) digits
precision, as recommended by 7.20.1.3 of WG14/N843. (It acts strange
when the rounding mode is not round to nearest, but since newlib
doesn't provide fesetround(), that's your own problem if you insist on
changing rounding mode by hand, as I understand it).

2) cygwin gcc rounds with *lots* more precision than DECIMAL_DIG,
about 50 digits. It rounds towards zero. These behaviours are a little
different than the recommendation in 6.4.4.2 Ibid., which says
constants should be converted as if by strtod() at runtime, but its
not a big difference.

3) cygwin printf correctly rounds to even, even out to about 41 digits.

4) I have no idea what mingw is doing, but it's different to the
above. Gcc constructs the same double precision constants as on cygwin
but strtod() is different and seems to have less precision, and
printf() seems to work with about 16 digits precision. At a glance I'd
say it rounds to zero, with exactly the precision of

On 05/07/05, Dave Korn wrote:
>  Stepping through the code at the weekend, I followed the 0.105 case as far
> down as ldtoa_r, where I observed that although there was code that would
> round 0.105 up to 0.11 if asked for only two sig.figs, the loop that
> generates successive digits was coming up with the sequence
> '0.10499999999.....', and because the rounding only looks at one digit
> beyond the requested s.f., it 'correctly' rounds 0.104 down to 0.10.

The closest double to 0.105 is actually
0.10499999999999999611421941381195210851728916168212890625, and this
is what printf() is (correctly) handed, and what it (correctly) rounds
to 0.10.
 
>  I say 'correctly' in quotes, because it's the correct way to round 0.104,
> but it's not in general correct to round a number by truncating it and then
> rounding the truncated version.

But I don't think that "truncating it and then rounding the truncated
version" is what printf() does. If we give it 0.125 and 0.375, which
are both representible exactly, then it rounds to 0.12 and 0.38, ie
one goes up and one goes down, to round to even. You can see it's not
simply truncating if you give it 0.1250000000000001, which gets
rounded to 0.13 not 0.12 as it would for truncation.

To summarize: cygwin does the right thing

Attachment: test.c
Description: Text document

--
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/

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]