/* Test NaN-resulting library calls. */ int test_errs(void) { int errs = 0; /* * Attempt to prevent constant folding and optimization of library * function bodies (when statically linked). */ volatile double x; volatile double y; printf("Checking well-defined library errors\n"); x = -3.0; y = 4.4; errs += CHECK_NAN(pow(x, y)); errs += CHECK_NAN(log(x)); x = -0.001; errs += CHECK_NAN(sqrt(x)); x = 1.0001; errs += CHECK_NAN(asin(x)); x = INFINITY; errs += CHECK_NAN(sin(x)); errs += CHECK_NAN(cos(x)); x = 0.999; errs += CHECK_NAN(acosh(x)); x = 3.3; y = 0.0; errs += CHECK_NAN(remainder(x, y)); y = INFINITY; errs += CHECK_NAN(remainder(y, x)); return errs; }
int test_constants() { int errs = 0; errs += CHECK_NAN(NAN); printf("Print out of NaN: %f\n", NAN); errs += CHECK_INF(INFINITY); printf("Print out of Infinity: %f\n", INFINITY); errs += CHECK_INF(1.0/0.0); return errs; }
/* Test NaN-resulting library calls. */ int test_errs() { int errs = 0; printf("Checking well-defined library errors\n"); errs += CHECK_NAN(pow(-3.0, 4.4)); errs += CHECK_NAN(log(-3.0)); errs += CHECK_NAN(sqrt(-0.001)); errs += CHECK_NAN(asin(1.0001)); errs += CHECK_NAN(sin(INFINITY)); errs += CHECK_NAN(cos(INFINITY)); errs += CHECK_NAN(acosh(0.999)); errs += CHECK_NAN(remainder(3.3, 0.0)); errs += CHECK_NAN(remainder(INFINITY, 3.3)); return errs; }
int test_constants(void) { int errs = 0; /* Attempt to prevent constant folding */ volatile double x = 1.0; volatile double y = 0.0; errs += CHECK_NAN(NAN); printf("Print out of NaN: %f\n", NAN); errs += CHECK_INF(INFINITY); printf("Print out of Infinity: %f\n", INFINITY); errs += CHECK_INF(x/y); return errs; }
int test_compares() { int errs = 0; printf("Comparing float constants\n"); errs += ASSERT_TRUE(NAN != NAN); errs += ASSERT_TRUE(isunordered(NAN, NAN)); errs += CHECK_NAN(NAN + 3.0f); errs += CHECK_NAN(NAN + NAN); errs += CHECK_NAN(NAN - NAN); errs += CHECK_NAN(NAN / NAN); errs += CHECK_NAN(0.0 / NAN); errs += CHECK_NAN(0.0 * NAN); errs += ASSERT_FALSE(NAN == NAN); errs += ASSERT_TRUE(INFINITY == INFINITY); errs += ASSERT_FALSE(INFINITY == -INFINITY); errs += ASSERT_TRUE(-INFINITY == -INFINITY); errs += ASSERT_TRUE(INFINITY + 100.0 == INFINITY); errs += ASSERT_TRUE(INFINITY - 100.0 == INFINITY); errs += ASSERT_TRUE(-INFINITY - 100.0 == -INFINITY); errs += ASSERT_TRUE(-INFINITY + 100.0 == -INFINITY); errs += ASSERT_TRUE(-INFINITY < INFINITY); errs += ASSERT_FALSE(-INFINITY > INFINITY); errs += CHECK_NAN(0.0 * INFINITY); errs += CHECK_NAN(0.0 / 0.0); errs += CHECK_NAN(INFINITY / INFINITY); errs += CHECK_NAN(INFINITY - INFINITY); errs += CHECK_NAN(INFINITY * NAN); errs += CHECK_INF(INFINITY + INFINITY); errs += CHECK_INF(1.0 / 0.0); errs += ASSERT_FALSE(isfinite(INFINITY)); errs += ASSERT_FALSE(isfinite(NAN)); return errs; }
int main(void) { /* Set up some volatile constants to block the optimizer. */ volatile double zero = 0.0; volatile double nan = NAN; volatile double two = 2.0; volatile double onesix = 1.6; volatile double infinity = INFINITY; int err_count = 0; #if defined(TEST_LLVM_IR) /* With the LLVM IR frem instruction, errno is never set * (see the PNaCl bitcode ABI documentation). */ int expected_errno_infinity = 0; int expected_errno_zerodiv = 0; #elif defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 10 /* * The older (pre 2.10) glibc and newlib don't set errno when x is infinity. * See "BUGS" under the fmod manpage. It only sets errno for divide by zero. */ int expected_errno_infinity = EDOM; int expected_errno_zerodiv = EDOM; #else int expected_errno_infinity = 0; int expected_errno_zerodiv = EDOM; #endif /* Initialize errno to something predictable. */ errno = 0; /* If x or y is a NaN, a NaN is returned. */ CHECK_NAN(0, nan, two); CHECK_NANF(0, (float)nan, (float)two); CHECK_NAN(0, two, nan); CHECK_NANF(0, (float)two, (float)nan); CHECK_NAN(0, -onesix, nan); CHECK_NANF(0, (float)-onesix, (float)nan); CHECK_NAN(0, nan, nan); CHECK_NANF(0, (float)nan, (float)nan); CHECK_NAN(0, nan, infinity); CHECK_NANF(0, (float)nan, (float)infinity); /* If x is infinity, a NaN is returned and errno is * expected_errno_infinity (see note about BUGS). */ CHECK_NAN(expected_errno_infinity, infinity, two); CHECK_NANF(expected_errno_infinity, (float)infinity, (float)two); CHECK_NAN(expected_errno_infinity, -infinity, two); CHECK_NANF(expected_errno_infinity, (float)-infinity, (float)two); /* If y is zero, a NaN is returned and errno is expected_errno_zerodiv. */ CHECK_NAN(expected_errno_zerodiv, two, zero); CHECK_NANF(expected_errno_zerodiv, (float)two, (float)zero); CHECK_NAN(expected_errno_zerodiv, two, -zero); CHECK_NANF(expected_errno_zerodiv, (float)two, (float)-zero); CHECK_NAN(expected_errno_zerodiv, infinity, zero); CHECK_NANF(expected_errno_zerodiv, (float)infinity, (float)zero); CHECK_NAN(expected_errno_zerodiv, infinity, -zero); CHECK_NANF(expected_errno_zerodiv, (float)infinity, (float)-zero); /* If x is +0 (-0), and y is not zero, a +0 (-0) is returned. */ CHECK_EQ(zero, zero, two); CHECK_EQF((float)zero, (float)zero, (float)two); CHECK_EQ(zero, zero, -two); CHECK_EQF((float)zero, (float)zero, (float)-two); CHECK_EQ(-zero, -zero, two); CHECK_EQF((float)-zero, (float)-zero, (float)two); CHECK_EQ(-zero, -zero, -two); CHECK_EQF((float)-zero, (float)-zero, (float)-two); /* * On success... the returned value has the same sign as x and a magnitude * less than the magnitude of y. */ CHECK_EQ(1.2, 5.2, two); CHECK_EQF(1.2f, 5.2f, (float)two); CHECK_EQ(-0.6, -0.6, two); CHECK_EQF(-0.6f, -0.6f, (float)two); CHECK_EQ(-0.6, -0.6, -two); CHECK_EQF(-0.6f, -0.6f, (float)-two); CHECK_EQ(zero, 6.4, onesix); CHECK_EQF((float)zero, 6.4, (float)onesix); CHECK_EQ(1.0, 5.0, two); CHECK_EQF(1.0f, 5.0, (float)two); CHECK_EQ(-1.0, -5.0, two); CHECK_EQF(-1.0f, -5.0, (float)two); CHECK_EQ(zero, 100.0, two); CHECK_EQF((float)zero, 100.0, (float)two); CHECK_EQ(-zero, -100.0, two); CHECK_EQF((float)-zero, -100.0, (float)two); /* If the numerator is finite and the denominator is an infinity, the * result is the numerator. */ CHECK_EQ(5.2, 5.2, infinity); CHECK_EQF(5.2f, 5.2f, (float)infinity); CHECK_EQ(5.2, 5.2, -infinity); CHECK_EQF(5.2f, 5.2f, (float)-infinity); CHECK_EQ(-5.2, -5.2, infinity); CHECK_EQF(-5.2f, -5.2f, (float)infinity); fprintf(stderr, "Total of %d errors\n", err_count); return err_count; }
int test_compares(void) { int errs = 0; /* Attempt to prevent constant folding */ volatile double x; volatile double y; printf("Comparing float constants\n"); x = NAN; errs += ASSERT_TRUE(x != x); errs += ASSERT_TRUE(isunordered(x, x)); errs += CHECK_NAN(x + 3.0f); errs += CHECK_NAN(x + x); errs += CHECK_NAN(x - x); errs += CHECK_NAN(x / x); errs += CHECK_NAN(0.0 / x); errs += CHECK_NAN(0.0 * x); errs += ASSERT_FALSE(x == x); x = INFINITY; errs += ASSERT_TRUE(x == x); errs += ASSERT_FALSE(x == -x); errs += ASSERT_TRUE(-x == -x); errs += ASSERT_TRUE(x + 100.0 == x); errs += ASSERT_TRUE(x - 100.0 == x); errs += ASSERT_TRUE(-x - 100.0 == -x); errs += ASSERT_TRUE(-x + 100.0 == -x); errs += ASSERT_TRUE(-x < x); errs += ASSERT_FALSE(-x > x); y = 0.0; errs += CHECK_NAN(y * x); errs += CHECK_NAN(y / y); errs += CHECK_NAN(x / x); errs += CHECK_NAN(x - x); y = NAN; errs += CHECK_NAN(x * y); x = INFINITY; errs += CHECK_INF(x + x); x = 1.0; y = 0.0; errs += CHECK_INF(x / y); x = INFINITY; errs += ASSERT_FALSE(isfinite(x)); x = NAN; errs += ASSERT_FALSE(isfinite(x)); return errs; }