Changeset View
Changeset View
Standalone View
Standalone View
lib/msun/tests/invctrig_test.c
Show All 26 Lines | |||||
/* | /* | ||||
* Tests for casin[h](), cacos[h](), and catan[h](). | * Tests for casin[h](), cacos[h](), and catan[h](). | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <assert.h> | |||||
#include <complex.h> | #include <complex.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> | ||||
#include "test-utils.h" | #include "test-utils.h" | ||||
Show All 12 Lines | |||||
* | * | ||||
* 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_p(func, z, result, exceptmask, excepts, checksign) do { \ | #define test_p(func, z, result, exceptmask, excepts, checksign) do { \ | ||||
volatile long double complex _d = z; \ | volatile long double complex _d = z; \ | ||||
debug(" testing %s(%Lg + %Lg I) == %Lg + %Lg I\n", #func, \ | debug(" testing %s(%Lg + %Lg I) == %Lg + %Lg I\n", #func, \ | ||||
creall(_d), cimagl(_d), creall(result), cimagl(result)); \ | creall(_d), cimagl(_d), creall(result), cimagl(result)); \ | ||||
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \ | ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT)); \ | ||||
assert(cfpequal_cs((func)(_d), (result), (checksign))); \ | ATF_CHECK(cfpequal_cs((func)(_d), (result), (checksign))); \ | ||||
assert(((void)(func), fetestexcept(exceptmask) == (excepts))); \ | CHECK_FP_EXCEPTIONS_MSG(excepts, exceptmask, "for %s(%s)", \ | ||||
#func, #z); \ | |||||
} while (0) | } while (0) | ||||
/* | /* | ||||
* Test within a given tolerance. The tolerance indicates relative error | * Test within a given tolerance. The tolerance indicates relative error | ||||
* in ulps. | * in ulps. | ||||
*/ | */ | ||||
#define test_p_tol(func, z, result, tol) do { \ | #define test_p_tol(func, z, result, tol) do { \ | ||||
volatile long double complex _d = z; \ | volatile long double complex _d = z; \ | ||||
debug(" testing %s(%Lg + %Lg I) ~= %Lg + %Lg I\n", #func, \ | debug(" testing %s(%Lg + %Lg I) ~= %Lg + %Lg I\n", #func, \ | ||||
creall(_d), cimagl(_d), creall(result), cimagl(result)); \ | creall(_d), cimagl(_d), creall(result), cimagl(result)); \ | ||||
assert(cfpequal_tol((func)(_d), (result), (tol), CS_BOTH)); \ | ATF_CHECK(cfpequal_tol((func)(_d), (result), (tol), CS_BOTH)); \ | ||||
} while (0) | } while (0) | ||||
/* These wrappers apply the identities f(conj(z)) = conj(f(z)). */ | /* These wrappers apply the identities f(conj(z)) = conj(f(z)). */ | ||||
#define test(func, z, result, exceptmask, excepts, checksign) do { \ | #define test(func, z, result, exceptmask, excepts, checksign) do { \ | ||||
test_p(func, z, result, exceptmask, excepts, checksign); \ | test_p(func, z, result, exceptmask, excepts, checksign); \ | ||||
test_p(func, conjl(z), conjl(result), exceptmask, excepts, checksign); \ | test_p(func, conjl(z), conjl(result), exceptmask, excepts, checksign); \ | ||||
} while (0) | } while (0) | ||||
#define test_tol(func, z, result, tol) do { \ | #define test_tol(func, z, result, tol) do { \ | ||||
Show All 33 Lines | |||||
} while (0) | } while (0) | ||||
static const long double | static const long double | ||||
pi = 3.14159265358979323846264338327950280L, | pi = 3.14159265358979323846264338327950280L, | ||||
c3pi = 9.42477796076937971538793014983850839L; | c3pi = 9.42477796076937971538793014983850839L; | ||||
/* Tests for 0 */ | /* Tests for 0 */ | ||||
static void | ATF_TC_WITHOUT_HEAD(zero); | ||||
test_zero(void) | ATF_TC_BODY(zero, tc) | ||||
{ | { | ||||
long double complex zero = CMPLXL(0.0, 0.0); | long double complex zero = CMPLXL(0.0, 0.0); | ||||
testall_tol(cacosh, zero, CMPLXL(0.0, pi / 2), 1); | testall_tol(cacosh, zero, CMPLXL(0.0, pi / 2), 1); | ||||
testall_tol(cacosh, -zero, CMPLXL(0.0, -pi / 2), 1); | testall_tol(cacosh, -zero, CMPLXL(0.0, -pi / 2), 1); | ||||
testall_tol(cacos, zero, CMPLXL(pi / 2, -0.0), 1); | testall_tol(cacos, zero, CMPLXL(pi / 2, -0.0), 1); | ||||
testall_tol(cacos, -zero, CMPLXL(pi / 2, 0.0), 1); | testall_tol(cacos, -zero, CMPLXL(pi / 2, 0.0), 1); | ||||
testall_odd(casinh, zero, zero, ALL_STD_EXCEPT, 0, CS_BOTH); | testall_odd(casinh, zero, zero, ALL_STD_EXCEPT, 0, CS_BOTH); | ||||
testall_odd(casin, zero, zero, ALL_STD_EXCEPT, 0, CS_BOTH); | testall_odd(casin, zero, zero, ALL_STD_EXCEPT, 0, CS_BOTH); | ||||
testall_odd(catanh, zero, zero, ALL_STD_EXCEPT, 0, CS_BOTH); | testall_odd(catanh, zero, zero, ALL_STD_EXCEPT, 0, CS_BOTH); | ||||
testall_odd(catan, zero, zero, ALL_STD_EXCEPT, 0, CS_BOTH); | testall_odd(catan, zero, zero, ALL_STD_EXCEPT, 0, CS_BOTH); | ||||
} | } | ||||
/* | /* | ||||
* Tests for NaN inputs. | * Tests for NaN inputs. | ||||
*/ | */ | ||||
static void | ATF_TC_WITHOUT_HEAD(nan); | ||||
test_nan(void) | ATF_TC_BODY(nan, tc) | ||||
{ | { | ||||
long double complex nan_nan = CMPLXL(NAN, NAN); | long double complex nan_nan = CMPLXL(NAN, NAN); | ||||
long double complex z; | long double complex z; | ||||
/* | /* | ||||
* IN CACOSH CACOS CASINH CATANH | * IN CACOSH CACOS CASINH CATANH | ||||
* NaN,NaN NaN,NaN NaN,NaN NaN,NaN NaN,NaN | * NaN,NaN NaN,NaN NaN,NaN NaN,NaN NaN,NaN | ||||
* finite,NaN NaN,NaN* NaN,NaN* NaN,NaN* NaN,NaN* | * finite,NaN NaN,NaN* NaN,NaN* NaN,NaN* NaN,NaN* | ||||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | ATF_TC_BODY(nan, tc) | ||||
testall(cacosh, z, nan_nan, OPT_INVALID, 0, 0); | testall(cacosh, z, nan_nan, OPT_INVALID, 0, 0); | ||||
testall(cacos, z, nan_nan, OPT_INVALID, 0, 0); | testall(cacos, z, nan_nan, OPT_INVALID, 0, 0); | ||||
testall(casinh, z, CMPLXL(NAN, 0), ALL_STD_EXCEPT, 0, CS_IMAG); | testall(casinh, z, CMPLXL(NAN, 0), ALL_STD_EXCEPT, 0, CS_IMAG); | ||||
testall(casin, z, nan_nan, OPT_INVALID, 0, 0); | testall(casin, z, nan_nan, OPT_INVALID, 0, 0); | ||||
testall(catanh, z, nan_nan, OPT_INVALID, 0, CS_IMAG); | testall(catanh, z, nan_nan, OPT_INVALID, 0, CS_IMAG); | ||||
testall(catan, z, CMPLXL(NAN, 0.0), ALL_STD_EXCEPT, 0, 0); | testall(catan, z, CMPLXL(NAN, 0.0), ALL_STD_EXCEPT, 0, 0); | ||||
} | } | ||||
static void | ATF_TC_WITHOUT_HEAD(inf); | ||||
test_inf(void) | ATF_TC_BODY(inf, tc) | ||||
{ | { | ||||
long double complex z; | long double complex z; | ||||
/* | /* | ||||
* IN CACOSH CACOS CASINH CATANH | * IN CACOSH CACOS CASINH CATANH | ||||
* Inf,Inf Inf,pi/4 pi/4,-Inf Inf,pi/4 0,pi/2 | * Inf,Inf Inf,pi/4 pi/4,-Inf Inf,pi/4 0,pi/2 | ||||
* -Inf,Inf Inf,3pi/4 3pi/4,-Inf --- --- | * -Inf,Inf Inf,3pi/4 3pi/4,-Inf --- --- | ||||
* Inf,finite Inf,0 0,-Inf Inf,0 0,pi/2 | * Inf,finite Inf,0 0,-Inf Inf,0 0,pi/2 | ||||
Show All 29 Lines | ATF_TC_BODY(inf, tc) | ||||
testall_odd_tol(casinh, z, CMPLXL(INFINITY, pi / 2), 1); | testall_odd_tol(casinh, z, CMPLXL(INFINITY, pi / 2), 1); | ||||
/* XXX We allow a spurious inexact exception here. */ | /* XXX We allow a spurious inexact exception here. */ | ||||
testall_odd(casin, z, CMPLXL(0.0, INFINITY), OPT_INEXACT, 0, CS_BOTH); | testall_odd(casin, z, CMPLXL(0.0, INFINITY), OPT_INEXACT, 0, CS_BOTH); | ||||
testall_odd_tol(catanh, z, CMPLXL(0, pi / 2), 1); | testall_odd_tol(catanh, z, CMPLXL(0, pi / 2), 1); | ||||
testall_odd_tol(catan, z, CMPLXL(pi / 2, 0), 1); | testall_odd_tol(catan, z, CMPLXL(pi / 2, 0), 1); | ||||
} | } | ||||
/* Tests along the real and imaginary axes. */ | /* Tests along the real and imaginary axes. */ | ||||
static void | ATF_TC_WITHOUT_HEAD(axes); | ||||
test_axes(void) | ATF_TC_BODY(axes, tc) | ||||
{ | { | ||||
static const long double nums[] = { | static const long double nums[] = { | ||||
-2, -1, -0.5, 0.5, 1, 2 | -2, -1, -0.5, 0.5, 1, 2 | ||||
}; | }; | ||||
long double complex z; | long double complex z; | ||||
unsigned i; | unsigned i; | ||||
for (i = 0; i < nitems(nums); i++) { | for (i = 0; i < nitems(nums); i++) { | ||||
Show All 19 Lines | for (i = 0; i < nitems(nums); i++) { | ||||
} | } | ||||
testall_tol(casinh, z, CMPLXL(asinh(nums[i]), 0.0), 1); | testall_tol(casinh, z, CMPLXL(asinh(nums[i]), 0.0), 1); | ||||
testall_tol(catan, z, CMPLXL(atan(nums[i]), 0), 1); | testall_tol(catan, z, CMPLXL(atan(nums[i]), 0), 1); | ||||
/* TODO: Test the imaginary axis. */ | /* TODO: Test the imaginary axis. */ | ||||
} | } | ||||
} | } | ||||
static void | ATF_TC_WITHOUT_HEAD(small); | ||||
test_small(void) | ATF_TC_BODY(small, tc) | ||||
{ | { | ||||
/* | /* | ||||
* z = 0.75 + i 0.25 | * z = 0.75 + i 0.25 | ||||
* acos(z) = Pi/4 - i ln(2)/2 | * acos(z) = Pi/4 - i ln(2)/2 | ||||
* asin(z) = Pi/4 + i ln(2)/2 | * asin(z) = Pi/4 + i ln(2)/2 | ||||
* atan(z) = atan(4)/2 + i ln(17/9)/4 | * atan(z) = atan(4)/2 + i ln(17/9)/4 | ||||
*/ | */ | ||||
complex long double z; | complex long double z; | ||||
complex long double acos_z; | complex long double acos_z; | ||||
complex long double asin_z; | complex long double asin_z; | ||||
complex long double atan_z; | complex long double atan_z; | ||||
z = CMPLXL(0.75L, 0.25L); | z = CMPLXL(0.75L, 0.25L); | ||||
acos_z = CMPLXL(pi / 4, -0.34657359027997265470861606072908828L); | acos_z = CMPLXL(pi / 4, -0.34657359027997265470861606072908828L); | ||||
asin_z = CMPLXL(pi / 4, 0.34657359027997265470861606072908828L); | asin_z = CMPLXL(pi / 4, 0.34657359027997265470861606072908828L); | ||||
atan_z = CMPLXL(0.66290883183401623252961960521423782L, | atan_z = CMPLXL(0.66290883183401623252961960521423782L, | ||||
0.15899719167999917436476103600701878L); | 0.15899719167999917436476103600701878L); | ||||
testall_tol(cacos, z, acos_z, 2); | testall_tol(cacos, z, acos_z, 2); | ||||
testall_odd_tol(casin, z, asin_z, 2); | testall_odd_tol(casin, z, asin_z, 2); | ||||
testall_odd_tol(catan, z, atan_z, 2); | testall_odd_tol(catan, z, atan_z, 2); | ||||
} | } | ||||
/* Test inputs that might cause overflow in a sloppy implementation. */ | /* Test inputs that might cause overflow in a sloppy implementation. */ | ||||
static void | ATF_TC_WITHOUT_HEAD(large); | ||||
test_large(void) | ATF_TC_BODY(large, tc) | ||||
{ | { | ||||
/* TODO: Write these tests */ | /* TODO: Write these tests */ | ||||
} | } | ||||
int | ATF_TP_ADD_TCS(tp) | ||||
main(void) | |||||
{ | { | ||||
ATF_TP_ADD_TC(tp, zero); | |||||
ATF_TP_ADD_TC(tp, nan); | |||||
ATF_TP_ADD_TC(tp, inf); | |||||
ATF_TP_ADD_TC(tp, axes); | |||||
ATF_TP_ADD_TC(tp, small); | |||||
ATF_TP_ADD_TC(tp, large); | |||||
ngie: add newline | |||||
printf("1..6\n"); | return (atf_no_error()); | ||||
test_zero(); | |||||
printf("ok 1 - invctrig zero\n"); | |||||
test_nan(); | |||||
printf("ok 2 - invctrig nan\n"); | |||||
test_inf(); | |||||
printf("ok 3 - invctrig inf\n"); | |||||
test_axes(); | |||||
printf("ok 4 - invctrig axes\n"); | |||||
test_small(); | |||||
printf("ok 5 - invctrig small\n"); | |||||
test_large(); | |||||
printf("ok 6 - invctrig large\n"); | |||||
return (0); | |||||
} | } |
add newline