]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
PowerPC: Fix nearbyintl failure for few inputs
authorRajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
Tue, 17 Jun 2014 13:46:25 +0000 (08:46 -0500)
committerAdhemerval Zanella <azanella@linux.vnet.ibm.com>
Tue, 17 Jun 2014 13:46:25 +0000 (08:46 -0500)
This patch fixes few failures in nearbyintl() where the fraction part is
close to 0.5.i  The new tests added report few extra failures in
nearbyint_downward and nearbyint_towardzero which is a known issue.

Fixes #17031.

ChangeLog
NEWS
math/libm-test.inc
sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c

index 9ebf711103c509892ef3daf4e29fa371b9d5ea05..2c554fae8ee010f103bc2b0799751c5c75e36a92 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2014-16-17  Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
+
+       [BZ #17031]
+       * sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c: Consider the low
+       double, adjusted for any remainder from the high double.
+       * math/libm-test.inc (nearbyint): Add tests.
+       (rint): Likewise.
+
 2014-06-17  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
 
        * nptl/sysdeps/powerpc/Makefile: Moved ...
diff --git a/NEWS b/NEWS
index 0ba83dcaa7d2fc57460b79787930b8e68b89daf7..d90acbf2d01571ae831777a4d48ac35ef327eef1 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -19,7 +19,8 @@ Version 2.20
   16791, 16796, 16799, 16800, 16815, 16823, 16824, 16831, 16838, 16849,
   16854, 16876, 16877, 16878, 16882, 16885, 16888, 16890, 16912, 16915,
   16916, 16917, 16922, 16927, 16928, 16932, 16943, 16958, 16965, 16966,
-  16967, 16977, 16978, 16984, 16990, 16996, 17009, 17042, 17048, 17058.
+  16967, 16977, 16978, 16984, 16990, 16996, 17009, 17031, 17042, 17048,
+  17058.
 
 * The minimum Linux kernel version that this version of the GNU C Library
   can be used with is 2.6.32.
index fa8e2385dc1bbb1f9944ee10061ea956071b630f..d98d85c715bb497efa8bc1379a228191f89cafab 100644 (file)
@@ -8188,6 +8188,10 @@ static const struct test_f_f_data nearbyint_test_data[] =
     TEST_f_f (nearbyint, 4503599627370496.75L, 4503599627370496.0L, NO_INEXACT_EXCEPTION, 4503599627370497.0L, NO_INEXACT_EXCEPTION, 4503599627370496.0L, NO_INEXACT_EXCEPTION, 4503599627370497.0L, NO_INEXACT_EXCEPTION),
     TEST_f_f (nearbyint, 4503599627370497.5L, 4503599627370497.0L, NO_INEXACT_EXCEPTION, 4503599627370498.0L, NO_INEXACT_EXCEPTION, 4503599627370497.0L, NO_INEXACT_EXCEPTION, 4503599627370498.0L, NO_INEXACT_EXCEPTION),
 # if LDBL_MANT_DIG > 100
+    TEST_f_f (nearbyint, 1024.5000000000001L, 1024.0L, NO_INEXACT_EXCEPTION, 1025.0L, NO_INEXACT_EXCEPTION, 1024.0L, NO_INEXACT_EXCEPTION, 1025.0L, NO_INEXACT_EXCEPTION),
+    TEST_f_f (nearbyint, 1025.5000000000001L, 1025.0L, NO_INEXACT_EXCEPTION, 1026.0L, NO_INEXACT_EXCEPTION, 1025.0L, NO_INEXACT_EXCEPTION, 1026.0L, NO_INEXACT_EXCEPTION),
+    TEST_f_f (nearbyint, -1024.5000000000001L, -1025.0L, NO_INEXACT_EXCEPTION, -1025.0L, NO_INEXACT_EXCEPTION, -1024.0L, NO_INEXACT_EXCEPTION, -1024.0L, NO_INEXACT_EXCEPTION),
+    TEST_f_f (nearbyint, -1025.5000000000001L, -1026.0L, NO_INEXACT_EXCEPTION, -1026.0L, NO_INEXACT_EXCEPTION, -1025.0L, NO_INEXACT_EXCEPTION, -1025.0L, NO_INEXACT_EXCEPTION),
     TEST_f_f (nearbyint, 4503599627370494.5000000000001L, 4503599627370494.0L, NO_INEXACT_EXCEPTION, 4503599627370495.0L, NO_INEXACT_EXCEPTION, 4503599627370494.0L, NO_INEXACT_EXCEPTION, 4503599627370495.0L, NO_INEXACT_EXCEPTION),
     TEST_f_f (nearbyint, 4503599627370495.5000000000001L, 4503599627370495.0L, NO_INEXACT_EXCEPTION, 4503599627370496.0L, NO_INEXACT_EXCEPTION, 4503599627370495.0L, NO_INEXACT_EXCEPTION, 4503599627370496.0L, NO_INEXACT_EXCEPTION),
     TEST_f_f (nearbyint, 4503599627370496.5000000000001L, 4503599627370496.0L, NO_INEXACT_EXCEPTION, 4503599627370497.0L, NO_INEXACT_EXCEPTION, 4503599627370496.0L, NO_INEXACT_EXCEPTION, 4503599627370497.0L, NO_INEXACT_EXCEPTION),
@@ -8890,6 +8894,10 @@ static const struct test_f_f_data rint_test_data[] =
     TEST_f_f (rint, 4503599627370496.75L, 4503599627370496.0L, INEXACT_EXCEPTION, 4503599627370497.0L, INEXACT_EXCEPTION, 4503599627370496.0L, INEXACT_EXCEPTION, 4503599627370497.0L, INEXACT_EXCEPTION),
     TEST_f_f (rint, 4503599627370497.5L, 4503599627370497.0L, INEXACT_EXCEPTION, 4503599627370498.0L, INEXACT_EXCEPTION, 4503599627370497.0L, INEXACT_EXCEPTION, 4503599627370498.0L, INEXACT_EXCEPTION),
 # if LDBL_MANT_DIG > 100
+    TEST_f_f (rint, 1024.5000000000001L, 1024.0L, INEXACT_EXCEPTION, 1025.0L, INEXACT_EXCEPTION, 1024.0L, INEXACT_EXCEPTION, 1025.0L, INEXACT_EXCEPTION),
+    TEST_f_f (rint, 1025.5000000000001L, 1025.0L, INEXACT_EXCEPTION, 1026.0L, INEXACT_EXCEPTION, 1025.0L, INEXACT_EXCEPTION, 1026.0L, INEXACT_EXCEPTION),
+    TEST_f_f (rint, -1024.5000000000001L, -1025.0L, INEXACT_EXCEPTION, -1025.0L, INEXACT_EXCEPTION, -1024.0L, INEXACT_EXCEPTION, -1024.0L, INEXACT_EXCEPTION),
+    TEST_f_f (rint, -1025.5000000000001L, -1026.0L, INEXACT_EXCEPTION, -1026.0L, INEXACT_EXCEPTION, -1025.0L, INEXACT_EXCEPTION, -1025.0L, INEXACT_EXCEPTION),
     TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370494.0L, INEXACT_EXCEPTION, 4503599627370495.0L, INEXACT_EXCEPTION, 4503599627370494.0L, INEXACT_EXCEPTION, 4503599627370495.0L, INEXACT_EXCEPTION),
     TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370495.0L, INEXACT_EXCEPTION, 4503599627370496.0L, INEXACT_EXCEPTION, 4503599627370495.0L, INEXACT_EXCEPTION, 4503599627370496.0L, INEXACT_EXCEPTION),
     TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370496.0L, INEXACT_EXCEPTION, 4503599627370497.0L, INEXACT_EXCEPTION, 4503599627370496.0L, INEXACT_EXCEPTION, 4503599627370497.0L, INEXACT_EXCEPTION),
index 4e997a68f9a70d139da9b6001efdbf5664f708fc..8f34604f54cc1d0c21c3193030d1d9939182660a 100644 (file)
@@ -38,6 +38,7 @@ __nearbyintl (long double x)
 
   if (fabs (u.d[0].d) < TWO52)
     {
+      double xh = u.d[0].d;
       double high = u.d[0].d;
       feholdexcept (&env);
       if (high > 0.0)
@@ -52,6 +53,10 @@ __nearbyintl (long double x)
          high += TWO52;
           if (high == 0.0) high = -0.0;
        }
+      if (u.d[1].d > 0.0 && (xh - high == 0.5))
+        high += 1.0;
+      else if (u.d[1].d < 0.0 && (-(xh - high) == 0.5))
+        high -= 1.0;
       u.d[0].d = high;
       u.d[1].d = 0.0;
       math_force_eval (u.d[0]);