Date: Sun, 15 Jan 1995 14:45:11 -0500 From: "Paul F. Werkowski" <pw@snoopy.MV.COM> To: freebsd-hackers@freefall.cdrom.com Subject: old vfprintf bug back again in 2.x Message-ID: <199501151945.OAA07055@snoopy.mv.com>
next in thread | raw e-mail | index | archive | help
A bug that was lurking in lib/libc/stdio/vfprintf.c prior to FreeBSD 1.1
is now again hiding in the 2.0 and -current source. The bug is demonstrated
by this code:
int main()
{
int FPRC = 16;
double d = 0;
printf( "%*.*e\n",FPRC+7,FPRC,d);
}
which results in
0e+00
instead of the correct
0.0000000000000000e+00
This breaks the AKCL (now GCL) compile/load feature.
I looked at the considerable differences between the 1.1 and 2.0 versions
of vfprintf and think I have reproduced the previous fixes. At least the
modified version passes the GCL test. Perhaps some official bug fixer can
look at this and commit to current /usr/src/lib/libc/stdio/?
Paul
*** vfprintf.c.dist Fri May 27 00:57:31 1994
--- vfprintf.c Sun Jan 15 14:38:03 1995
***************
*** 502,521 ****
base = 10;
goto number;
#ifdef FLOATING_POINT
! case 'e': /* anomalous precision */
case 'E':
! prec = (prec == -1) ?
! DEFPREC + 1 : prec + 1;
! /* FALLTHROUGH */
! goto fp_begin;
! case 'f': /* always print trailing zeroes */
! if (prec != 0)
! flags |= ALT;
case 'g':
case 'G':
! if (prec == -1)
prec = DEFPREC;
! fp_begin: _double = va_arg(ap, double);
/* do this before tricky precision changes */
if (isinf(_double)) {
if (_double < 0)
--- 502,524 ----
base = 10;
goto number;
#ifdef FLOATING_POINT
! case 'e':
case 'E':
! case 'f':
case 'g':
case 'G':
! if (prec == -1) {
prec = DEFPREC;
! } else if ((ch == 'g' || ch == 'G') && prec == 0) {
! prec = 1;
! }
!
! if (flags & LONGDBL) {
! _double = (double) va_arg(ap, long double);
! } else {
! _double = va_arg(ap, double);
! }
!
/* do this before tricky precision changes */
if (isinf(_double)) {
if (_double < 0)
***************
*** 802,808 ****
if (ch == 'f')
mode = 3;
else {
! mode = 2;
}
if (value < 0) {
value = -value;
--- 805,818 ----
if (ch == 'f')
mode = 3;
else {
! /* To obtain ndigits after the decimal point for the 'e'
! * and 'E' formats, round to ndigits + 1 significant
! * figures.
! */
! if (ch == 'e' || ch == 'E') {
! ndigits++;
! }
! mode = 2; /* ndigits significant digits */
}
if (value < 0) {
value = -value;
***************
*** 810,816 ****
} else
*sign = '\000';
digits = __dtoa(value, mode, ndigits, decpt, &dsgn, &rve);
! if (flags & ALT) { /* Print trailing zeros */
bp = digits + ndigits;
if (ch == 'f') {
if (*digits == '0' && value)
--- 820,826 ----
} else
*sign = '\000';
digits = __dtoa(value, mode, ndigits, decpt, &dsgn, &rve);
! if ((ch != 'g' && ch != 'G') || flags & ALT) { /* Print trailing zeros */
bp = digits + ndigits;
if (ch == 'f') {
if (*digits == '0' && value)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199501151945.OAA07055>
