mirror of
https://github.com/opnsense/src.git
synced 2026-06-08 16:22:46 -04:00
Fix incorrect hypotl(3) result with subnormal numbers
This adjusts the factor used to scale the subnormal numbers, so it becomes the right value after adjusting its exponent. Thanks to Steve Kargl for finding the most elegant fix. Also enable the hypot tests, and add a test case for this bug. PR: 253313 (cherry picked from commitd3338f3355) Fix lib/msun/test builds on platforms without 80-bit long doubles Afterd3338f3355, the lib/msun test case 'hypotl_near_underflow' would fail to compile on platforms where long doubles weren't 80 bit, like on x86. Disable this particular test on such platforms for now. PR: 253313 (cherry picked from commit2512066228)
This commit is contained in:
parent
c558999977
commit
97232b0dc0
3 changed files with 26 additions and 1 deletions
|
|
@ -70,12 +70,36 @@ ATF_TC_BODY(pr50698, tc)
|
|||
ATF_CHECK(!isnan(val));
|
||||
}
|
||||
|
||||
#if __LDBL_MANT_DIG__ == 64
|
||||
ATF_TC(hypotl_near_underflow);
|
||||
ATF_TC_HEAD(hypotl_near_underflow, tc)
|
||||
{
|
||||
atf_tc_set_md_var(tc, "descr", "Test hypotl near underflow");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(hypotl_near_underflow, tc)
|
||||
{
|
||||
volatile long double a = 0x1.b2933cafa0bb7p-16383L;
|
||||
volatile long double b = 0x1.fffffffffffffp-16351L;
|
||||
volatile long double e = 0x1.fffffffffffffp-16351L;
|
||||
volatile long double ulp = __LDBL_EPSILON__;
|
||||
|
||||
volatile long double val = hypotl(a, b);
|
||||
|
||||
ATF_CHECK(!isinf(val));
|
||||
ATF_CHECK(fabsl(val - e) <= 2 * ulp);
|
||||
}
|
||||
#endif /* __LDBL_MANT_DIG__ == 64 */
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
|
||||
ATF_TP_ADD_TC(tp, hypot_integer);
|
||||
ATF_TP_ADD_TC(tp, hypotf_integer);
|
||||
ATF_TP_ADD_TC(tp, pr50698);
|
||||
#if __LDBL_MANT_DIG__ == 64
|
||||
ATF_TP_ADD_TC(tp, hypotl_near_underflow);
|
||||
#endif /* __LDBL_MANT_DIG__ == 64 */
|
||||
|
||||
return atf_no_error();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ hypotl(long double x, long double y)
|
|||
man_t manh, manl;
|
||||
GET_LDBL_MAN(manh,manl,b);
|
||||
if((manh|manl)==0) return a;
|
||||
t1=0;
|
||||
t1=1;
|
||||
SET_HIGH_WORD(t1,ESW(MAX_EXP-2)); /* t1=2^(MAX_EXP-2) */
|
||||
b *= t1;
|
||||
a *= t1;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ NETBSD_ATF_TESTS_C+= erf_test
|
|||
NETBSD_ATF_TESTS_C+= exp_test
|
||||
NETBSD_ATF_TESTS_C+= fmod_test
|
||||
NETBSD_ATF_TESTS_C+= fe_round_test
|
||||
NETBSD_ATF_TESTS_C+= hypot_test
|
||||
NETBSD_ATF_TESTS_C+= infinity_test
|
||||
NETBSD_ATF_TESTS_C+= ilogb_test
|
||||
NETBSD_ATF_TESTS_C+= ldexp_test
|
||||
|
|
|
|||
Loading…
Reference in a new issue