mirror of
https://sourceware.org/git/glibc.git
synced 2025-01-03 16:21:06 +00:00
Fix exp2l inaccuracy (bug 13824).
This commit is contained in:
parent
c0df8e693f
commit
48e44791e4
@ -1,5 +1,12 @@
|
||||
2012-03-22 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
[BZ #13824]
|
||||
* math/e_exp2l.c: Include <float.h>.
|
||||
(__ieee754_exp2l): Handle overflow and underflow cases
|
||||
separately. Only pass fractional part of argument to
|
||||
__ieee754_expl.
|
||||
* math/libm-test.inc (exp2_test): Add more tests.
|
||||
|
||||
* sysdeps/ieee754/ldbl-128/k_cosl.c (__kernel_cosl): Negate y if
|
||||
negating x to take absolute value.
|
||||
* sysdeps/ieee754/ldbl-128/k_sincosl.c (__kernel_sincosl):
|
||||
|
12
NEWS
12
NEWS
@ -11,12 +11,12 @@ Version 2.16
|
||||
|
||||
174, 350, 411, 2541, 2547, 2548, 2551, 2552, 2553, 2554, 2562, 2563, 2565,
|
||||
2566, 2576, 3335, 3976, 3992, 4026, 4108, 4596, 4822, 5077, 5461, 5805,
|
||||
5993, 6471, 6730, 6884, 6907, 6911, 9739, 9902, 10110, 10135, 10140, 10210,
|
||||
10545, 10716, 11174, 11322, 11365, 11451, 11494, 12047, 13058, 13525,
|
||||
13526, 13527, 13528, 13529, 13530, 13531, 13532, 13533, 13547, 13551,
|
||||
13552, 13553, 13555, 13559, 13566, 13583, 13618, 13637, 13656, 13658,
|
||||
13673, 13695, 13704, 13706, 13726, 13738, 13786, 13792, 13806, 13840,
|
||||
13841, 13844, 13846, 13851, 13852, 13854, 13871, 13883
|
||||
5993, 6471, 6730, 6884, 6907, 6911, 9739, 9902, 10110, 10135, 10140,
|
||||
10210, 10545, 10716, 11174, 11322, 11365, 11451, 11494, 12047, 13058,
|
||||
13525, 13526, 13527, 13528, 13529, 13530, 13531, 13532, 13533, 13547,
|
||||
13551, 13552, 13553, 13555, 13559, 13566, 13583, 13618, 13637, 13656,
|
||||
13658, 13673, 13695, 13704, 13706, 13726, 13738, 13786, 13792, 13806,
|
||||
13824, 13840, 13841, 13844, 13846, 13851, 13852, 13854, 13871, 13883
|
||||
|
||||
* ISO C11 support:
|
||||
|
||||
|
@ -1,11 +1,49 @@
|
||||
/* Compute 2^x.
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <math.h>
|
||||
#include <math_private.h>
|
||||
#include <float.h>
|
||||
|
||||
long double
|
||||
__ieee754_exp2l (long double x)
|
||||
{
|
||||
/* This is a very stupid and inprecise implementation. It'll get
|
||||
replaced sometime (soon?). */
|
||||
return __ieee754_expl (M_LN2l * x);
|
||||
if (__builtin_expect (isless (x, (long double) LDBL_MAX_EXP), 1))
|
||||
{
|
||||
if (__builtin_expect (isgreaterequal (x, (long double) (LDBL_MIN_EXP
|
||||
- LDBL_MANT_DIG
|
||||
- 1)), 1))
|
||||
{
|
||||
int intx = (int) x;
|
||||
long double fractx = x - intx;
|
||||
return __scalbnl (__ieee754_expl (M_LN2l * fractx), intx);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Underflow or exact zero. */
|
||||
if (__isinfl (x))
|
||||
return 0;
|
||||
else
|
||||
return LDBL_MIN * LDBL_MIN;
|
||||
}
|
||||
}
|
||||
else
|
||||
/* Infinity, NaN or overflow. */
|
||||
return LDBL_MAX * x;
|
||||
}
|
||||
strong_alias (__ieee754_exp2l, __exp2l_finite)
|
||||
|
@ -3127,6 +3127,21 @@ exp2_test (void)
|
||||
TEST_f_f (exp2, -1e6, 0);
|
||||
TEST_f_f (exp2, 0.75L, 1.68179283050742908606225095246642979L);
|
||||
|
||||
TEST_f_f (exp2, 100.5, 1.792728671193156477399422023278661496394e+30L);
|
||||
TEST_f_f (exp2, 127, 0x1p127);
|
||||
TEST_f_f (exp2, -149, 0x1p-149);
|
||||
|
||||
#ifndef TEST_FLOAT
|
||||
TEST_f_f (exp2, 1000.25, 1.274245659452564874772384918171765416737e+301L);
|
||||
TEST_f_f (exp2, 1023, 0x1p1023);
|
||||
TEST_f_f (exp2, -1074, 0x1p-1074);
|
||||
#endif
|
||||
|
||||
#if defined TEST_LDOUBLE && LDBL_MAX_EXP >= 16384
|
||||
TEST_f_f (exp2, 16383, 0x1p16383L);
|
||||
TEST_f_f (exp2, -16400, 0x1p-16400L);
|
||||
#endif
|
||||
|
||||
END (exp2);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user