diff options
-rw-r--r-- | ChangeLog | 26 | ||||
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | math/libm-test.inc | 217 | ||||
-rw-r--r-- | sysdeps/ieee754/dbl-64/s_lrint.c | 37 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-128/s_llrintl.c | 35 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-128/s_lrintl.c | 54 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-96/s_llrintl.c | 19 | ||||
-rw-r--r-- | sysdeps/ieee754/ldbl-96/s_lrintl.c | 55 |
8 files changed, 422 insertions, 23 deletions
@@ -1,3 +1,29 @@ +2015-10-08 Joseph Myers <joseph@codesourcery.com> + + [BZ #19094] + * sysdeps/ieee754/dbl-64/s_lrint.c: Include <fenv.h> and + <limits.h>. + (__lrint) [FE_INVALID || FE_INEXACT]: Force FE_INVALID exception + when result overflows but exception would not result from cast. + * sysdeps/ieee754/ldbl-128/s_llrintl.c: Include <fenv.h> and + <limits.h>. + (__llrintl) [FE_INVALID || FE_INEXACT]: Force FE_INVALID exception + when result overflows but exception would not result from cast. + * sysdeps/ieee754/ldbl-128/s_lrintl.c: Include <fenv.h> and + <limits.h>. + (__lrintl) [FE_INVALID || FE_INEXACT]: Force FE_INVALID exception + when result overflows but exception would not result from cast. + * sysdeps/ieee754/ldbl-96/s_llrintl.c: Include <fenv.h> and + <limits.h>. + (__llrintl) [FE_INVALID || FE_INEXACT]: Force FE_INVALID exception + when result overflows but exception would not result from cast. + * sysdeps/ieee754/ldbl-96/s_lrintl.c: Include <fenv.h> and + <limits.h>. + (__lrintl) [FE_INVALID || FE_INEXACT]: Force FE_INVALID exception + when result overflows but exception would not result from cast. + * math/libm-test.inc (lrint_test_data): Add more tests. + (llrint_test_data): Likewise. + 2015-10-08 Roland McGrath <roland@hack.frob.com> [BZ #18872] @@ -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. + 19086, 19088, 19094. * The obsolete header <regexp.h> has been removed. Programs that require this header must be updated to use <regex.h> instead. diff --git a/math/libm-test.inc b/math/libm-test.inc index cb738ca..652735d 100644 --- a/math/libm-test.inc +++ b/math/libm-test.inc @@ -7808,6 +7808,155 @@ static const struct test_f_l_data lrint_test_data[] = #endif TEST_f_l (lrint, -0x1p64, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), TEST_f_l (lrint, -0x1p65, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_f_l (lrint, 0x7fffff80p0, 0x7fffff80LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), +#ifndef TEST_FLOAT + TEST_f_l (lrint, 0x7fffffffp0, 0x7fffffffLL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), +# if LONG_MAX > 0x7fffffff + TEST_f_l (lrint, 0x7fffffff.4p0, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_f_l (lrint, 0x7fffffff.7ffffcp0, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_f_l (lrint, 0x7fffffff.8p0, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_f_l (lrint, 0x7fffffff.cp0, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), +# else + TEST_f_l (lrint, 0x7fffffff.4p0, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_f_l (lrint, 0x7fffffff.7ffffcp0, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_f_l (lrint, 0x7fffffff.8p0, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_f_l (lrint, 0x7fffffff.cp0, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), +# endif +#endif +#if LONG_MAX > 0x7fffffff +# if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 64 + TEST_f_l (lrint, 0x7fffffff.7fffffff8p0L, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), +# endif +# if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106 + TEST_f_l (lrint, 0x7fffffff.7fffffffffffffffffep0L, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), +# endif +# if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 113 + TEST_f_l (lrint, 0x7fffffff.7fffffffffffffffffffcp0L, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), +# endif +#else +# if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 64 + TEST_f_l (lrint, 0x7fffffff.7fffffff8p0L, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), +# endif +# if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106 + TEST_f_l (lrint, 0x7fffffff.7fffffffffffffffffep0L, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), +# endif +# if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 113 + TEST_f_l (lrint, 0x7fffffff.7fffffffffffffffffffcp0L, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), +# endif +#endif +#ifndef TEST_FLOAT +# if LONG_MAX > 0x7fffffff + TEST_f_l (lrint, -0x80000000.4p0, -0x80000001LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_f_l (lrint, -0x80000000.7ffff8p0, -0x80000001LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_f_l (lrint, -0x80000000.8p0, -0x80000001LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_f_l (lrint, -0x80000000.cp0, -0x80000001LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000001LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_f_l (lrint, -0x80000001p0, -0x80000001LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), +# else + TEST_f_l (lrint, -0x80000000.4p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_f_l (lrint, -0x80000000.7ffff8p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_f_l (lrint, -0x80000000.8p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_f_l (lrint, -0x80000000.cp0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_f_l (lrint, -0x80000001p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), +# endif +#endif +#if LONG_MAX > 0x7fffffff + TEST_f_l (lrint, -0x80000100p0, -0x80000100LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), +#else + TEST_f_l (lrint, -0x80000100p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), +#endif +#if LONG_MAX > 0x7fffffff +# if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 64 + TEST_f_l (lrint, -0x80000000.7fffffffp0L, -0x80000001LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), +# endif +# if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106 + TEST_f_l (lrint, -0x80000000.7fffffffffffffffffcp0L, -0x80000001LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), +# endif +# if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 113 + TEST_f_l (lrint, -0x80000000.7fffffffffffffffffff8p0L, -0x80000001LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), +# endif +#else +# if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 64 + TEST_f_l (lrint, -0x80000000.7fffffffp0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), +# endif +# if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106 + TEST_f_l (lrint, -0x80000000.7fffffffffffffffffcp0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), +# endif +# if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 113 + TEST_f_l (lrint, -0x80000000.7fffffffffffffffffff8p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), +# endif +#endif +#if LONG_MAX > 0x7fffffff + TEST_f_l (lrint, 0x7fffff8000000000p0, 0x7fffff8000000000LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), +#else + TEST_f_l (lrint, 0x7fffff8000000000p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), +#endif +#ifndef TEST_FLOAT +# if LONG_MAX > 0x7fffffff + TEST_f_l (lrint, 0x7ffffffffffffc00p0, 0x7ffffffffffffc00LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), +# else + TEST_f_l (lrint, 0x7ffffffffffffc00p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), +# endif +#endif +#ifdef TEST_LDOUBLE +# if LONG_MAX > 0x7fffffff + TEST_f_l (lrint, 0x7fffffffffffffffp0L, 0x7fffffffffffffffLL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_f_l (lrint, 0x7fffffffffffffff.8p0L, 0x7fffffffffffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION, 0x7fffffffffffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), +# else + TEST_f_l (lrint, 0x7fffffffffffffffp0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_f_l (lrint, 0x7fffffffffffffff.8p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), +# endif +# if LDBL_MANT_DIG > 64 +# if LONG_MAX > 0x7fffffff + TEST_f_l (lrint, 0x7fffffffffffffff.4p0L, 0x7fffffffffffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffffffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffffffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_f_l (lrint, 0x7fffffffffffffff.cp0L, 0x7fffffffffffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION, 0x7fffffffffffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), +# else + TEST_f_l (lrint, 0x7fffffffffffffff.4p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_f_l (lrint, 0x7fffffffffffffff.cp0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), +# endif +# endif +# if LONG_MAX > 0x7fffffff +# if LDBL_MANT_DIG >= 106 + TEST_f_l (lrint, 0x7fffffffffffffff.7fffffffffep0L, 0x7fffffffffffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffffffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffffffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), +# endif +# if LDBL_MANT_DIG >= 113 + TEST_f_l (lrint, 0x7fffffffffffffff.7fffffffffffcp0L, 0x7fffffffffffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffffffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffffffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), +# endif +# else +# if LDBL_MANT_DIG >= 106 + TEST_f_l (lrint, 0x7fffffffffffffff.7fffffffffep0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), +# endif +# if LDBL_MANT_DIG >= 113 + TEST_f_l (lrint, 0x7fffffffffffffff.7fffffffffffcp0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), +# endif +# endif +#endif +#ifdef TEST_LDOUBLE + TEST_f_l (lrint, -0x8000000000000001p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), +#endif +#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106 +# if LONG_MAX > 0x7fffffff + TEST_f_l (lrint, -0x8000000000000000.4p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION, LLONG_MIN, INEXACT_EXCEPTION|ERRNO_UNCHANGED, LLONG_MIN, INEXACT_EXCEPTION|ERRNO_UNCHANGED, LLONG_MIN, INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_f_l (lrint, -0x8000000000000000.7fffffffffcp0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION, LLONG_MIN, INEXACT_EXCEPTION|ERRNO_UNCHANGED, LLONG_MIN, INEXACT_EXCEPTION|ERRNO_UNCHANGED, LLONG_MIN, INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_f_l (lrint, -0x8000000000000000.8p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION, LLONG_MIN, INEXACT_EXCEPTION|ERRNO_UNCHANGED, LLONG_MIN, INEXACT_EXCEPTION|ERRNO_UNCHANGED, LLONG_MIN, INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_f_l (lrint, -0x8000000000000000.cp0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION, LLONG_MIN, INEXACT_EXCEPTION|ERRNO_UNCHANGED, LLONG_MIN, INEXACT_EXCEPTION|ERRNO_UNCHANGED), +# else + TEST_f_l (lrint, -0x8000000000000000.4p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_f_l (lrint, -0x8000000000000000.7fffffffffcp0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_f_l (lrint, -0x8000000000000000.8p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_f_l (lrint, -0x8000000000000000.cp0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), +# endif +#endif + TEST_f_l (lrint, -0x8000010000000000p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), +#ifndef TEST_FLOAT + TEST_f_l (lrint, -0x8000000000000800p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), +#endif +#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 113 +# if LONG_MAX > 0x7fffffff + TEST_f_l (lrint, -0x8000000000000000.7fffffffffff8p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION, LLONG_MIN, INEXACT_EXCEPTION|ERRNO_UNCHANGED, LLONG_MIN, INEXACT_EXCEPTION|ERRNO_UNCHANGED, LLONG_MIN, INEXACT_EXCEPTION|ERRNO_UNCHANGED), +# else + TEST_f_l (lrint, -0x8000000000000000.7fffffffffff8p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), +# endif +#endif TEST_f_l (lrint, 0.0, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_f_l (lrint, minus_zero, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_f_l (lrint, min_value, 0, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 1, INEXACT_EXCEPTION|ERRNO_UNCHANGED), @@ -7975,6 +8124,74 @@ static const struct test_f_L_data llrint_test_data[] = TEST_f_L (llrint, -0x1p63, LLONG_MIN, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_f_L (llrint, -0x1p64, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), TEST_f_L (llrint, -0x1p65, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_f_L (llrint, 0x7fffff80p0, 0x7fffff80LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), +#ifndef TEST_FLOAT + TEST_f_L (llrint, 0x7fffffffp0, 0x7fffffffLL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_f_L (llrint, 0x7fffffff.4p0, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_f_L (llrint, 0x7fffffff.7ffffcp0, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_f_L (llrint, 0x7fffffff.8p0, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_f_L (llrint, 0x7fffffff.cp0, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), +#endif +#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 64 + TEST_f_L (llrint, 0x7fffffff.7fffffff8p0L, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), +#endif +#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106 + TEST_f_L (llrint, 0x7fffffff.7fffffffffffffffffep0L, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), +#endif +#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 113 + TEST_f_L (llrint, 0x7fffffff.7fffffffffffffffffffcp0L, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), +#endif +#ifndef TEST_FLOAT + TEST_f_L (llrint, -0x80000000.4p0, -0x80000001LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_f_L (llrint, -0x80000000.7ffff8p0, -0x80000001LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_f_L (llrint, -0x80000000.8p0, -0x80000001LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_f_L (llrint, -0x80000000.cp0, -0x80000001LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000001LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_f_L (llrint, -0x80000001p0, -0x80000001LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), +#endif + TEST_f_L (llrint, -0x80000100p0, -0x80000100LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), +#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 64 + TEST_f_L (llrint, -0x80000000.7fffffffp0L, -0x80000001LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), +#endif +#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106 + TEST_f_L (llrint, -0x80000000.7fffffffffffffffffcp0L, -0x80000001LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), +#endif +#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 113 + TEST_f_L (llrint, -0x80000000.7fffffffffffffffffff8p0L, -0x80000001LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, -0x80000000LL, INEXACT_EXCEPTION|ERRNO_UNCHANGED), +#endif + TEST_f_L (llrint, 0x7fffff8000000000p0, 0x7fffff8000000000LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), +#ifndef TEST_FLOAT + TEST_f_L (llrint, 0x7ffffffffffffc00p0, 0x7ffffffffffffc00LL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), +#endif +#ifdef TEST_LDOUBLE + TEST_f_L (llrint, 0x7fffffffffffffffp0L, 0x7fffffffffffffffLL, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_f_L (llrint, 0x7fffffffffffffff.8p0L, 0x7fffffffffffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION, 0x7fffffffffffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), +# if LDBL_MANT_DIG > 64 + TEST_f_L (llrint, 0x7fffffffffffffff.4p0L, 0x7fffffffffffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffffffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffffffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), + TEST_f_L (llrint, 0x7fffffffffffffff.cp0L, 0x7fffffffffffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION, 0x7fffffffffffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), +# endif +# if LDBL_MANT_DIG >= 106 + TEST_f_L (llrint, 0x7fffffffffffffff.7fffffffffep0L, 0x7fffffffffffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffffffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffffffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), +# endif +# if LDBL_MANT_DIG >= 113 + TEST_f_L (llrint, 0x7fffffffffffffff.7fffffffffffcp0L, 0x7fffffffffffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffffffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0x7fffffffffffffffLL, INEXACT_EXCEPTION|ERRNO_UNCHANGED, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), +# endif +#endif +#ifdef TEST_LDOUBLE + TEST_f_L (llrint, -0x8000000000000001p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), +#endif +#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106 + TEST_f_L (llrint, -0x8000000000000000.4p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION, LLONG_MIN, INEXACT_EXCEPTION|ERRNO_UNCHANGED, LLONG_MIN, INEXACT_EXCEPTION|ERRNO_UNCHANGED, LLONG_MIN, INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_f_L (llrint, -0x8000000000000000.7fffffffffcp0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION, LLONG_MIN, INEXACT_EXCEPTION|ERRNO_UNCHANGED, LLONG_MIN, INEXACT_EXCEPTION|ERRNO_UNCHANGED, LLONG_MIN, INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_f_L (llrint, -0x8000000000000000.8p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION, LLONG_MIN, INEXACT_EXCEPTION|ERRNO_UNCHANGED, LLONG_MIN, INEXACT_EXCEPTION|ERRNO_UNCHANGED, LLONG_MIN, INEXACT_EXCEPTION|ERRNO_UNCHANGED), + TEST_f_L (llrint, -0x8000000000000000.cp0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION, LLONG_MIN, INEXACT_EXCEPTION|ERRNO_UNCHANGED, LLONG_MIN, INEXACT_EXCEPTION|ERRNO_UNCHANGED), +#endif + TEST_f_L (llrint, -0x8000010000000000p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), +#ifndef TEST_FLOAT + TEST_f_L (llrint, -0x8000000000000800p0, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION), +#endif +#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 113 + TEST_f_L (llrint, -0x8000000000000000.7fffffffffff8p0L, IGNORE, NO_INEXACT_EXCEPTION|INVALID_EXCEPTION, LLONG_MIN, INEXACT_EXCEPTION|ERRNO_UNCHANGED, LLONG_MIN, INEXACT_EXCEPTION|ERRNO_UNCHANGED, LLONG_MIN, INEXACT_EXCEPTION|ERRNO_UNCHANGED), +#endif TEST_f_L (llrint, 0.0, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_f_L (llrint, minus_zero, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), TEST_f_L (llrint, min_value, 0, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 0, INEXACT_EXCEPTION|ERRNO_UNCHANGED, 1, INEXACT_EXCEPTION|ERRNO_UNCHANGED), diff --git a/sysdeps/ieee754/dbl-64/s_lrint.c b/sysdeps/ieee754/dbl-64/s_lrint.c index 353d5f5..39f95ad 100644 --- a/sysdeps/ieee754/dbl-64/s_lrint.c +++ b/sysdeps/ieee754/dbl-64/s_lrint.c @@ -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> @@ -62,8 +64,22 @@ __lrint (double x) result = ((long int) i0 << (j0 - 20)) | (i1 << (j0 - 52)); else { - w = math_narrow_eval (two52[sx] + x); - t = w - two52[sx]; +#if defined FE_INVALID || defined FE_INEXACT + /* X < LONG_MAX + 1 implied by J0 < 31. */ + if (sizeof (long int) == 4 + && x > (double) LONG_MAX) + { + /* In the event of overflow we must raise the "invalid" + exception, but not "inexact". */ + t = __nearbyint (x); + feraiseexcept (t == LONG_MAX ? FE_INEXACT : FE_INVALID); + } + else +#endif + { + w = math_narrow_eval (two52[sx] + x); + t = w - two52[sx]; + } EXTRACT_WORDS (i0, i1, t); j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; i0 &= 0xfffff; @@ -77,8 +93,21 @@ __lrint (double x) } 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. */ +#if defined FE_INVALID || defined FE_INEXACT + if (sizeof (long int) == 4 + && x < (double) LONG_MIN + && x > (double) LONG_MIN - 1.0) + { + /* If truncation produces LONG_MIN, the cast will not raise + the exception, but may raise "inexact". */ + t = __nearbyint (x); + feraiseexcept (t == LONG_MIN ? FE_INEXACT : FE_INVALID); + return LONG_MIN; + } +#endif return (long int) x; } diff --git a/sysdeps/ieee754/ldbl-128/s_llrintl.c b/sysdeps/ieee754/ldbl-128/s_llrintl.c index 77eb2d6..b9e2178 100644 --- a/sysdeps/ieee754/ldbl-128/s_llrintl.c +++ b/sysdeps/ieee754/ldbl-128/s_llrintl.c @@ -19,6 +19,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,8 +49,21 @@ __llrintl (long double x) if (j0 < (int32_t) (8 * sizeof (long long int)) - 1) { - w = two112[sx] + x; - t = w - two112[sx]; +#if defined FE_INVALID || defined FE_INEXACT + /* X < LLONG_MAX + 1 implied by J0 < 63. */ + if (x > (long double) LLONG_MAX) + { + /* In the event of overflow we must raise the "invalid" + exception, but not "inexact". */ + t = __nearbyintl (x); + feraiseexcept (t == LLONG_MAX ? FE_INEXACT : FE_INVALID); + } + else +#endif + { + w = two112[sx] + x; + t = w - two112[sx]; + } GET_LDOUBLE_WORDS64 (i0, i1, t); j0 = ((i0 >> 48) & 0x7fff) - 0x3fff; i0 &= 0x0000ffffffffffffLL; @@ -63,8 +78,20 @@ __llrintl (long double x) } 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. */ +#if defined FE_INVALID || defined FE_INEXACT + if (x < (long double) LLONG_MIN + && x > (long double) LLONG_MIN - 1.0L) + { + /* If truncation produces LLONG_MIN, the cast will not raise + the exception, but may raise "inexact". */ + t = __nearbyintl (x); + feraiseexcept (t == LLONG_MIN ? FE_INEXACT : FE_INVALID); + return LLONG_MIN; + } +#endif return (long long int) x; } diff --git a/sysdeps/ieee754/ldbl-128/s_lrintl.c b/sysdeps/ieee754/ldbl-128/s_lrintl.c index d0b0aeb..cb5a75b 100644 --- a/sysdeps/ieee754/ldbl-128/s_lrintl.c +++ b/sysdeps/ieee754/ldbl-128/s_lrintl.c @@ -19,6 +19,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,8 +51,22 @@ __lrintl (long double x) { if (j0 < 48) { - w = two112[sx] + x; - t = w - two112[sx]; +#if defined FE_INVALID || defined FE_INEXACT + /* X < LONG_MAX + 1 implied by J0 < 31. */ + if (sizeof (long int) == 4 + && x > (long double) LONG_MAX) + { + /* In the event of overflow we must raise the "invalid" + exception, but not "inexact". */ + t = __nearbyintl (x); + feraiseexcept (t == LONG_MAX ? FE_INEXACT : FE_INVALID); + } + else +#endif + { + w = two112[sx] + x; + t = w - two112[sx]; + } GET_LDOUBLE_WORDS64 (i0, i1, t); j0 = ((i0 >> 48) & 0x7fff) - 0x3fff; i0 &= 0x0000ffffffffffffLL; @@ -62,8 +78,22 @@ __lrintl (long double x) result = ((long int) i0 << (j0 - 48)) | (i1 << (j0 - 112)); else { - w = two112[sx] + x; - t = w - two112[sx]; +#if defined FE_INVALID || defined FE_INEXACT + /* X < LONG_MAX + 1 implied by J0 < 63. */ + if (sizeof (long int) == 8 + && x > (long double) LONG_MAX) + { + /* In the event of overflow we must raise the "invalid" + exception, but not "inexact". */ + t = __nearbyintl (x); + feraiseexcept (t == LONG_MAX ? FE_INEXACT : FE_INVALID); + } + else +#endif + { + w = two112[sx] + x; + t = w - two112[sx]; + } GET_LDOUBLE_WORDS64 (i0, i1, t); j0 = ((i0 >> 48) & 0x7fff) - 0x3fff; i0 &= 0x0000ffffffffffffLL; @@ -77,8 +107,20 @@ __lrintl (long double x) } 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. */ +#if defined FE_INVALID || defined FE_INEXACT + if (x < (long double) LONG_MIN + && x > (long double) LONG_MIN - 1.0L) + { + /* If truncation produces LONG_MIN, the cast will not raise + the exception, but may raise "inexact". */ + t = __nearbyintl (x); + feraiseexcept (t == LONG_MIN ? FE_INEXACT : FE_INVALID); + return LONG_MIN; + } +#endif return (long int) x; } diff --git a/sysdeps/ieee754/ldbl-96/s_llrintl.c b/sysdeps/ieee754/ldbl-96/s_llrintl.c index c73741e..e3faa21 100644 --- a/sysdeps/ieee754/ldbl-96/s_llrintl.c +++ b/sysdeps/ieee754/ldbl-96/s_llrintl.c @@ -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> @@ -50,8 +52,21 @@ __llrintl (long double x) result = (((long long int) i0 << 32) | i1) << (j0 - 63); else { - w = two63[sx] + x; - t = w - two63[sx]; +#if defined FE_INVALID || defined FE_INEXACT + /* X < LLONG_MAX + 1 implied by J0 < 63. */ + if (x > (long double) LLONG_MAX) + { + /* In the event of overflow we must raise the "invalid" + exception, but not "inexact". */ + t = __nearbyintl (x); + feraiseexcept (t == LLONG_MAX ? FE_INEXACT : FE_INVALID); + } + else +#endif + { + w = two63[sx] + x; + t = w - two63[sx]; + } GET_LDOUBLE_WORDS (se, i0, i1, t); j0 = (se & 0x7fff) - 0x3fff; diff --git a/sysdeps/ieee754/ldbl-96/s_lrintl.c b/sysdeps/ieee754/ldbl-96/s_lrintl.c index 598423b..4dd1993 100644 --- a/sysdeps/ieee754/ldbl-96/s_lrintl.c +++ b/sysdeps/ieee754/ldbl-96/s_lrintl.c @@ -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> @@ -46,8 +48,22 @@ __lrintl (long double x) if (j0 < 31) { - w = two63[sx] + x; - t = w - two63[sx]; +#if defined FE_INVALID || defined FE_INEXACT + /* X < LONG_MAX + 1 implied by J0 < 31. */ + if (sizeof (long int) == 4 + && x > (long double) LONG_MAX) + { + /* In the event of overflow we must raise the "invalid" + exception, but not "inexact". */ + t = __nearbyintl (x); + feraiseexcept (t == LONG_MAX ? FE_INEXACT : FE_INVALID); + } + else +#endif + { + w = two63[sx] + x; + t = w - two63[sx]; + } GET_LDOUBLE_WORDS (se, i0, i1, t); j0 = (se & 0x7fff) - 0x3fff; @@ -59,8 +75,22 @@ __lrintl (long double x) result = ((long int) i0 << (j0 - 31)) | (i1 << (j0 - 63)); else { - w = two63[sx] + x; - t = w - two63[sx]; +#if defined FE_INVALID || defined FE_INEXACT + /* X < LONG_MAX + 1 implied by J0 < 63. */ + if (sizeof (long int) == 8 + && x > (long double) LONG_MAX) + { + /* In the event of overflow we must raise the "invalid" + exception, but not "inexact". */ + t = __nearbyintl (x); + feraiseexcept (t == LONG_MAX ? FE_INEXACT : FE_INVALID); + } + else +#endif + { + w = two63[sx] + x; + t = w - two63[sx]; + } GET_LDOUBLE_WORDS (se, i0, i1, t); j0 = (se & 0x7fff) - 0x3fff; @@ -72,8 +102,21 @@ __lrintl (long double x) } 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. */ +#if defined FE_INVALID || defined FE_INEXACT + if (sizeof (long int) == 4 + && x < (long double) LONG_MIN + && x > (long double) LONG_MIN - 1.0L) + { + /* If truncation produces LONG_MIN, the cast will not raise + the exception, but may raise "inexact". */ + t = __nearbyintl (x); + feraiseexcept (t == LONG_MIN ? FE_INEXACT : FE_INVALID); + return LONG_MIN; + } +#endif return (long int) x; } |