about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>2014-06-17 08:46:25 -0500
committerAdhemerval Zanella <azanella@linux.vnet.ibm.com>2014-08-28 09:25:47 -0400
commit7e986751f5c05f3363c01c717972f87a681da0d0 (patch)
tree78781ababa253591ec22c8fe9f1b9d82bbd48d50
parent2289a56644fc05786e2d5637c76d47afea7d38b9 (diff)
downloadglibc-7e986751f5c05f3363c01c717972f87a681da0d0.tar.gz
glibc-7e986751f5c05f3363c01c717972f87a681da0d0.tar.xz
glibc-7e986751f5c05f3363c01c717972f87a681da0d0.zip
PowerPC: Fix nearbyintl failure for few inputs
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.

This is a backport of 754c5a08aacb44895d1ab97c553ce424eb43f761.
-rw-r--r--ChangeLog8
-rw-r--r--NEWS3
-rw-r--r--math/libm-test.inc8
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c5
4 files changed, 23 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index a8a24b5127..95dcce84ac 100644
--- 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-11  Vidya Ranganathan  <vidya@linux.vnet.ibm.com>
 
 	* sysdeps/powerpc/powerpc64/power7/strcmp.S: New file: Optimization.
diff --git a/NEWS b/NEWS
index 99bda3c9b8..96b7621c0f 100644
--- a/NEWS
+++ b/NEWS
@@ -9,7 +9,8 @@ Version 2.19.1
 
 * The following bugs are resolved with this release:
 
-  16545, 16683, 16689, 16701, 16706, 16707, 16739, 16815, 16619, 16740.
+  16545, 16683, 16689, 16701, 16706, 16707, 16739, 16815, 16619, 16740,
+  17031.
 
 Version 2.19
 
diff --git a/math/libm-test.inc b/math/libm-test.inc
index 1c5c022f4f..848b89ee7b 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -10519,6 +10519,10 @@ static const struct test_f_f_data nearbyint_test_data[] =
     TEST_f_f (nearbyint,  34503599627370498.515625L, 34503599627370499.0L),
     TEST_f_f (nearbyint, -34503599627370498.515625L, -34503599627370499.0L),
 # if LDBL_MANT_DIG >= 106
+    TEST_f_f (nearbyint, 1024.5000000000001L, 1025.0L, NO_INEXACT_EXCEPTION),
+    TEST_f_f (nearbyint, 1025.5000000000001L, 1026.0L, NO_INEXACT_EXCEPTION),
+    TEST_f_f (nearbyint, -1024.5000000000001L, -1025.0L, NO_INEXACT_EXCEPTION),
+    TEST_f_f (nearbyint, -1025.5000000000001L, -1026.0L, NO_INEXACT_EXCEPTION),
     TEST_f_f (nearbyint,  1192568192774434123539907640624.484375L, 1192568192774434123539907640624.0L),
     TEST_f_f (nearbyint, -1192568192774434123539907640624.484375L, -1192568192774434123539907640624.0L),
 # endif
@@ -11335,6 +11339,10 @@ static const struct test_f_f_data rint_test_data[] =
     TEST_f_f (rint, 4503599627370497.5L, 4503599627370498.0L, INEXACT_EXCEPTION),
 
 # if LDBL_MANT_DIG > 100
+    TEST_f_f (rint, 1024.5000000000001L, 1025.0L, INEXACT_EXCEPTION),
+    TEST_f_f (rint, 1025.5000000000001L, 1026.0L, INEXACT_EXCEPTION),
+    TEST_f_f (rint, -1024.5000000000001L, -1025.0L, INEXACT_EXCEPTION),
+    TEST_f_f (rint, -1025.5000000000001L, -1026.0L, INEXACT_EXCEPTION),
     TEST_f_f (rint, 4503599627370494.5000000000001L, 4503599627370495.0L, INEXACT_EXCEPTION),
     TEST_f_f (rint, 4503599627370495.5000000000001L, 4503599627370496.0L, INEXACT_EXCEPTION),
     TEST_f_f (rint, 4503599627370496.5000000000001L, 4503599627370497.0L, INEXACT_EXCEPTION),
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c b/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c
index 4e997a68f9..8f34604f54 100644
--- a/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/s_nearbyintl.c
@@ -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]);