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.
This commit is contained in:
Joseph Myers 2015-10-09 00:32:14 +00:00
parent d0d286d32d
commit 0e069029a8
3 changed files with 8 additions and 2 deletions

View File

@ -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]

2
NEWS
View File

@ -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.

View File

@ -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