Subject: Re: lib/32861: frexp returns incorrect value for small floating-point
To: None <lib-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Matthias Drochner <M.Drochner@fz-juelich.de>
List: netbsd-bugs
Date: 02/20/2006 17:10:02
The following reply was made to PR lib/32861; it has been noted by GNATS.

From: Matthias Drochner <M.Drochner@fz-juelich.de>
To: gnats-bugs@netbsd.org
Cc: lib-bug-people@netbsd.org, gnats-admin@netbsd.org,
	netbsd-bugs@netbsd.org
Subject: Re: lib/32861: frexp returns incorrect value for small floating-point 
 values
Date: Mon, 20 Feb 2006 18:06:04 +0100

 This is a multipart MIME message.
 
 --==_Exmh_94551241839340
 Content-Type: text/plain; charset=us-ascii
 
 
 We should fix the libc version, even if it is just kept for
 binary compatibility, and it would be good to have something
 less intrusive to pull into the stable branch.
 I'll append a possible fix.
 Can you give it a try?
 (I don't have an idea why the fdlibm version scales by 2^54 in that
 situation. It doesn't hurt, but should be unecessary. If you've got
 some test suite, you might prove me wrong...)
 
 best regards
 Matthias
 
 
 
 --==_Exmh_94551241839340
 Content-Type: text/plain ; name="frexp.txt"; charset=us-ascii
 Content-Description: frexp.txt
 Content-Disposition: attachment; filename="frexp.txt"
 
 Index: gen/frexp_ieee754.c
 ===================================================================
 RCS file: /cvsroot/src/lib/libc/gen/frexp_ieee754.c,v
 retrieving revision 1.4
 diff -u -p -r1.4 frexp_ieee754.c
 --- gen/frexp_ieee754.c	27 Oct 2003 00:05:46 -0000	1.4
 +++ gen/frexp_ieee754.c	20 Feb 2006 16:51:37 -0000
 @@ -66,7 +66,13 @@ frexp(double value, int *eptr)
  		 */
  		u.dblu_d = value;
  		if (u.dblu_dbl.dbl_exp != DBL_EXP_INFNAN) {
 -			*eptr = u.dblu_dbl.dbl_exp - (DBL_EXP_BIAS - 1);
 +			*eptr = 0;
 +			if (u.dblu_dbl.dbl_exp == 0) {
 +				/* denormal, scale out of mantissa */
 +				*eptr = -DBL_FRACBITS;
 +				u.dblu_d *= 4.50359962737049600000e+15;
 +			}
 +			*eptr += u.dblu_dbl.dbl_exp - (DBL_EXP_BIAS - 1);
  			u.dblu_dbl.dbl_exp = DBL_EXP_BIAS - 1;
  		}
  		return (u.dblu_d);
 
 --==_Exmh_94551241839340--