Re: RFA: Support infinity, NaN, and denormalized numbers in floatformat.c

2012-08-17 Thread Ian Lance Taylor
On Thu, Aug 16, 2012 at 9:20 AM, Andreas Schwab sch...@linux-m68k.org wrote:

 * floatformat.c (floatformat_to_double): Correctly handle numbers
 between 1 and 2.  Simplify handling of denormal number.
 (main): Test with 1.1.

This is OK.

Thanks.

Ian


Re: RFA: Support infinity, NaN, and denormalized numbers in floatformat.c

2012-08-16 Thread Andreas Schwab
Ian Lance Taylor i...@wasabisystems.com writes:

 @@ -306,8 +359,18 @@ floatformat_to_double (fmt, from, to)
mant = get_field (ufrom, fmt-byteorder, fmt-totalsize,
mant_off, mant_bits);
  
 -  dto += ldexp ((double)mant, exponent - mant_bits);
 -  exponent -= mant_bits;
 +  /* Handle denormalized numbers.  FIXME: What should we do for
 +  non-IEEE formats?  */
 +  if (exponent == 0  mant != 0)
 + dto += ldexp ((double)mant,
 +   (- fmt-exp_bias
 +- mant_bits
 +- (mant_off - fmt-man_start)
 ++ 1));
 +  else
 + dto += ldexp ((double)mant, exponent - mant_bits);
 +  if (exponent != 0)
 + exponent -= mant_bits;

That mishandles numbers between 1 and 2 (ie. where the unbiased exponent
is zero) with floating-point formats with more than 32 mantissa bits.
Also, the handling of denormal numbers can be simplified by just setting
exponent appropriately.

Andreas.

* floatformat.c (floatformat_to_double): Correctly handle numbers
between 1 and 2.  Simplify handling of denormal number.
(main): Test with 1.1.
---
 libiberty/floatformat.c | 38 ++
 1 file changed, 14 insertions(+), 24 deletions(-)

diff --git a/libiberty/floatformat.c b/libiberty/floatformat.c
index 1116c63..c58ab01 100644
--- a/libiberty/floatformat.c
+++ b/libiberty/floatformat.c
@@ -1,5 +1,5 @@
 /* IEEE floating point support routines, for GDB, the GNU Debugger.
-   Copyright 1991, 1994, 1999, 2000, 2003, 2005, 2006, 2010
+   Copyright 1991, 1994, 1999, 2000, 2003, 2005, 2006, 2010, 2012
Free Software Foundation, Inc.
 
 This file is part of GDB.
@@ -463,7 +463,6 @@ floatformat_to_double (const struct floatformat *fmt,
   unsigned long mant;
   unsigned int mant_bits, mant_off;
   int mant_bits_left;
-  int special_exponent;/* It's a NaN, denorm or zero */
 
   /* Split values are not handled specially, since the top half has
  the correctly rounded double value (in the only supported case of
@@ -503,20 +502,20 @@ floatformat_to_double (const struct floatformat *fmt,
   mant_off = fmt-man_start;
   dto = 0.0;
 
-  special_exponent = exponent == 0 || (unsigned long) exponent == fmt-exp_nan;
-
-  /* Don't bias zero's, denorms or NaNs.  */
-  if (!special_exponent)
-exponent -= fmt-exp_bias;
-
   /* Build the result algebraically.  Might go infinite, underflow, etc;
  who cares. */
 
-  /* If this format uses a hidden bit, explicitly add it in now.  Otherwise,
- increment the exponent by one to account for the integer bit.  */
-
-  if (!special_exponent)
+  /* For denorms use minimum exponent.  */
+  if (exponent == 0)
+exponent = 1 - fmt-exp_bias;
+  else
 {
+  exponent -= fmt-exp_bias;
+
+  /* If this format uses a hidden bit, explicitly add it in now.
+Otherwise, increment the exponent by one to account for the
+integer bit.  */
+
   if (fmt-intbit == floatformat_intbit_no)
dto = ldexp (1.0, exponent);
   else
@@ -530,18 +529,8 @@ floatformat_to_double (const struct floatformat *fmt,
   mant = get_field (ufrom, fmt-byteorder, fmt-totalsize,
 mant_off, mant_bits);
 
-  /* Handle denormalized numbers.  FIXME: What should we do for
-non-IEEE formats?  */
-  if (special_exponent  exponent == 0  mant != 0)
-   dto += ldexp ((double)mant,
- (- fmt-exp_bias
-  - mant_bits
-  - (mant_off - fmt-man_start)
-  + 1));
-  else
-   dto += ldexp ((double)mant, exponent - mant_bits);
-  if (exponent != 0)
-   exponent -= mant_bits;
+  dto += ldexp ((double) mant, exponent - mant_bits);
+  exponent -= mant_bits;
   mant_off += mant_bits;
   mant_bits_left -= mant_bits;
 }
@@ -756,6 +745,7 @@ main (void)
 {
   ieee_test (0.0);
   ieee_test (0.5);
+  ieee_test (1.1);
   ieee_test (256.0);
   ieee_test (0.12345);
   ieee_test (234235.78907234);
-- 
1.7.11.5


-- 
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
And now for something completely different.