On Sat, 27 Dec 2008 21:24:10 +0100 Roland Mainz wrote: > This is basically a spin-off of > http://bugs.opensolaris.org/view_bug.do?bug_id=6773712 ("1-digit hex fp > base conversion of long double rounds incorrectly"). > The bug description for Solaris libc says this: > > The first line of output from this program is correct. The second line > > is not. > > > > leviathan% cat a.c > > #include <stdio.h> > > > > int main() > > { > > printf("%.0a\n", 1.5); > > printf("%.0La\n", 1.5L); > > return 0; > > } > > leviathan% cc -o a a.c > > leviathan% a > > 0x1p+1 > > 0x1p+0 > > leviathan%
an 'aA' format rounding patch for src/lib/libast/sfio/sfcvt.c follows but I have a question about the leading hex digit 0 or 1 (0x1*) what is the source of this requirement posix and c99 only state: where there is one hexadecimal digit (which is nonzero if the argument is a normalized floating-point number and is otherwise unspecified) before the decimal-point character the libast/sfio implementation also formats to the 0x1* form but gnu libc does not --- .../sfio/sfcvt.c Tue Aug 19 03:32:17 2008 +++ sfio/sfcvt.c Sun Dec 28 04:41:52 2008 @@ -210,7 +210,9 @@ while ((x -= 4) >= 0) { *sp++ = ep[(m >> x) & 0xf]; if (sp >= endsp) - { ep = sp + 1; + { if (((m >> x) & 0xf) >= 8) + (*decpt)++; + ep = sp + 1; goto done; } } @@ -369,13 +371,13 @@ return SF_INF; if(format & SFFMT_AFORMAT) - { double g; - int x; + { double g; + int x; b = sp = buf; ep = (format & SFFMT_UPPER) ? ux : lx; if(n_digit <= 0 || n_digit >= (size - 9)) n_digit = size - 9; - endsp = sp + n_digit; + endsp = sp + n_digit + 1; g = frexp(f, &x); *decpt = x; @@ -387,7 +389,9 @@ while ((x -= 4) >= 0) { *sp++ = ep[(m >> x) & 0xf]; if (sp >= endsp) - { ep = sp + 1; + { if (((m >> x) & 0xf) >= 8) + (*decpt)++; + ep = sp + 1; goto done; } }