Changeset View
Changeset View
Standalone View
Standalone View
lib/msun/tests/exponential_test.c
Show All 25 Lines | |||||
/* | /* | ||||
* Tests for corner cases in exp*(). | * Tests for corner cases in exp*(). | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <assert.h> | |||||
#include <fenv.h> | #include <fenv.h> | ||||
#include <float.h> | #include <float.h> | ||||
#include <math.h> | #include <math.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#ifdef __i386__ | #ifdef __i386__ | ||||
#include <ieeefp.h> | #include <ieeefp.h> | ||||
#endif | #endif | ||||
Show All 12 Lines | |||||
* These are macros instead of functions so that assert provides more | * These are macros instead of functions so that assert provides more | ||||
* meaningful error messages. | * meaningful error messages. | ||||
* | * | ||||
* XXX The volatile here is to avoid gcc's bogus constant folding and work | * XXX The volatile here is to avoid gcc's bogus constant folding and work | ||||
* around the lack of support for the FENV_ACCESS pragma. | * around the lack of support for the FENV_ACCESS pragma. | ||||
*/ | */ | ||||
#define test(func, x, result, exceptmask, excepts) do { \ | #define test(func, x, result, exceptmask, excepts) do { \ | ||||
volatile long double _d = x; \ | volatile long double _d = x; \ | ||||
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \ | ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT)); \ | ||||
assert(fpequal((func)(_d), (result))); \ | ATF_CHECK(fpequal((func)(_d), (result))); \ | ||||
assert(((void)(func), fetestexcept(exceptmask) == (excepts))); \ | CHECK_FP_EXCEPTIONS_MSG(excepts, exceptmask, "for %s(%s)", \ | ||||
#func, #x); \ | |||||
} while (0) | } while (0) | ||||
/* Test all the functions that compute b^x. */ | /* Test all the functions that compute b^x. */ | ||||
#define _testall0(x, result, exceptmask, excepts) do { \ | #define _testall0(x, result, exceptmask, excepts) do { \ | ||||
test(exp, x, result, exceptmask, excepts); \ | test(exp, x, result, exceptmask, excepts); \ | ||||
test(expf, x, result, exceptmask, excepts); \ | test(expf, x, result, exceptmask, excepts); \ | ||||
test(exp2, x, result, exceptmask, excepts); \ | test(exp2, x, result, exceptmask, excepts); \ | ||||
test(exp2f, x, result, exceptmask, excepts); \ | test(exp2f, x, result, exceptmask, excepts); \ | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | #if !defined(__i386__) | ||||
testall1(50000.0, INFINITY, ALL_STD_EXCEPT & ~FE_INEXACT, FE_OVERFLOW); | testall1(50000.0, INFINITY, ALL_STD_EXCEPT & ~FE_INEXACT, FE_OVERFLOW); | ||||
/* exp(small) == 0, underflow and inexact exceptions */ | /* exp(small) == 0, underflow and inexact exceptions */ | ||||
testall0(-50000.0, 0.0, ALL_STD_EXCEPT, FE_UNDERFLOW | FE_INEXACT); | testall0(-50000.0, 0.0, ALL_STD_EXCEPT, FE_UNDERFLOW | FE_INEXACT); | ||||
#endif | #endif | ||||
testall1(-50000.0, -1.0, ALL_STD_EXCEPT, FE_INEXACT); | testall1(-50000.0, -1.0, ALL_STD_EXCEPT, FE_INEXACT); | ||||
} | } | ||||
static void | |||||
run_exp2_tests(void) | |||||
{ | |||||
unsigned i; | |||||
/* | /* | ||||
* We should insist that exp2() return exactly the correct | * We should insist that exp2() return exactly the correct | ||||
* result and not raise an inexact exception for integer | * result and not raise an inexact exception for integer | ||||
* arguments. | * arguments. | ||||
*/ | */ | ||||
feclearexcept(FE_ALL_EXCEPT); | ATF_TC_WITHOUT_HEAD(exp2f); | ||||
for (i = FLT_MIN_EXP - FLT_MANT_DIG; i < FLT_MAX_EXP; i++) { | ATF_TC_BODY(exp2f, tc) | ||||
assert(exp2f(i) == ldexpf(1.0, i)); | { | ||||
assert(fetestexcept(ALL_STD_EXCEPT) == 0); | ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT)); | ||||
for (int i = FLT_MIN_EXP - FLT_MANT_DIG; i < FLT_MAX_EXP; i++) { | |||||
ATF_CHECK_EQ(exp2f(i), ldexpf(1.0, i)); | |||||
CHECK_FP_EXCEPTIONS(0, ALL_STD_EXCEPT); | |||||
} | } | ||||
for (i = DBL_MIN_EXP - DBL_MANT_DIG; i < DBL_MAX_EXP; i++) { | |||||
assert(exp2(i) == ldexp(1.0, i)); | |||||
assert(fetestexcept(ALL_STD_EXCEPT) == 0); | |||||
} | } | ||||
for (i = LDBL_MIN_EXP - LDBL_MANT_DIG; i < LDBL_MAX_EXP; i++) { | |||||
assert(exp2l(i) == ldexpl(1.0, i)); | ATF_TC_WITHOUT_HEAD(exp2); | ||||
assert(fetestexcept(ALL_STD_EXCEPT) == 0); | ATF_TC_BODY(exp2, tc) | ||||
{ | |||||
ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT)); | |||||
for (int i = DBL_MIN_EXP - DBL_MANT_DIG; i < DBL_MAX_EXP; i++) { | |||||
ATF_CHECK_EQ(exp2(i), ldexp(1.0, i)); | |||||
CHECK_FP_EXCEPTIONS(0, ALL_STD_EXCEPT); | |||||
} | } | ||||
} | } | ||||
int | ATF_TC_WITHOUT_HEAD(exp2l); | ||||
main(void) | ATF_TC_BODY(exp2l, tc) | ||||
{ | { | ||||
ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT)); | |||||
for (int i = LDBL_MIN_EXP - LDBL_MANT_DIG; i < LDBL_MAX_EXP; i++) { | |||||
ATF_CHECK_EQ(exp2l(i), ldexpl(1.0, i)); | |||||
CHECK_FP_EXCEPTIONS(0, ALL_STD_EXCEPT); | |||||
} | |||||
} | |||||
printf("1..3\n"); | ATF_TC_WITHOUT_HEAD(generic); | ||||
ATF_TC_BODY(generic, tc) | |||||
{ | |||||
run_generic_tests(); | run_generic_tests(); | ||||
printf("ok 1 - exponential\n"); | } | ||||
#ifdef __i386__ | #ifdef __i386__ | ||||
ATF_TC_WITHOUT_HEAD(generic_fp_pe); | |||||
ATF_TC_BODY(generic_fp_pe, tc) | |||||
{ | |||||
fpsetprec(FP_PE); | fpsetprec(FP_PE); | ||||
run_generic_tests(); | run_generic_tests(); | ||||
} | |||||
#endif | #endif | ||||
printf("ok 2 - exponential\n"); | |||||
run_exp2_tests(); | ATF_TP_ADD_TCS(tp) | ||||
printf("ok 3 - exponential\n"); | { | ||||
ATF_TP_ADD_TC(tp, generic); | |||||
#ifdef __i386__ | |||||
ATF_TP_ADD_TC(tp, generic_fp_pe); | |||||
#endif | |||||
ATF_TP_ADD_TC(tp, exp2); | |||||
ATF_TP_ADD_TC(tp, exp2f); | |||||
ATF_TP_ADD_TC(tp, exp2l); | |||||
ngie: These tests should be split up, otherwise a single assertion failure will tank the rest of the… | |||||
return (0); | return (atf_no_error()); | ||||
} | } |
These tests should be split up, otherwise a single assertion failure will tank the rest of the test program.