about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2015-10-09 00:32:14 +0000
committerJoseph Myers <joseph@codesourcery.com>2015-10-09 00:32:14 +0000
commit0e069029a8bb132876d315242054a312ae106852 (patch)
tree3afba08492052af6c50456621e0aba3323bccc29
parentd0d286d32dda654f8983e8fe77bca0a2cda2051b (diff)
downloadglibc-0e069029a8bb132876d315242054a312ae106852.tar.gz
glibc-0e069029a8bb132876d315242054a312ae106852.tar.xz
glibc-0e069029a8bb132876d315242054a312ae106852.zip
Fix dbl-64 lrint for 64-bit long (bug 19095).
The dbl-64 implementation of lrint produces incorrect results for some
arguments with 64-bit long because a 32-bit (unsigned) low part of the
mantissa is shifted left, losing high bits in the process.  This patch
fixes this by casting to long int before shifting, as in lround (as
this case only applies for 64-bit long, there are no issues with
sign-extension).

Tested for mips64 (n64).

	[BZ #19095]
	* sysdeps/ieee754/dbl-64/s_lrint.c (__lrint): Cast low part of
	mantissa to long int before shifting left.
-rw-r--r--ChangeLog6
-rw-r--r--NEWS2
-rw-r--r--sysdeps/ieee754/dbl-64/s_lrint.c2
3 files changed, 8 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 0bfe5f56a4..1ceae346df 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2015-10-09  Joseph Myers  <joseph@codesourcery.com>
+
+	[BZ #19095]
+	* sysdeps/ieee754/dbl-64/s_lrint.c (__lrint): Cast low part of
+	mantissa to long int before shifting left.
+
 2015-10-08  Joseph Myers  <joseph@codesourcery.com>
 
 	[BZ #19094]
diff --git a/NEWS b/NEWS
index 352e468603..5c239f3988 100644
--- a/NEWS
+++ b/NEWS
@@ -19,7 +19,7 @@ Version 2.23
   18875, 18887, 18921, 18951, 18952, 18956, 18961, 18966, 18967, 18969,
   18970, 18977, 18980, 18981, 18985, 19003, 19012, 19016, 19018, 19032,
   19046, 19049, 19050, 19059, 19071, 19076, 19077, 19078, 19079, 19085,
-  19086, 19088, 19094.
+  19086, 19088, 19094, 19095.
 
 * The obsolete header <regexp.h> has been removed.  Programs that require
   this header must be updated to use <regex.h> instead.
diff --git a/sysdeps/ieee754/dbl-64/s_lrint.c b/sysdeps/ieee754/dbl-64/s_lrint.c
index 39f95adc21..d004594bc2 100644
--- a/sysdeps/ieee754/dbl-64/s_lrint.c
+++ b/sysdeps/ieee754/dbl-64/s_lrint.c
@@ -61,7 +61,7 @@ __lrint (double x)
   else if (j0 < (int32_t) (8 * sizeof (long int)) - 1)
     {
       if (j0 >= 52)
-	result = ((long int) i0 << (j0 - 20)) | (i1 << (j0 - 52));
+	result = ((long int) i0 << (j0 - 20)) | ((long int) i1 << (j0 - 52));
       else
 	{
 #if defined FE_INVALID || defined FE_INEXACT