PortInitializer::PortInitializer() { union { unsigned int ui[2]; double d; } nan = {{ 0, 0x7FF80000 }}; Port::nan = nan.d; assert(!signbit(Port::nan)); union { unsigned int ui[4]; longdouble ld; } ldbl_nan = {{ 0, 0xC0000000, 0x7FFF, 0}}; Port::ldbl_nan = ldbl_nan.ld; assert(!signbit(Port::ldbl_nan)); union { unsigned int ui[4]; longdouble ld; } snan = {{ 0, 0xA0000000, 0x7FFF, 0 }}; Port::snan = snan.ld; #if __FreeBSD__ && __i386__ // LDBL_MAX comes out as infinity. Fix. static unsigned char x[sizeof(longdouble)] = { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x7F }; Port::ldbl_max = *(longdouble *)&x[0]; // FreeBSD defaults to double precision. Switch to extended precision. fpsetprec(FP_PE); #endif }
main () { unsigned long long int k; double x; #if defined(__i386__) && defined(__FreeBSD__) /* This test case assumes extended-precision, but FreeBSD defaults to double-precision. Make it so. */ fpsetprec (FP_PE); #endif if (sizeof (double) >= 8) { k = 0x8693ba6d7d220401ULL; x = d (k); k = (unsigned long long) x; if (k != 0x8693ba6d7d220800ULL) abort (); } k = 0x8234508000000001ULL; x = s (k); k = (unsigned long long) x; if (k != 0x8234510000000000ULL) abort (); exit (0); }
PortInitializer::PortInitializer() { assert(!signbit(Port::nan)); #if __FreeBSD__ && __i386__ // LDBL_MAX comes out as infinity. Fix. static unsigned char x[sizeof(longdouble)] = { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x7F }; Port::ldbl_max = *(longdouble *)&x[0]; // FreeBSD defaults to double precision. Switch to extended precision. fpsetprec(FP_PE); #endif }
int main(int argc, char *argv[]) { printf("1..26\n"); #ifdef __i386__ fpsetprec(FP_PE); #endif run_tests(); return (failures); }
int main(void) { printf("1..1\n"); run_tests(); #ifdef __i386__ fpsetprec(FP_PE); run_tests(); #endif printf("ok 1 - lrint\n"); return (0); }
PortInitializer::PortInitializer() { // gcc nan's have the sign bit set by default, so turn it off // Need the volatile to prevent gcc from doing incorrect // constant folding. volatile long double foo; foo = NAN; if (signbit(foo)) // signbit sometimes, not always, set foo = -foo; // turn off sign bit Port::nan = foo; #if __FreeBSD__ && __i386__ // LDBL_MAX comes out as infinity. Fix. static unsigned char x[sizeof(long double)] = { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x7F }; Port::ldbl_max = *(long double *)&x[0]; // FreeBSD defaults to double precision. Switch to extended precision. fpsetprec(FP_PE); #endif }
int main(int argc, char *argv[]) { printf("1..3\n"); run_generic_tests(); printf("ok 1 - exponential\n"); #ifdef __i386__ fpsetprec(FP_PE); run_generic_tests(); #endif printf("ok 2 - exponential\n"); run_exp2_tests(); printf("ok 3 - exponential\n"); return (0); }
DLLEXPORT long double cbrtl(long double x) { union IEEEl2bits u, v; long double r, s, t, w; double dr, dt, dx; float ft, fx; u_int32_t hx; u_int16_t expsign; int k; u.e = x; expsign = u.xbits.expsign; k = expsign & 0x7fff; /* * If x = +-Inf, then cbrt(x) = +-Inf. * If x = NaN, then cbrt(x) = NaN. */ if (k == BIAS + LDBL_MAX_EXP) return (x + x); #ifdef __i386__ fp_prec_t oprec; oprec = fpgetprec(); if (oprec != FP_PE) fpsetprec(FP_PE); #endif if (k == 0) { /* If x = +-0, then cbrt(x) = +-0. */ if ((u.bits.manh | u.bits.manl) == 0) { #ifdef __i386__ if (oprec != FP_PE) fpsetprec(oprec); #endif return (x); } /* Adjust subnormal numbers. */ u.e *= 0x1.0p514; k = u.bits.exp; k -= BIAS + 514; } else k -= BIAS; u.xbits.expsign = BIAS; v.e = 1; x = u.e; switch (k % 3) { case 1: case -2: x = 2*x; k--; break; case 2: case -1: x = 4*x; k -= 2; break; } v.xbits.expsign = (expsign & 0x8000) | (BIAS + k / 3); /* * The following is the guts of s_cbrtf, with the handling of * special values removed and extra care for accuracy not taken, * but with most of the extra accuracy not discarded. */ /* ~5-bit estimate: */ fx = x; GET_FLOAT_WORD(hx, fx); SET_FLOAT_WORD(ft, ((hx & 0x7fffffff) / 3 + B1)); /* ~16-bit estimate: */ dx = x; dt = ft; dr = dt * dt * dt; dt = dt * (dx + dx + dr) / (dx + dr + dr); /* ~47-bit estimate: */ dr = dt * dt * dt; dt = dt * (dx + dx + dr) / (dx + dr + dr); #if LDBL_MANT_DIG == 64 /* * dt is cbrtl(x) to ~47 bits (after x has been reduced to 1 <= x < 8). * Round it away from zero to 32 bits (32 so that t*t is exact, and * away from zero for technical reasons). */ volatile double vd2 = 0x1.0p32; volatile double vd1 = 0x1.0p-31; #define vd ((long double)vd2 + vd1) t = dt + vd - 0x1.0p32; #elif LDBL_MANT_DIG == 113 /* * Round dt away from zero to 47 bits. Since we don't trust the 47, * add 2 47-bit ulps instead of 1 to round up. Rounding is slow and * might be avoidable in this case, since on most machines dt will * have been evaluated in 53-bit precision and the technical reasons * for rounding up might not apply to either case in cbrtl() since * dt is much more accurate than needed. */ t = dt + 0x2.0p-46 + 0x1.0p60L - 0x1.0p60; #else #error "Unsupported long double format" #endif /* * Final step Newton iteration to 64 or 113 bits with * error < 0.667 ulps */ s=t*t; /* t*t is exact */ r=x/s; /* error <= 0.5 ulps; |r| < |t| */ w=t+t; /* t+t is exact */ r=(r-t)/(w+r); /* r-t is exact; w+r ~= 3*t */ t=t+t*r; /* error <= 0.5 + 0.5/3 + epsilon */ t *= v.e; #ifdef __i386__ if (oprec != FP_PE) fpsetprec(oprec); #endif return (t); }
int gsl_ieee_set_mode (int precision, int rounding, int exception_mask) { fp_prec_t prec = 0 ; fp_except_t mode = 0 ; fp_rnd_t rnd = 0 ; switch (precision) { case GSL_IEEE_SINGLE_PRECISION: prec = FP_PS; fpsetprec(prec); break ; case GSL_IEEE_DOUBLE_PRECISION: prec = FP_PD; fpsetprec(prec); break ; case GSL_IEEE_EXTENDED_PRECISION: prec = FP_PE; fpsetprec(prec); break ; } switch (rounding) { case GSL_IEEE_ROUND_TO_NEAREST: rnd = FP_RN ; fpsetround (rnd) ; break ; case GSL_IEEE_ROUND_DOWN: rnd = FP_RM ; fpsetround (rnd) ; break ; case GSL_IEEE_ROUND_UP: rnd = FP_RP ; fpsetround (rnd) ; break ; case GSL_IEEE_ROUND_TO_ZERO: rnd = FP_RZ ; fpsetround (rnd) ; break ; default: rnd = FP_RN ; fpsetround (rnd) ; } /* Turn on all the exceptions apart from 'inexact' */ mode = FP_X_INV | FP_X_DNML | FP_X_DZ | FP_X_OFL | FP_X_UFL ; if (exception_mask & GSL_IEEE_MASK_INVALID) mode &= ~ FP_X_INV ; if (exception_mask & GSL_IEEE_MASK_DENORMALIZED) mode &= ~ FP_X_DNML ; if (exception_mask & GSL_IEEE_MASK_DIVISION_BY_ZERO) mode &= ~ FP_X_DZ ; if (exception_mask & GSL_IEEE_MASK_OVERFLOW) mode &= ~ FP_X_OFL ; if (exception_mask & GSL_IEEE_MASK_UNDERFLOW) mode &= ~ FP_X_UFL ; if (exception_mask & GSL_IEEE_TRAP_INEXACT) { mode |= FP_X_IMP ; } else { mode &= ~ FP_X_IMP ; } fpsetmask (mode) ; return GSL_SUCCESS ; }
int main(int argc, char *argv[]) { static const int ex_under = FE_UNDERFLOW | FE_INEXACT; /* shorthand */ static const int ex_over = FE_OVERFLOW | FE_INEXACT; long double ldbl_small, ldbl_eps, ldbl_max; printf("1..5\n"); #ifdef __i386__ fpsetprec(FP_PE); #endif /* * We can't use a compile-time constant here because gcc on * FreeBSD/i386 assumes long doubles are truncated to the * double format. */ ldbl_small = ldexpl(1.0, LDBL_MIN_EXP - LDBL_MANT_DIG); ldbl_eps = LDBL_EPSILON; ldbl_max = ldexpl(1.0 - ldbl_eps / 2, LDBL_MAX_EXP); /* * Special cases involving zeroes. */ #define ztest(prec) \ test##prec(copysign##prec(1.0, nextafter##prec(0.0, -0.0)), -1.0, 0); \ test##prec(copysign##prec(1.0, nextafter##prec(-0.0, 0.0)), 1.0, 0); \ test##prec(copysign##prec(1.0, nexttoward##prec(0.0, -0.0)), -1.0, 0);\ test##prec(copysign##prec(1.0, nexttoward##prec(-0.0, 0.0)), 1.0, 0) ztest(); ztest(f); ztest(l); #undef ztest #define stest(next, eps, prec) \ test##prec(next(-0.0, 42.0), eps, ex_under); \ test##prec(next(0.0, -42.0), -eps, ex_under); \ test##prec(next(0.0, INFINITY), eps, ex_under); \ test##prec(next(-0.0, -INFINITY), -eps, ex_under) stest(nextafter, 0x1p-1074, ); stest(nextafterf, 0x1p-149f, f); stest(nextafterl, ldbl_small, l); stest(nexttoward, 0x1p-1074, ); stest(nexttowardf, 0x1p-149f, f); stest(nexttowardl, ldbl_small, l); #undef stest printf("ok 1 - next\n"); /* * `x == y' and NaN tests */ testall(42.0, 42.0, 42.0, 0); testall(-42.0, -42.0, -42.0, 0); testall(INFINITY, INFINITY, INFINITY, 0); testall(-INFINITY, -INFINITY, -INFINITY, 0); testall(NAN, 42.0, NAN, 0); testall(42.0, NAN, NAN, 0); testall(NAN, NAN, NAN, 0); printf("ok 2 - next\n"); /* * Tests where x is an ordinary normalized number */ testboth(1.0, 2.0, 1.0 + DBL_EPSILON, 0, ); testboth(1.0, -INFINITY, 1.0 - DBL_EPSILON/2, 0, ); testboth(1.0, 2.0, 1.0 + FLT_EPSILON, 0, f); testboth(1.0, -INFINITY, 1.0 - FLT_EPSILON/2, 0, f); testboth(1.0, 2.0, 1.0 + ldbl_eps, 0, l); testboth(1.0, -INFINITY, 1.0 - ldbl_eps/2, 0, l); testboth(-1.0, 2.0, -1.0 + DBL_EPSILON/2, 0, ); testboth(-1.0, -INFINITY, -1.0 - DBL_EPSILON, 0, ); testboth(-1.0, 2.0, -1.0 + FLT_EPSILON/2, 0, f); testboth(-1.0, -INFINITY, -1.0 - FLT_EPSILON, 0, f); testboth(-1.0, 2.0, -1.0 + ldbl_eps/2, 0, l); testboth(-1.0, -INFINITY, -1.0 - ldbl_eps, 0, l); /* Cases where nextafter(...) != nexttoward(...) */ test(nexttoward(1.0, 1.0 + ldbl_eps), 1.0 + DBL_EPSILON, 0); testf(nexttowardf(1.0, 1.0 + ldbl_eps), 1.0 + FLT_EPSILON, 0); testl(nexttowardl(1.0, 1.0 + ldbl_eps), 1.0 + ldbl_eps, 0); printf("ok 3 - next\n"); /* * Tests at word boundaries, normalization boundaries, etc. */ testboth(0x1.87654ffffffffp+0, INFINITY, 0x1.87655p+0, 0, ); testboth(0x1.87655p+0, -INFINITY, 0x1.87654ffffffffp+0, 0, ); testboth(0x1.fffffffffffffp+0, INFINITY, 0x1p1, 0, ); testboth(0x1p1, -INFINITY, 0x1.fffffffffffffp+0, 0, ); testboth(0x0.fffffffffffffp-1022, INFINITY, 0x1p-1022, 0, ); testboth(0x1p-1022, -INFINITY, 0x0.fffffffffffffp-1022, ex_under, ); testboth(0x1.fffffep0f, INFINITY, 0x1p1, 0, f); testboth(0x1p1, -INFINITY, 0x1.fffffep0f, 0, f); testboth(0x0.fffffep-126f, INFINITY, 0x1p-126f, 0, f); testboth(0x1p-126f, -INFINITY, 0x0.fffffep-126f, ex_under, f); #if LDBL_MANT_DIG == 53 testboth(0x1.87654ffffffffp+0L, INFINITY, 0x1.87655p+0L, 0, l); testboth(0x1.87655p+0L, -INFINITY, 0x1.87654ffffffffp+0L, 0, l); testboth(0x1.fffffffffffffp+0L, INFINITY, 0x1p1L, 0, l); testboth(0x1p1L, -INFINITY, 0x1.fffffffffffffp+0L, 0, l); testboth(0x0.fffffffffffffp-1022L, INFINITY, 0x1p-1022L, 0, l); testboth(0x1p-1022L, -INFINITY, 0x0.fffffffffffffp-1022L, ex_under, l); #elif LDBL_MANT_DIG == 64 && !defined(__i386) testboth(0x1.87654321fffffffep+0L, INFINITY, 0x1.87654322p+0L, 0, l); testboth(0x1.87654322p+0L, -INFINITY, 0x1.87654321fffffffep+0L, 0, l); testboth(0x1.fffffffffffffffep0L, INFINITY, 0x1p1L, 0, l); testboth(0x1p1L, -INFINITY, 0x1.fffffffffffffffep0L, 0, l); testboth(0x0.fffffffffffffffep-16382L, INFINITY, 0x1p-16382L, 0, l); testboth(0x1p-16382L, -INFINITY, 0x0.fffffffffffffffep-16382L, ex_under, l); #elif LDBL_MANT_DIG == 113 testboth(0x1.876543210987ffffffffffffffffp+0L, INFINITY, 0x1.876543210988p+0, 0, l); testboth(0x1.876543210988p+0L, -INFINITY, 0x1.876543210987ffffffffffffffffp+0L, 0, l); testboth(0x1.ffffffffffffffffffffffffffffp0L, INFINITY, 0x1p1L, 0, l); testboth(0x1p1L, -INFINITY, 0x1.ffffffffffffffffffffffffffffp0L, 0, l); testboth(0x0.ffffffffffffffffffffffffffffp-16382L, INFINITY, 0x1p-16382L, 0, l); testboth(0x1p-16382L, -INFINITY, 0x0.ffffffffffffffffffffffffffffp-16382L, ex_under, l); #endif printf("ok 4 - next\n"); /* * Overflow tests */ test(idd(nextafter(DBL_MAX, INFINITY)), INFINITY, ex_over); test(idd(nextafter(INFINITY, 0.0)), DBL_MAX, 0); test(idd(nexttoward(DBL_MAX, DBL_MAX * 2.0L)), INFINITY, ex_over); #if LDBL_MANT_DIG > 53 test(idd(nexttoward(INFINITY, DBL_MAX * 2.0L)), DBL_MAX, 0); #endif testf(idf(nextafterf(FLT_MAX, INFINITY)), INFINITY, ex_over); testf(idf(nextafterf(INFINITY, 0.0)), FLT_MAX, 0); testf(idf(nexttowardf(FLT_MAX, FLT_MAX * 2.0)), INFINITY, ex_over); testf(idf(nexttowardf(INFINITY, FLT_MAX * 2.0)), FLT_MAX, 0); testboth(ldbl_max, INFINITY, INFINITY, ex_over, l); testboth(INFINITY, 0.0, ldbl_max, 0, l); printf("ok 5 - next\n"); return (0); }