mirror of
https://sourceware.org/git/glibc.git
synced 2025-01-03 16:21:06 +00:00
Fix lround, llround missing exceptions close to overflow threshold (bug 19088).
The dbl-64, ldbl-96 and ldbl-128 implementations of lround and llround fail to produce "invalid" exceptions in cases where the rounded result overflows the target type, but truncating the floating-point argument to the next integer towards zero does not overflow it (so in particular casts do not produce such exceptions). (This issue cannot arise for float, or for double with 64-bit target type, or for ldbl-96 with 64-bit target type and negative arguments, because of insufficient precision in the floating-point type for arguments with the relevant property to exist.) This patch fixes these problems by inserting checks for the special cases that can occur in each implementation, and explicitly raising FE_INVALID (and avoiding the cast if it might raise spurious FE_INEXACT). Tested for x86_64, x86 and mips64. [BZ #19088] * sysdeps/ieee754/dbl-64/s_lround.c: Include <fenv.h> and <limits.h>. (__lround) [FE_INVALID]: Force FE_INVALID exception when result overflows but exception would not result from cast. * sysdeps/ieee754/dbl-64/wordsize-64/s_lround.c: Include <fenv.h> and <limits.h>. (__lround) [FE_INVALID]: Force FE_INVALID exception when result overflows but exception would not result from cast. * sysdeps/ieee754/ldbl-128/s_llroundl.c: Include <fenv.h> and <limits.h>. (__llroundl) [FE_INVALID]: Force FE_INVALID exception when result overflows but exception would not result from cast. * sysdeps/ieee754/ldbl-128/s_lroundl.c: Include <fenv.h> and <limits.h>. (__lroundl) [FE_INVALID]: Force FE_INVALID exception when result overflows but exception would not result from cast. * sysdeps/ieee754/ldbl-96/s_llroundl.c: Include <fenv.h> and <limits.h>. (__llroundl) [FE_INVALID]: Force FE_INVALID exception when result overflows but exception would not result from cast. * sysdeps/ieee754/ldbl-96/s_lroundl.c: Include <fenv.h> and <limits.h>. (__lroundl) [FE_INVALID]: Force FE_INVALID exception when result overflows but exception would not result from cast. * math/libm-test.inc (lround_test_data): Add more tests. (llround_test_data): Likewise.
This commit is contained in:
parent
939e092a9e
commit
8afdb7ac1e
30
ChangeLog
30
ChangeLog
@ -1,3 +1,33 @@
|
||||
2015-10-07 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
[BZ #19088]
|
||||
* sysdeps/ieee754/dbl-64/s_lround.c: Include <fenv.h> and
|
||||
<limits.h>.
|
||||
(__lround) [FE_INVALID]: Force FE_INVALID exception when result
|
||||
overflows but exception would not result from cast.
|
||||
* sysdeps/ieee754/dbl-64/wordsize-64/s_lround.c: Include <fenv.h>
|
||||
and <limits.h>.
|
||||
(__lround) [FE_INVALID]: Force FE_INVALID exception when result
|
||||
overflows but exception would not result from cast.
|
||||
* sysdeps/ieee754/ldbl-128/s_llroundl.c: Include <fenv.h> and
|
||||
<limits.h>.
|
||||
(__llroundl) [FE_INVALID]: Force FE_INVALID exception when result
|
||||
overflows but exception would not result from cast.
|
||||
* sysdeps/ieee754/ldbl-128/s_lroundl.c: Include <fenv.h> and
|
||||
<limits.h>.
|
||||
(__lroundl) [FE_INVALID]: Force FE_INVALID exception when result
|
||||
overflows but exception would not result from cast.
|
||||
* sysdeps/ieee754/ldbl-96/s_llroundl.c: Include <fenv.h> and
|
||||
<limits.h>.
|
||||
(__llroundl) [FE_INVALID]: Force FE_INVALID exception when result
|
||||
overflows but exception would not result from cast.
|
||||
* sysdeps/ieee754/ldbl-96/s_lroundl.c: Include <fenv.h> and
|
||||
<limits.h>.
|
||||
(__lroundl) [FE_INVALID]: Force FE_INVALID exception when result
|
||||
overflows but exception would not result from cast.
|
||||
* math/libm-test.inc (lround_test_data): Add more tests.
|
||||
(llround_test_data): Likewise.
|
||||
|
||||
2015-10-07 Steve Ellcey <sellcey@imgtec.com>
|
||||
|
||||
* timezone/Makefile (CFLAGS-zic.c): Add -Wno-unused-variable.
|
||||
|
2
NEWS
2
NEWS
@ -18,7 +18,7 @@ Version 2.23
|
||||
18820, 18823, 18824, 18825, 18857, 18863, 18870, 18872, 18873, 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.
|
||||
19049, 19050, 19059, 19071, 19076, 19077, 19078, 19079, 19085, 19088.
|
||||
|
||||
* The obsolete header <regexp.h> has been removed. Programs that require
|
||||
this header must be updated to use <regex.h> instead.
|
||||
|
@ -8282,6 +8282,123 @@ static const struct test_f_l_data lround_test_data[] =
|
||||
#endif
|
||||
TEST_f_l (lround, -0x1p64, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
TEST_f_l (lround, -0x1p65, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
TEST_f_l (lround, 0x7fffff80p0, 0x7fffff80LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
#ifndef TEST_FLOAT
|
||||
TEST_f_l (lround, 0x7fffffffp0, 0x7fffffffLL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
TEST_f_l (lround, 0x7fffffff.4p0, 0x7fffffffLL, ERRNO_UNCHANGED),
|
||||
TEST_f_l (lround, 0x7fffffff.7ffffcp0, 0x7fffffffLL, ERRNO_UNCHANGED),
|
||||
# if LONG_MAX > 0x7fffffff
|
||||
TEST_f_l (lround, 0x7fffffff.8p0, 0x80000000LL, ERRNO_UNCHANGED),
|
||||
TEST_f_l (lround, 0x7fffffff.cp0, 0x80000000LL, ERRNO_UNCHANGED),
|
||||
# else
|
||||
TEST_f_l (lround, 0x7fffffff.8p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
TEST_f_l (lround, 0x7fffffff.cp0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
# endif
|
||||
#endif
|
||||
#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 64
|
||||
TEST_f_l (lround, 0x7fffffff.7fffffff8p0L, 0x7fffffffLL, ERRNO_UNCHANGED),
|
||||
#endif
|
||||
#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106
|
||||
TEST_f_l (lround, 0x7fffffff.7fffffffffffffffffep0L, 0x7fffffffLL, ERRNO_UNCHANGED),
|
||||
#endif
|
||||
#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 113
|
||||
TEST_f_l (lround, 0x7fffffff.7fffffffffffffffffffcp0L, 0x7fffffffLL, ERRNO_UNCHANGED),
|
||||
#endif
|
||||
#ifndef TEST_FLOAT
|
||||
TEST_f_l (lround, -0x80000000.4p0, -0x80000000LL, ERRNO_UNCHANGED),
|
||||
TEST_f_l (lround, -0x80000000.7ffff8p0, -0x80000000LL, ERRNO_UNCHANGED),
|
||||
# if LONG_MAX > 0x7fffffff
|
||||
TEST_f_l (lround, -0x80000000.8p0, -0x80000001LL, ERRNO_UNCHANGED),
|
||||
TEST_f_l (lround, -0x80000000.cp0, -0x80000001LL, ERRNO_UNCHANGED),
|
||||
TEST_f_l (lround, -0x80000001p0, -0x80000001LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
# else
|
||||
TEST_f_l (lround, -0x80000000.8p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
TEST_f_l (lround, -0x80000000.cp0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
TEST_f_l (lround, -0x80000001p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
# endif
|
||||
#endif
|
||||
#if LONG_MAX > 0x7fffffff
|
||||
TEST_f_l (lround, -0x80000100p0, -0x80000100LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
#else
|
||||
TEST_f_l (lround, -0x80000100p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
#endif
|
||||
#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 64
|
||||
TEST_f_l (lround, -0x80000000.7fffffffp0L, -0x80000000LL, ERRNO_UNCHANGED),
|
||||
#endif
|
||||
#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106
|
||||
TEST_f_l (lround, -0x80000000.7fffffffffffffffffcp0L, -0x80000000LL, ERRNO_UNCHANGED),
|
||||
#endif
|
||||
#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 113
|
||||
TEST_f_l (lround, -0x80000000.7fffffffffffffffffff8p0L, -0x80000000LL, ERRNO_UNCHANGED),
|
||||
#endif
|
||||
#if LONG_MAX > 0x7fffffff
|
||||
TEST_f_l (lround, 0x7fffff8000000000p0, 0x7fffff8000000000LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
#else
|
||||
TEST_f_l (lround, 0x7fffff8000000000p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
#endif
|
||||
#ifndef TEST_FLOAT
|
||||
# if LONG_MAX > 0x7fffffff
|
||||
TEST_f_l (lround, 0x7ffffffffffffc00p0, 0x7ffffffffffffc00LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
# else
|
||||
TEST_f_l (lround, 0x7ffffffffffffc00p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
# endif
|
||||
#endif
|
||||
#ifdef TEST_LDOUBLE
|
||||
# if LONG_MAX > 0x7fffffff
|
||||
TEST_f_l (lround, 0x7fffffffffffffffp0L, 0x7fffffffffffffffLL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
# else
|
||||
TEST_f_l (lround, 0x7fffffffffffffffp0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
# endif
|
||||
TEST_f_l (lround, 0x7fffffffffffffff.8p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
# if LDBL_MANT_DIG > 64
|
||||
# if LONG_MAX > 0x7fffffff
|
||||
TEST_f_l (lround, 0x7fffffffffffffff.4p0L, 0x7fffffffffffffffLL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
# else
|
||||
TEST_f_l (lround, 0x7fffffffffffffff.4p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
# endif
|
||||
TEST_f_l (lround, 0x7fffffffffffffff.cp0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
# endif
|
||||
# if LONG_MAX > 0x7fffffff
|
||||
# if LDBL_MANT_DIG >= 106
|
||||
TEST_f_l (lround, 0x7fffffffffffffff.7fffffffffep0L, 0x7fffffffffffffffLL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
# endif
|
||||
# if LDBL_MANT_DIG >= 113
|
||||
TEST_f_l (lround, 0x7fffffffffffffff.7fffffffffffcp0L, 0x7fffffffffffffffLL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
# endif
|
||||
# else
|
||||
# if LDBL_MANT_DIG >= 106
|
||||
TEST_f_l (lround, 0x7fffffffffffffff.7fffffffffep0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
# endif
|
||||
# if LDBL_MANT_DIG >= 113
|
||||
TEST_f_l (lround, 0x7fffffffffffffff.7fffffffffffcp0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#ifdef TEST_LDOUBLE
|
||||
TEST_f_l (lround, -0x8000000000000001p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
#endif
|
||||
#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106
|
||||
# if LONG_MAX > 0x7fffffff
|
||||
TEST_f_l (lround, -0x8000000000000000.4p0L, LLONG_MIN, ERRNO_UNCHANGED),
|
||||
TEST_f_l (lround, -0x8000000000000000.7fffffffffcp0L, LLONG_MIN, ERRNO_UNCHANGED),
|
||||
# else
|
||||
TEST_f_l (lround, -0x8000000000000000.4p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
TEST_f_l (lround, -0x8000000000000000.7fffffffffcp0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
# endif
|
||||
TEST_f_l (lround, -0x8000000000000000.8p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
TEST_f_l (lround, -0x8000000000000000.cp0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
#endif
|
||||
TEST_f_l (lround, -0x8000010000000000p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
#ifndef TEST_FLOAT
|
||||
TEST_f_l (lround, -0x8000000000000800p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
#endif
|
||||
#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 113
|
||||
# if LONG_MAX > 0x7fffffff
|
||||
TEST_f_l (lround, -0x8000000000000000.7fffffffffff8p0L, LLONG_MIN, ERRNO_UNCHANGED),
|
||||
# else
|
||||
TEST_f_l (lround, -0x8000000000000000.7fffffffffff8p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
# endif
|
||||
#endif
|
||||
TEST_f_l (lround, 0, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
TEST_f_l (lround, minus_zero, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
TEST_f_l (lround, min_value, 0.0, ERRNO_UNCHANGED),
|
||||
@ -8492,6 +8609,74 @@ static const struct test_f_L_data llround_test_data[] =
|
||||
TEST_f_L (llround, -0x1p63, LLONG_MIN, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
TEST_f_L (llround, -0x1p64, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
TEST_f_L (llround, -0x1p65, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
TEST_f_L (llround, 0x7fffff80p0, 0x7fffff80LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
#ifndef TEST_FLOAT
|
||||
TEST_f_L (llround, 0x7fffffffp0, 0x7fffffffLL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
TEST_f_L (llround, 0x7fffffff.4p0, 0x7fffffffLL, ERRNO_UNCHANGED),
|
||||
TEST_f_L (llround, 0x7fffffff.7ffffcp0, 0x7fffffffLL, ERRNO_UNCHANGED),
|
||||
TEST_f_L (llround, 0x7fffffff.8p0, 0x80000000LL, ERRNO_UNCHANGED),
|
||||
TEST_f_L (llround, 0x7fffffff.cp0, 0x80000000LL, ERRNO_UNCHANGED),
|
||||
#endif
|
||||
#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 64
|
||||
TEST_f_L (llround, 0x7fffffff.7fffffff8p0L, 0x7fffffffLL, ERRNO_UNCHANGED),
|
||||
#endif
|
||||
#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106
|
||||
TEST_f_L (llround, 0x7fffffff.7fffffffffffffffffep0L, 0x7fffffffLL, ERRNO_UNCHANGED),
|
||||
#endif
|
||||
#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 113
|
||||
TEST_f_L (llround, 0x7fffffff.7fffffffffffffffffffcp0L, 0x7fffffffLL, ERRNO_UNCHANGED),
|
||||
#endif
|
||||
#ifndef TEST_FLOAT
|
||||
TEST_f_L (llround, -0x80000000.4p0, -0x80000000LL, ERRNO_UNCHANGED),
|
||||
TEST_f_L (llround, -0x80000000.7ffff8p0, -0x80000000LL, ERRNO_UNCHANGED),
|
||||
TEST_f_L (llround, -0x80000000.8p0, -0x80000001LL, ERRNO_UNCHANGED),
|
||||
TEST_f_L (llround, -0x80000000.cp0, -0x80000001LL, ERRNO_UNCHANGED),
|
||||
TEST_f_L (llround, -0x80000001p0, -0x80000001LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
#endif
|
||||
TEST_f_L (llround, -0x80000100p0, -0x80000100LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 64
|
||||
TEST_f_L (llround, -0x80000000.7fffffffp0L, -0x80000000LL, ERRNO_UNCHANGED),
|
||||
#endif
|
||||
#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106
|
||||
TEST_f_L (llround, -0x80000000.7fffffffffffffffffcp0L, -0x80000000LL, ERRNO_UNCHANGED),
|
||||
#endif
|
||||
#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 113
|
||||
TEST_f_L (llround, -0x80000000.7fffffffffffffffffff8p0L, -0x80000000LL, ERRNO_UNCHANGED),
|
||||
#endif
|
||||
TEST_f_L (llround, 0x7fffff8000000000p0, 0x7fffff8000000000LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
#ifndef TEST_FLOAT
|
||||
TEST_f_L (llround, 0x7ffffffffffffc00p0, 0x7ffffffffffffc00LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
#endif
|
||||
#ifdef TEST_LDOUBLE
|
||||
TEST_f_L (llround, 0x7fffffffffffffffp0L, 0x7fffffffffffffffLL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
TEST_f_L (llround, 0x7fffffffffffffff.8p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
# if LDBL_MANT_DIG > 64
|
||||
TEST_f_L (llround, 0x7fffffffffffffff.4p0L, 0x7fffffffffffffffLL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
TEST_f_L (llround, 0x7fffffffffffffff.cp0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
# endif
|
||||
# if LDBL_MANT_DIG >= 106
|
||||
TEST_f_L (llround, 0x7fffffffffffffff.7fffffffffep0L, 0x7fffffffffffffffLL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
# endif
|
||||
# if LDBL_MANT_DIG >= 113
|
||||
TEST_f_L (llround, 0x7fffffffffffffff.7fffffffffffcp0L, 0x7fffffffffffffffLL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
# endif
|
||||
#endif
|
||||
#ifdef TEST_LDOUBLE
|
||||
TEST_f_L (llround, -0x8000000000000001p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
#endif
|
||||
#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106
|
||||
TEST_f_L (llround, -0x8000000000000000.4p0L, LLONG_MIN, ERRNO_UNCHANGED),
|
||||
TEST_f_L (llround, -0x8000000000000000.7fffffffffcp0L, LLONG_MIN, ERRNO_UNCHANGED),
|
||||
TEST_f_L (llround, -0x8000000000000000.8p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
TEST_f_L (llround, -0x8000000000000000.cp0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
#endif
|
||||
TEST_f_L (llround, -0x8000010000000000p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
#ifndef TEST_FLOAT
|
||||
TEST_f_L (llround, -0x8000000000000800p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION),
|
||||
#endif
|
||||
#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 113
|
||||
TEST_f_L (llround, -0x8000000000000000.7fffffffffff8p0L, LLONG_MIN, ERRNO_UNCHANGED),
|
||||
#endif
|
||||
TEST_f_L (llround, 0, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
TEST_f_L (llround, minus_zero, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
|
||||
TEST_f_L (llround, min_value, 0.0, ERRNO_UNCHANGED),
|
||||
|
@ -17,6 +17,8 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <fenv.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <math_private.h>
|
||||
@ -60,13 +62,33 @@ __lround (double x)
|
||||
if (j0 == 20)
|
||||
result = (long int) i0;
|
||||
else
|
||||
{
|
||||
result = ((long int) i0 << (j0 - 20)) | (j >> (52 - j0));
|
||||
#ifdef FE_INVALID
|
||||
if (sizeof (long int) == 4
|
||||
&& sign == 1
|
||||
&& result == LONG_MIN)
|
||||
/* Rounding brought the value out of range. */
|
||||
feraiseexcept (FE_INVALID);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The number is too large. It is left implementation defined
|
||||
what happens. */
|
||||
/* The number is too large. Unless it rounds to LONG_MIN,
|
||||
FE_INVALID must be raised and the return value is
|
||||
unspecified. */
|
||||
#ifdef FE_INVALID
|
||||
if (sizeof (long int) == 4
|
||||
&& x <= (double) LONG_MIN - 0.5)
|
||||
{
|
||||
/* If truncation produces LONG_MIN, the cast will not raise
|
||||
the exception, but may raise "inexact". */
|
||||
feraiseexcept (FE_INVALID);
|
||||
return LONG_MIN;
|
||||
}
|
||||
#endif
|
||||
return (long int) x;
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,8 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <fenv.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <math_private.h>
|
||||
@ -48,12 +50,30 @@ __lround (double x)
|
||||
i0 += UINT64_C(0x8000000000000) >> j0;
|
||||
|
||||
result = i0 >> (52 - j0);
|
||||
#ifdef FE_INVALID
|
||||
if (sizeof (long int) == 4
|
||||
&& sign == 1
|
||||
&& result == LONG_MIN)
|
||||
/* Rounding brought the value out of range. */
|
||||
feraiseexcept (FE_INVALID);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The number is too large. It is left implementation defined
|
||||
what happens. */
|
||||
/* The number is too large. Unless it rounds to LONG_MIN,
|
||||
FE_INVALID must be raised and the return value is
|
||||
unspecified. */
|
||||
#ifdef FE_INVALID
|
||||
if (sizeof (long int) == 4
|
||||
&& x <= (double) LONG_MIN - 0.5)
|
||||
{
|
||||
/* If truncation produces LONG_MIN, the cast will not raise
|
||||
the exception, but may raise "inexact". */
|
||||
feraiseexcept (FE_INVALID);
|
||||
return LONG_MIN;
|
||||
}
|
||||
#endif
|
||||
return (long int) x;
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,8 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <fenv.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <math_private.h>
|
||||
@ -60,13 +62,30 @@ __llroundl (long double x)
|
||||
if (j0 == 48)
|
||||
result = (long long int) i0;
|
||||
else
|
||||
{
|
||||
result = ((long long int) i0 << (j0 - 48)) | (j >> (112 - j0));
|
||||
#ifdef FE_INVALID
|
||||
if (sign == 1 && result == LLONG_MIN)
|
||||
/* Rounding brought the value out of range. */
|
||||
feraiseexcept (FE_INVALID);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The number is too large. It is left implementation defined
|
||||
what happens. */
|
||||
/* The number is too large. Unless it rounds to LLONG_MIN,
|
||||
FE_INVALID must be raised and the return value is
|
||||
unspecified. */
|
||||
#ifdef FE_INVALID
|
||||
if (x <= (long double) LLONG_MIN - 0.5L)
|
||||
{
|
||||
/* If truncation produces LLONG_MIN, the cast will not raise
|
||||
the exception, but may raise "inexact". */
|
||||
feraiseexcept (FE_INVALID);
|
||||
return LLONG_MIN;
|
||||
}
|
||||
#endif
|
||||
return (long long int) x;
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,8 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <fenv.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <math_private.h>
|
||||
@ -47,6 +49,13 @@ __lroundl (long double x)
|
||||
{
|
||||
i0 += 0x0000800000000000LL >> j0;
|
||||
result = i0 >> (48 - j0);
|
||||
#ifdef FE_INVALID
|
||||
if (sizeof (long int) == 4
|
||||
&& sign == 1
|
||||
&& result == LONG_MIN)
|
||||
/* Rounding brought the value out of range. */
|
||||
feraiseexcept (FE_INVALID);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (j0 >= 112)
|
||||
@ -60,11 +69,32 @@ __lroundl (long double x)
|
||||
if (j0 == 48)
|
||||
result = (long int) i0;
|
||||
else
|
||||
{
|
||||
result = ((long int) i0 << (j0 - 48)) | (j >> (112 - j0));
|
||||
#ifdef FE_INVALID
|
||||
if (sizeof (long int) == 8
|
||||
&& sign == 1
|
||||
&& result == LONG_MIN)
|
||||
/* Rounding brought the value out of range. */
|
||||
feraiseexcept (FE_INVALID);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The number is too large. Unless it rounds to LONG_MIN,
|
||||
FE_INVALID must be raised and the return value is
|
||||
unspecified. */
|
||||
#ifdef FE_INVALID
|
||||
if (x <= (long double) LONG_MIN - 0.5L)
|
||||
{
|
||||
/* If truncation produces LONG_MIN, the cast will not raise
|
||||
the exception, but may raise "inexact". */
|
||||
feraiseexcept (FE_INVALID);
|
||||
return LONG_MIN;
|
||||
}
|
||||
#endif
|
||||
/* The number is too large. It is left implementation defined
|
||||
what happens. */
|
||||
return (long int) x;
|
||||
|
@ -17,6 +17,8 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <fenv.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <math_private.h>
|
||||
@ -64,7 +66,14 @@ __llroundl (long double x)
|
||||
++result;
|
||||
|
||||
if (j0 > 31)
|
||||
{
|
||||
result = (result << (j0 - 31)) | (j >> (63 - j0));
|
||||
#ifdef FE_INVALID
|
||||
if (sign == 1 && result == LLONG_MIN)
|
||||
/* Rounding brought the value out of range. */
|
||||
feraiseexcept (FE_INVALID);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -17,6 +17,8 @@
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <fenv.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <math_private.h>
|
||||
@ -49,6 +51,13 @@ __lroundl (long double x)
|
||||
}
|
||||
|
||||
result = j >> (31 - j0);
|
||||
#ifdef FE_INVALID
|
||||
if (sizeof (long int) == 4
|
||||
&& sign == 1
|
||||
&& result == LONG_MIN)
|
||||
/* Rounding brought the value out of range. */
|
||||
feraiseexcept (FE_INVALID);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (j0 < (int32_t) (8 * sizeof (long int)) - 1)
|
||||
@ -66,13 +75,33 @@ __lroundl (long double x)
|
||||
if (j0 == 31)
|
||||
result = ures;
|
||||
else
|
||||
{
|
||||
result = (ures << (j0 - 31)) | (j >> (63 - j0));
|
||||
#ifdef FE_INVALID
|
||||
if (sizeof (long int) == 8
|
||||
&& sign == 1
|
||||
&& result == LONG_MIN)
|
||||
/* Rounding brought the value out of range. */
|
||||
feraiseexcept (FE_INVALID);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The number is too large. It is left implementation defined
|
||||
what happens. */
|
||||
/* The number is too large. Unless it rounds to LONG_MIN,
|
||||
FE_INVALID must be raised and the return value is
|
||||
unspecified. */
|
||||
#ifdef FE_INVALID
|
||||
if (sizeof (long int) == 4
|
||||
&& x <= (long double) LONG_MIN - 0.5L)
|
||||
{
|
||||
/* If truncation produces LONG_MIN, the cast will not raise
|
||||
the exception, but may raise "inexact". */
|
||||
feraiseexcept (FE_INVALID);
|
||||
return LONG_MIN;
|
||||
}
|
||||
#endif
|
||||
return (long int) x;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user