Changeset View
Changeset View
Standalone View
Standalone View
head/tools/regression/lib/msun/test-cexp.c
Show All 25 Lines | |||||
/* | /* | ||||
* Tests for corner cases in cexp*(). | * Tests for corner cases in cexp*(). | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/param.h> | |||||
#include <assert.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" | ||||
#define N(i) (sizeof(i) / sizeof((i)[0])) | |||||
#pragma STDC FENV_ACCESS ON | #pragma STDC FENV_ACCESS ON | ||||
#pragma STDC CX_LIMITED_RANGE OFF | #pragma STDC CX_LIMITED_RANGE OFF | ||||
/* | /* | ||||
* Test that a function returns the correct value and sets the | * Test that a function returns the correct value and sets the | ||||
* exception flags correctly. The exceptmask specifies which | * exception flags correctly. The exceptmask specifies which | ||||
* exceptions we should check. We need to be lenient for several | * exceptions we should check. We need to be lenient for several | ||||
* reasons, but mainly because on some architectures it's impossible | * reasons, but mainly because on some architectures it's impossible | ||||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | |||||
*/ | */ | ||||
void | void | ||||
test_nan() | test_nan() | ||||
{ | { | ||||
int i; | int i; | ||||
/* cexp(x + NaNi) = NaN + NaNi and optionally raises invalid */ | /* cexp(x + NaNi) = NaN + NaNi and optionally raises invalid */ | ||||
/* cexp(NaN + yi) = NaN + NaNi and optionally raises invalid (|y|>0) */ | /* cexp(NaN + yi) = NaN + NaNi and optionally raises invalid (|y|>0) */ | ||||
for (i = 0; i < N(finites); i++) { | for (i = 0; i < nitems(finites); i++) { | ||||
printf("# Run %d..\n", i); | printf("# Run %d..\n", i); | ||||
testall(CMPLXL(finites[i], NAN), CMPLXL(NAN, NAN), | testall(CMPLXL(finites[i], NAN), CMPLXL(NAN, NAN), | ||||
ALL_STD_EXCEPT & ~FE_INVALID, 0, 0); | ALL_STD_EXCEPT & ~FE_INVALID, 0, 0); | ||||
if (finites[i] == 0.0) | if (finites[i] == 0.0) | ||||
continue; | continue; | ||||
/* XXX FE_INEXACT shouldn't be raised here */ | /* XXX FE_INEXACT shouldn't be raised here */ | ||||
testall(CMPLXL(NAN, finites[i]), CMPLXL(NAN, NAN), | testall(CMPLXL(NAN, finites[i]), CMPLXL(NAN, NAN), | ||||
ALL_STD_EXCEPT & ~(FE_INVALID | FE_INEXACT), 0, 0); | ALL_STD_EXCEPT & ~(FE_INVALID | FE_INEXACT), 0, 0); | ||||
Show All 15 Lines | |||||
} | } | ||||
void | void | ||||
test_inf(void) | test_inf(void) | ||||
{ | { | ||||
int i; | int i; | ||||
/* cexp(x + inf i) = NaN + NaNi and raises invalid */ | /* cexp(x + inf i) = NaN + NaNi and raises invalid */ | ||||
for (i = 0; i < N(finites); i++) { | for (i = 0; i < nitems(finites); i++) { | ||||
printf("# Run %d..\n", i); | printf("# Run %d..\n", i); | ||||
testall(CMPLXL(finites[i], INFINITY), CMPLXL(NAN, NAN), | testall(CMPLXL(finites[i], INFINITY), CMPLXL(NAN, NAN), | ||||
ALL_STD_EXCEPT, FE_INVALID, 1); | ALL_STD_EXCEPT, FE_INVALID, 1); | ||||
} | } | ||||
/* cexp(-inf + yi) = 0 * (cos(y) + sin(y)i) */ | /* cexp(-inf + yi) = 0 * (cos(y) + sin(y)i) */ | ||||
/* XXX shouldn't raise an inexact exception */ | /* XXX shouldn't raise an inexact exception */ | ||||
testall(CMPLXL(-INFINITY, M_PI_4), CMPLXL(0.0, 0.0), | testall(CMPLXL(-INFINITY, M_PI_4), CMPLXL(0.0, 0.0), | ||||
ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1); | ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1); | ||||
Show All 24 Lines | testall(CMPLXL(INFINITY, -0.0), CMPLXL(INFINITY, -0.0), | ||||
ALL_STD_EXCEPT, 0, 1); | ALL_STD_EXCEPT, 0, 1); | ||||
} | } | ||||
void | void | ||||
test_reals(void) | test_reals(void) | ||||
{ | { | ||||
int i; | int i; | ||||
for (i = 0; i < N(finites); i++) { | for (i = 0; i < nitems(finites); i++) { | ||||
/* XXX could check exceptions more meticulously */ | /* XXX could check exceptions more meticulously */ | ||||
printf("# Run %d..\n", i); | printf("# Run %d..\n", i); | ||||
test(cexp, CMPLXL(finites[i], 0.0), | test(cexp, CMPLXL(finites[i], 0.0), | ||||
CMPLXL(exp(finites[i]), 0.0), | CMPLXL(exp(finites[i]), 0.0), | ||||
FE_INVALID | FE_DIVBYZERO, 0, 1); | FE_INVALID | FE_DIVBYZERO, 0, 1); | ||||
test(cexp, CMPLXL(finites[i], -0.0), | test(cexp, CMPLXL(finites[i], -0.0), | ||||
CMPLXL(exp(finites[i]), -0.0), | CMPLXL(exp(finites[i]), -0.0), | ||||
FE_INVALID | FE_DIVBYZERO, 0, 1); | FE_INVALID | FE_DIVBYZERO, 0, 1); | ||||
test(cexpf, CMPLXL(finites[i], 0.0), | test(cexpf, CMPLXL(finites[i], 0.0), | ||||
CMPLXL(expf(finites[i]), 0.0), | CMPLXL(expf(finites[i]), 0.0), | ||||
FE_INVALID | FE_DIVBYZERO, 0, 1); | FE_INVALID | FE_DIVBYZERO, 0, 1); | ||||
test(cexpf, CMPLXL(finites[i], -0.0), | test(cexpf, CMPLXL(finites[i], -0.0), | ||||
CMPLXL(expf(finites[i]), -0.0), | CMPLXL(expf(finites[i]), -0.0), | ||||
FE_INVALID | FE_DIVBYZERO, 0, 1); | FE_INVALID | FE_DIVBYZERO, 0, 1); | ||||
} | } | ||||
} | } | ||||
void | void | ||||
test_imaginaries(void) | test_imaginaries(void) | ||||
{ | { | ||||
int i; | int i; | ||||
for (i = 0; i < N(finites); i++) { | for (i = 0; i < nitems(finites); i++) { | ||||
printf("# Run %d..\n", i); | printf("# Run %d..\n", i); | ||||
test(cexp, CMPLXL(0.0, finites[i]), | test(cexp, CMPLXL(0.0, finites[i]), | ||||
CMPLXL(cos(finites[i]), sin(finites[i])), | CMPLXL(cos(finites[i]), sin(finites[i])), | ||||
ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1); | ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1); | ||||
test(cexp, CMPLXL(-0.0, finites[i]), | test(cexp, CMPLXL(-0.0, finites[i]), | ||||
CMPLXL(cos(finites[i]), sin(finites[i])), | CMPLXL(cos(finites[i]), sin(finites[i])), | ||||
ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1); | ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1); | ||||
test(cexpf, CMPLXL(0.0, finites[i]), | test(cexpf, CMPLXL(0.0, finites[i]), | ||||
Show All 15 Lines | static const double tests[] = { | ||||
-1.0, M_PI_4, M_SQRT2 * 0.5 / M_E, M_SQRT2 * 0.5 / M_E, | -1.0, M_PI_4, M_SQRT2 * 0.5 / M_E, M_SQRT2 * 0.5 / M_E, | ||||
2.0, M_PI_2, 0.0, M_E * M_E, | 2.0, M_PI_2, 0.0, M_E * M_E, | ||||
M_LN2, M_PI, -2.0, 0.0, | M_LN2, M_PI, -2.0, 0.0, | ||||
}; | }; | ||||
double a, b; | double a, b; | ||||
double x, y; | double x, y; | ||||
int i; | int i; | ||||
for (i = 0; i < N(tests); i += 4) { | for (i = 0; i < nitems(tests); i += 4) { | ||||
printf("# Run %d..\n", i); | printf("# Run %d..\n", i); | ||||
a = tests[i]; | a = tests[i]; | ||||
b = tests[i + 1]; | b = tests[i + 1]; | ||||
x = tests[i + 2]; | x = tests[i + 2]; | ||||
y = tests[i + 3]; | y = tests[i + 3]; | ||||
test_tol(cexp, CMPLXL(a, b), CMPLXL(x, y), 3 * DBL_ULP()); | test_tol(cexp, CMPLXL(a, b), CMPLXL(x, y), 3 * DBL_ULP()); | ||||
/* float doesn't have enough precision to pass these tests */ | /* float doesn't have enough precision to pass these tests */ | ||||
▲ Show 20 Lines • Show All 67 Lines • Show Last 20 Lines |