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;
}
}