float FN_PROTOTYPE(expf)(float x) { static const float max_exp_arg = 8.8722839355E+01F, /* 0x42B17218 */ min_exp_arg = -1.0327893066E+02F, /* 0xC2CE8ED0 */ thirtytwo_by_log2 = 4.6166240692E+01F, /* 0x4238AA3B */ log2_by_32_lead = 2.1659851074E-02F, /* 0x3CB17000 */ log2_by_32_tail = 9.9831822808E-07F; /* 0x3585FDF4 */ float z1, z2, z; int m; unsigned int ux, ax; /* Computation of exp(x). We compute the values m, z1, and z2 such that exp(x) = 2**m * (z1 + z2), where exp(x) is the natural exponential of x. Computations needed in order to obtain m, z1, and z2 involve three steps. First, we reduce the argument x to the form x = n * log2/32 + remainder, where n has the value of an integer and |remainder| <= log2/64. The value of n = x * 32/log2 rounded to the nearest integer and the remainder = x - n*log2/32. Second, we approximate exp(r1 + r2) - 1 where r1 is the leading part of the remainder and r2 is the trailing part of the remainder. Third, we reconstruct the exponential of x so that exp(x) = 2**m * (z1 + z2). */ GET_BITS_SP32(x, ux); ax = ux & (~SIGNBIT_SP32); if (ax >= 0x42B17218) /* abs(x) >= 88.7... */ { if(ax >= 0x7f800000) { /* x is either NaN or infinity */ if (ux & MANTBITS_SP32) /* x is NaN */ return x + x; /* Raise invalid if it is a signalling NaN */ else if (ux & SIGNBIT_SP32) /* x is negative infinity; return 0.0 with no flags */ return 0.0; else /* x is positive infinity */ return x; } if (x > max_exp_arg) /* Return +infinity with overflow flag */ return retval_errno_erange_overflow(x); else if (x < min_exp_arg) /* x is negative. Return +zero with underflow and inexact flags */ return retval_errno_erange_underflow(x); } /* Handle small arguments separately */ if (ax < 0x3c800000) /* abs(x) < 1/64 */ { if (ax < 0x32800000) /* abs(x) < 2^(-26) */ return 1.0F + x; /* Raises inexact if x is non-zero */ else z = ((((((( 1.0F/5040)*x+ 1.0F/720)*x+ 1.0F/120)*x+ 1.0F/24)*x+ 1.0F/6)*x+ 1.0F/2)*x+ 1.0F)*x + 1.0F; } else { /* Find m and z such that exp(x) = 2**m * (z1 + z2) */ splitexpf(x, 1.0F, thirtytwo_by_log2, log2_by_32_lead, log2_by_32_tail, &m, &z1, &z2); /* Scale (z1 + z2) by 2.0**m */ if (m >= EMIN_SP32 && m <= EMAX_SP32) z = scaleFloat_1((float)(z1+z2),m); else z = scaleFloat_2((float)(z1+z2),m); } return z; }
float FN_PROTOTYPE(exp2f)(float x) { static const float max_exp2_arg = 128.0F, /* 0x43000000 */ min_exp2_arg = -149.0F, /* 0xc3150000 */ log2 = 6.931471824645996e-01F, /* 0x3f317218 */ one_by_32_lead = 0.03125F; float y, z1, z2, z; int m; unsigned int ux, ax; /* Computation of exp2f(x). We compute the values m, z1, and z2 such that exp2f(x) = 2**m * (z1 + z2), where exp2f(x) is 2**x. Computations needed in order to obtain m, z1, and z2 involve three steps. First, we reduce the argument x to the form x = n/32 + remainder, where n has the value of an integer and |remainder| <= 1/64. The value of n = x * 32 rounded to the nearest integer and the remainder = x - n/32. Second, we approximate exp2f(r1 + r2) - 1 where r1 is the leading part of the remainder and r2 is the trailing part of the remainder. Third, we reconstruct exp2f(x) so that exp2f(x) = 2**m * (z1 + z2). */ GET_BITS_SP32(x, ux); ax = ux & (~SIGNBIT_SP32); if (ax >= 0x43000000) /* abs(x) >= 128.0 */ { if(ax >= 0x7f800000) { /* x is either NaN or infinity */ if (ux & MANTBITS_SP32) /* x is NaN */ return x + x; /* Raise invalid if it is a signalling NaN */ else if (ux & SIGNBIT_SP32) /* x is negative infinity; return 0.0 with no flags. */ return 0.0F; else /* x is positive infinity */ return x; } if (x > max_exp2_arg) /* Return +infinity with overflow flag */ return retval_errno_erange_overflow(x); else if (x < min_exp2_arg) /* x is negative. Return +zero with underflow and inexact flags */ return retval_errno_erange_underflow(x); } /* Handle small arguments separately */ if (ax < 0x3cb8aa3b) /* abs(x) < 1/(64*log2) */ { if (ax < 0x32800000) /* abs(x) < 2^(-26) */ return 1.0F + x; /* Raises inexact if x is non-zero */ else { y = log2*x; z = (((((((( 1.0F/40320)*y+ 1.0F/5040)*y+ 1.0F/720)*y+ 1.0F/120)*y+ 1.0F/24)*y+ 1.0F/6)*y+ 1.0F/2)*y+ 1.0F)*y + 1.0F; } } else { /* Find m, z1 and z2 such that exp2f(x) = 2**m * (z1 + z2) */ splitexpf(x, log2, 32.0F, one_by_32_lead, 0.0F, &m, &z1, &z2); /* Scale (z1 + z2) by 2.0**m */ if (m >= EMIN_SP32 && m <= EMAX_SP32) z = scaleFloat_1((float)(z1+z2),m); else z = scaleFloat_2((float)(z1+z2),m); } return z; }
double FN_PROTOTYPE(exp2)(double x) { static const double max_exp2_arg = 1024.0, /* 0x4090000000000000 */ min_exp2_arg = -1074.0, /* 0xc090c80000000000 */ log2 = 6.931471805599453094178e-01, /* 0x3fe62e42fefa39ef */ log2_lead = 6.93147167563438415527E-01, /* 0x3fe62e42f8000000 */ log2_tail = 1.29965068938898869640E-08, /* 0x3e4be8e7bcd5e4f1 */ one_by_32_lead = 0.03125; double y, z1, z2, z, hx, tx, y1, y2; int m; unsigned long ux, ax; /* Computation of exp2(x). We compute the values m, z1, and z2 such that exp2(x) = 2**m * (z1 + z2), where exp2(x) is 2**x. Computations needed in order to obtain m, z1, and z2 involve three steps. First, we reduce the argument x to the form x = n/32 + remainder, where n has the value of an integer and |remainder| <= 1/64. The value of n = x * 32 rounded to the nearest integer and the remainder = x - n/32. Second, we approximate exp2(r1 + r2) - 1 where r1 is the leading part of the remainder and r2 is the trailing part of the remainder. Third, we reconstruct exp2(x) so that exp2(x) = 2**m * (z1 + z2). */ GET_BITS_DP64(x, ux); ax = ux & (~SIGNBIT_DP64); if (ax >= 0x4090000000000000) /* abs(x) >= 1024.0 */ { if(ax >= 0x7ff0000000000000) { /* x is either NaN or infinity */ if (ux & MANTBITS_DP64) /* x is NaN */ return x + x; /* Raise invalid if it is a signalling NaN */ else if (ux & SIGNBIT_DP64) /* x is negative infinity; return 0.0 with no flags. */ return 0.0; else /* x is positive infinity */ return x; } if (x > max_exp2_arg) /* Return +infinity with overflow flag */ return retval_errno_erange_overflow(x); else if (x < min_exp2_arg) /* x is negative. Return +zero with underflow and inexact flags */ return retval_errno_erange_underflow(x); } /* Handle small arguments separately */ if (ax < 0x3fb7154764ee6c2f) /* abs(x) < 1/(16*log2) */ { if (ax < 0x3c00000000000000) /* abs(x) < 2^(-63) */ return 1.0 + x; /* Raises inexact if x is non-zero */ else { /* Split x into hx (head) and tx (tail). */ unsigned long u; hx = x; GET_BITS_DP64(hx, u); u &= 0xfffffffff8000000; PUT_BITS_DP64(u, hx); tx = x - hx; /* Carefully multiply x by log2. y1 is the most significant part of the result, and y2 the least significant part */ y1 = x * log2_lead; y2 = (((hx * log2_lead - y1) + hx * log2_tail) + tx * log2_lead) + tx * log2_tail; y = y1 + y2; z = (9.99564649780173690e-1 + (1.61251249355268050e-5 + (2.37986978239838493e-2 + 2.68724774856111190e-7*y)*y)*y)/ (9.99564649780173692e-1 + (-4.99766199765151309e-1 + (1.070876894098586184e-1 + (-1.189773642681502232e-2 + 5.9480622371960190616e-4*y)*y)*y)*y); z = ((z * y1) + (z * y2)) + 1.0; } } else { /* Find m, z1 and z2 such that exp2(x) = 2**m * (z1 + z2) */ splitexp(x, log2, 32.0, one_by_32_lead, 0.0, &m, &z1, &z2); /* Scale (z1 + z2) by 2.0**m */ if (m > EMIN_DP64 && m < EMAX_DP64) z = scaleDouble_1((z1+z2),m); else z = scaleDouble_2((z1+z2),m); } return z; }
float FN_PROTOTYPE(exp10f)(float x) { static const float max_exp10_arg = 3.8531841278E+01F, /* 0x421A209B */ min_exp10_arg =-4.4853469848E+01F, /* 0xC23369F4 */ log10 = 2.3025850929E+00F, /* 0x40135D8E */ thirtytwo_by_log10of2 = 1.0630169677E+02F, /* 0x42D49A78 */ log10of2_by_32_lead = 9.4070434570E-03F, /* 0x3C1A2000 */ log10of2_by_32_tail = 1.4390730030E-07F; /* 0x341A84F0 */ float y, z1, z2, z; int m; unsigned int ux, ax; /* Computation of exp10f (x). We compute the values m, z1, and z2 such that exp10f(x) = 2**m * (z1 + z2), where exp10f(x) is 10**x. Computations needed in order to obtain m, z1, and z2 involve three steps. First, we reduce the argument x to the form x = n * log10of2/32 + remainder, where n has the value of an integer and |remainder| <= log10of2/64. The value of n = x * 32/log10of2 rounded to the nearest integer and the remainder = x - n*log10of2/32. Second, we approximate exp10f(r1 + r2) - 1 where r1 is the leading part of the remainder and r2 is the trailing part of the remainder. Third, we reconstruct exp10f(x) so that exp10f(x) = 2**m * (z1 + z2). */ GET_BITS_SP32(x, ux); ax = ux & (~SIGNBIT_SP32); if (ax >= 0x421A209B) /* abs(x) >= 38.5... */ { if(ax >= 0x7f800000) { /* x is either NaN or infinity */ if (ux & MANTBITS_SP32) /* x is NaN */ return x + x; /* Raise invalid if it is a signalling NaN */ else if (ux & SIGNBIT_SP32) /* x is negative infinity; return 0.0 with no flags. */ return 0.0F; else /* x is positive infinity */ return x; } if (x > max_exp10_arg) /* Return +infinity with overflow flag */ return retval_errno_erange_overflow(x); else if (x < min_exp10_arg) /* x is negative. Return +zero with underflow and inexact flags */ return retval_errno_erange_underflow(x); } /* Handle small arguments separately */ if (ax < 0x3bde5bd9) /* abs(x) < 1/(64*log10) */ { if (ax < 0x32800000) /* abs(x) < 2^(-26) */ return 1.0F + x; /* Raises inexact if x is non-zero */ else { y = log10*x; z = (((((((( 1.0F/40320)*x+ 1.0F/5040)*y+ 1.0F/720)*y+ 1.0F/120)*y+ 1.0F/24)*y+ 1.0F/6)*y+ 1.0F/2)*y+ 1.0F)*y + 1.0F; } } else { /* Find m, z1 and z2 such that exp10f(x) = 2**m * (z1 + z2) */ splitexpf(x, log10, thirtytwo_by_log10of2, log10of2_by_32_lead, log10of2_by_32_tail, &m, &z1, &z2); /* Scale (z1 + z2) by 2.0**m */ if (m >= EMIN_SP32 && m <= EMAX_SP32) z = scaleFloat_1((float)(z1+z2),m); else z = scaleFloat_2((float)(z1+z2),m); } return z; }
double FN_PROTOTYPE(exp)(double x) { static const double max_exp_arg = 7.09782712893383973096e+02, /* 0x40862e42fefa39ef */ min_exp_arg = -7.45133219101941108420e+02, /* 0xc0874910d52d3051 */ thirtytwo_by_log2 = 4.61662413084468283841e+01, /* 0x40471547652b82fe */ log2_by_32_lead = 2.16608493356034159660e-02, /* 0x3f962e42fe000000 */ log2_by_32_trail = 5.68948749532545630390e-11; /* 0x3dcf473de6af278e */ double z1, z2, z; int m; unsigned long ux, ax; /* Computation of exp(x). We compute the values m, z1, and z2 such that exp(x) = 2**m * (z1 + z2), where exp(x) is the natural exponential of x. Computations needed in order to obtain m, z1, and z2 involve three steps. First, we reduce the argument x to the form x = n * log2/32 + remainder, where n has the value of an integer and |remainder| <= log2/64. The value of n = x * 32/log2 rounded to the nearest integer and the remainder = x - n*log2/32. Second, we approximate exp(r1 + r2) - 1 where r1 is the leading part of the remainder and r2 is the trailing part of the remainder. Third, we reconstruct the exponential of x so that exp(x) = 2**m * (z1 + z2). */ GET_BITS_DP64(x, ux); ax = ux & (~SIGNBIT_DP64); if (ax >= 0x40862e42fefa39ef) /* abs(x) >= 709.78... */ { if(ax >= 0x7ff0000000000000) { /* x is either NaN or infinity */ if (ux & MANTBITS_DP64) /* x is NaN */ return x + x; /* Raise invalid if it is a signalling NaN */ else if (ux & SIGNBIT_DP64) /* x is negative infinity; return 0.0 with no flags. */ return 0.0; else /* x is positive infinity */ return x; } if (x > max_exp_arg) /* Return +infinity with overflow flag */ return retval_errno_erange_overflow(x); else if (x < min_exp_arg) /* x is negative. Return +zero with underflow and inexact flags */ return retval_errno_erange_underflow(x); } /* Handle small arguments separately */ if (ax < 0x3fb0000000000000) /* abs(x) < 1/16 */ { if (ax < 0x3c00000000000000) /* abs(x) < 2^(-63) */ z = 1.0 + x; /* Raises inexact if x is non-zero */ else z = (((((((((( 1.0/3628800)*x+ 1.0/362880)*x+ 1.0/40320)*x+ 1.0/5040)*x+ 1.0/720)*x+ 1.0/120)*x+ 1.0/24)*x+ 1.0/6)*x+ 1.0/2)*x+ 1.0)*x + 1.0; } else { /* Find m, z1 and z2 such that exp(x) = 2**m * (z1 + z2) */ splitexp(x, 1.0, thirtytwo_by_log2, log2_by_32_lead, log2_by_32_trail, &m, &z1, &z2); /* Scale (z1 + z2) by 2.0**m */ if (m >= EMIN_DP64 && m <= EMAX_DP64) z = scaleDouble_1((z1+z2),m); else z = scaleDouble_2((z1+z2),m); } return z; }