OSDN Git Service

2005-06-28 Dave Korn <dave.korn@artimi.com>
authorjjohnstn <jjohnstn>
Tue, 28 Jun 2005 17:03:17 +0000 (17:03 +0000)
committerjjohnstn <jjohnstn>
Tue, 28 Jun 2005 17:03:17 +0000 (17:03 +0000)
        * libm/common/s_lrint.c (lrint):  Fix signed-vs-unsigned comparison
        and miscalculation caused by fp representation of zero.
        * libm/common/sf_lrint.c (lrintf):  Likewise.

newlib/ChangeLog
newlib/libm/common/s_lrint.c
newlib/libm/common/sf_lrint.c

index ae95843..ae96c23 100644 (file)
@@ -1,3 +1,9 @@
+2005-06-28  Dave Korn  <dave.korn@artimi.com>
+
+       * libm/common/s_lrint.c (lrint):  Fix signed-vs-unsigned comparison
+       and miscalculation caused by fp representation of zero.
+       * libm/common/sf_lrint.c (lrintf):  Likewise.
+
 2005-06-16  Christopher Faylor  <cgf@timesys.com>
 
        * libc/stdio/vfprintf.c (cvt): Don't rely on pointer aliasing to
index 541bf2c..45759f1 100644 (file)
@@ -54,7 +54,11 @@ TWO52[2]={
   long int result;
   
   EXTRACT_WORDS(i0,i1,x);
+
+  /* Extract sign bit. */
   sx = (i0>>31)&1;
+
+  /* Extract exponent field. */
   j0 = ((i0 & 0x7ff00000) >> 20) - 1023;
   
   if(j0 < 20)
@@ -66,13 +70,17 @@ TWO52[2]={
           w = TWO52[sx] + x;
           t = w - TWO52[sx];
           GET_HIGH_WORD(i0, t);
+          /* Detect the all-zeros representation of plus and
+             minus zero, which fails the calculation below. */
+          if ((i0 & ~(1 << 31)) == 0)
+              return 0;
           j0 = ((i0 & 0x7ff00000) >> 20) - 1023;
           i0 &= 0x000fffff;
           i0 |= 0x00100000;
           result = i0 >> (20 - j0);
         }
     }
-  else if (j0 < (8 * sizeof (long int)) - 1)
+  else if (j0 < (int)(8 * sizeof (long int)) - 1)
     {
       if (j0 >= 52)
         result = ((long int) i0 << (j0 - 20)) | (i1 << (j0 - 52));
index a58508f..427bbb6 100644 (file)
@@ -28,6 +28,10 @@ static const float
 #else
 static float 
 #endif
+/* Adding a float, x, to 2^23 will cause the result to be rounded based on
+   the fractional part of x, according to the implementation's current rounding
+   mode.  2^23 is the smallest float that can be represented using all 23 significant
+   digits. */
 TWO23[2]={
   8.3886080000e+06, /* 0x4b000000 */
  -8.3886080000e+06, /* 0xcb000000 */
@@ -54,7 +58,7 @@ TWO23[2]={
   /* Extract exponent field. */
   j0 = ((i0 & 0x7f800000) >> 23) - 127;
   
-  if (j0 < (sizeof (long int) * 8) - 1)
+  if (j0 < (int)(sizeof (long int) * 8) - 1)
     {
       if (j0 < -1)
         return 0;
@@ -65,6 +69,10 @@ TWO23[2]={
           w = TWO23[sx] + x;
           t = w - TWO23[sx];
           GET_FLOAT_WORD (i0, t);
+          /* Detect the all-zeros representation of plus and
+             minus zero, which fails the calculation below. */
+          if ((i0 & ~(1 << 31)) == 0)
+              return 0;
           j0 = ((i0 >> 23) & 0xff) - 0x7f;
           i0 &= 0x7fffff;
           i0 |= 0x800000;