inline long double operator()(const long double& x) const { #if defined(NTA_OS_WINDOWS) return log(1.0 + x); #else return log1pl(x); #endif }
long double atanhl(long double x) { long double t; t = fabsl(x); if (t == one) return (x / zero); t = t / (one - t); return (copysignl(half, x) * log1pl(t + t)); }
/* acosh(x) = log(x + sqrt(x*x-1)) */ long double acoshl(long double x) { union ldshape u = {x}; int e = u.i.se & 0x7fff; if (e < 0x3fff + 1) /* |x| < 2, invalid if x < 1 or nan */ return log1pl(x - 1 + sqrtl((x - 1) * (x - 1) + 2 * (x - 1))); if (e < 0x3fff + 32) /* |x| < 0x1p32 */ return logl(2 * x - 1 / (x + sqrtl(x * x - 1))); return logl(x) + 0.693147180559945309417232121458176568L; }
long double atanhl(long double x) { long double t; uint16_t hx, ix; ENTERI(); GET_LDBL_EXPSIGN(hx, x); ix = hx & 0x7fff; if (ix >= 0x3fff) /* |x| >= 1, or NaN or misnormal */ RETURNI(fabsl(x) == 1 ? x / zero : (x - x) / (x - x)); if (ix < BIAS + EXP_TINY && (huge + x) > zero) RETURNI(x); /* x is tiny */ SET_LDBL_EXPSIGN(x, ix); if (ix < 0x3ffe) { /* |x| < 0.5, or misnormal */ t = x+x; t = 0.5*log1pl(t+t*x/(one-x)); } else t = 0.5*log1pl((x+x)/(one-x)); RETURNI((hx & 0x8000) == 0 ? t : -t); }
/* atanh(x) = log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2 ~= x + x^3/3 + o(x^5) */ long double atanhl(long double x) { union ldshape u = {x}; unsigned e = u.i.se & 0x7fff; unsigned s = u.i.se >> 15; /* |x| */ u.i.se = e; x = u.f; if (e < 0x3ff - 1) { if (e < 0x3ff - LDBL_MANT_DIG / 2) { /* handle underflow */ if (e == 0) FORCE_EVAL((float)x); } else { /* |x| < 0.5, up to 1.7ulp error */ x = 0.5 * log1pl(2 * x + 2 * x * x / (1 - x)); } } else { /* avoid overflow */ x = 0.5 * log1pl(2 * (x / (1 - x))); } return s ? -x : x; }
long double complex catanhl(long double complex z) { long double x, y, ax, ay, rx, ry; x = creall(z); y = cimagl(z); ax = fabsl(x); ay = fabsl(y); if (y == 0 && ax <= 1) return (CMPLXL(atanhl(x), y)); if (x == 0) return (CMPLXL(x, atanl(y))); if (isnan(x) || isnan(y)) { if (isinf(x)) return (CMPLXL(copysignl(0, x), y + y)); if (isinf(y)) return (CMPLXL(copysignl(0, x), copysignl(pio2_hi + pio2_lo, y))); return (CMPLXL(nan_mix(x, y), nan_mix(x, y))); } if (ax > RECIP_EPSILON || ay > RECIP_EPSILON) return (CMPLXL(real_part_reciprocal(x, y), copysignl(pio2_hi + pio2_lo, y))); if (ax < SQRT_3_EPSILON / 2 && ay < SQRT_3_EPSILON / 2) { raise_inexact(); return (z); } if (ax == 1 && ay < LDBL_EPSILON) rx = (m_ln2 - logl(ay)) / 2; else rx = log1pl(4 * ax / sum_squares(ax - 1, ay)) / 4; if (ax == 1) ry = atan2l(2, -ay) / 2; else if (ay < LDBL_EPSILON) ry = atan2l(2 * ay, (1 - ax) * (1 + ax)) / 2; else ry = atan2l(2 * ay, (1 - ax) * (1 + ax) - ay * ay) / 2; return (CMPLXL(copysignl(rx, x), copysignl(ry, y))); }
long double acoshl(long double x) { long double t; if (isnanl(x)) return (x + x); else if (x > big) return (logl(x) + ln2); else if (x > one) { t = sqrtl(x - one); return (log1pl(t * (t + sqrtl(x + one)))); } else if (x == one) return (zero); else return ((x - x) / (x - x)); }
long double asinhl(long double x) { long double t, w; w = fabsl(x); if (isnanl(x)) return (x + x); /* x is NaN */ if (w < tiny) { #ifndef lint volatile long double dummy = x + big; /* inexact if x != 0 */ #endif return (x); /* tiny x */ } else if (w < big) { t = one / w; return (copysignl(log1pl(w + w / (t + sqrtl(one + t * t))), x)); } else return (copysignl(logl(w) + ln2, x)); }
long double asinhl(long double x) { long double t,w; int32_t hx,ix; GET_LDOUBLE_EXP(hx,x); ix = hx&0x7fff; if(ix==0x7fff) return x+x; /* x is inf or NaN */ if(ix< 0x3fde) { /* |x|<2**-34 */ if(huge+x>one) return x; /* return x inexact except 0 */ } if(ix>0x4020) { /* |x| > 2**34 */ w = logl(fabsl(x))+ln2; } else if (ix>0x4000) { /* 2**34 > |x| > 2.0 */ t = fabsl(x); w = logl(2.0*t+one/(sqrtl(x*x+one)+t)); } else { /* 2.0 > |x| > 2**-28 */ t = x*x; w =log1pl(fabsl(x)+t/(one+sqrtl(one+t))); } if(hx&0x8000) return -w; else return w; }
long double acoshl(long double x) { long double t; uint32_t se,i0,i1; GET_LDOUBLE_WORDS(se, i0, i1, x); if (se < 0x3fff || se & 0x8000) { /* x < 1 */ return (x-x)/(x-x); } else if (se >= 0x401d) { /* x > 2**30 */ if (se >= 0x7fff) /* x is inf or NaN */ return x+x; return logl(x) + ln2; /* acoshl(huge) = logl(2x) */ } else if (((se-0x3fff)|i0|i1) == 0) { return 0.0; /* acosh(1) = 0 */ } else if (se > 0x4000) { /* x > 2 */ t = x*x; return logl(2.0*x - 1.0/(x + sqrtl(t - 1.0))); } /* 1 < x <= 2 */ t = x - 1.0; return log1pl(t + sqrtl(2.0*t + t*t)); }
long double asinhl(long double x) { long double t, w; uint16_t hx, ix; ENTERI(); GET_LDBL_EXPSIGN(hx, x); ix = hx & 0x7fff; if (ix >= 0x7fff) RETURNI(x+x); /* x is inf, NaN or misnormal */ if (ix < BIAS + EXP_TINY) { /* |x| < TINY, or misnormal */ if (huge + x > one) RETURNI(x); /* return x inexact except 0 */ } if (ix >= BIAS + EXP_LARGE) { /* |x| >= LARGE, or misnormal */ w = logl(fabsl(x))+ln2; } else if (ix >= 0x4000) { /* LARGE > |x| >= 2.0, or misnormal */ t = fabsl(x); w = logl(2.0*t+one/(sqrtl(x*x+one)+t)); } else { /* 2.0 > |x| >= TINY, or misnormal */ t = x*x; w =log1pl(fabsl(x)+t/(one+sqrtl(one+t))); } RETURNI((hx & 0x8000) == 0 ? w : -w); }
double log1p(double x) { return log1pl(x); }
ldcomplex casinl(ldcomplex z) { long double x, y, t, R, S, A, Am1, B, y2, xm1, xp1, Apx; int ix, iy, hx, hy; ldcomplex ans; x = LD_RE(z); y = LD_IM(z); hx = HI_XWORD(x); hy = HI_XWORD(y); ix = hx & 0x7fffffff; iy = hy & 0x7fffffff; x = fabsl(x); y = fabsl(y); /* special cases */ /* x is inf or NaN */ if (ix >= 0x7fff0000) { /* x is inf or NaN */ if (isinfl(x)) { /* x is INF */ LD_IM(ans) = x; if (iy >= 0x7fff0000) { if (isinfl(y)) /* casin(inf + i inf) = pi/4 + i inf */ LD_RE(ans) = pi_4 + pi_4_l; else /* casin(inf + i NaN) = NaN + i inf */ LD_RE(ans) = y + y; } else /* casin(inf + iy) = pi/2 + i inf */ LD_RE(ans) = pi_2 + pi_2_l; } else { /* x is NaN */ if (iy >= 0x7fff0000) { /* INDENT OFF */ /* * casin(NaN + i inf) = NaN + i inf * casin(NaN + i NaN) = NaN + i NaN */ /* INDENT ON */ LD_IM(ans) = y + y; LD_RE(ans) = x + x; } else { /* INDENT OFF */ /* casin(NaN + i y ) = NaN + i NaN */ /* INDENT ON */ LD_IM(ans) = LD_RE(ans) = x + y; } } if (hx < 0) LD_RE(ans) = -LD_RE(ans); if (hy < 0) LD_IM(ans) = -LD_IM(ans); return (ans); } /* casin(+0 + i 0) = 0 + i 0. */ if (x == zero && y == zero) return (z); if (iy >= 0x7fff0000) { /* y is inf or NaN */ if (isinfl(y)) { /* casin( x + i inf ) = 0 + i inf */ LD_IM(ans) = y; LD_RE(ans) = zero; } else { /* casin( x + i NaN ) = NaN + i NaN */ LD_IM(ans) = x + y; if (x == zero) LD_RE(ans) = x; else LD_RE(ans) = y; } if (hx < 0) LD_RE(ans) = -LD_RE(ans); if (hy < 0) LD_IM(ans) = -LD_IM(ans); return (ans); } if (y == zero) { /* region 1: y=0 */ if (ix < 0x3fff0000) { /* |x| < 1 */ LD_RE(ans) = asinl(x); LD_IM(ans) = zero; } else { LD_RE(ans) = pi_2 + pi_2_l; if (ix >= ip1) /* |x| >= i386 ? 2**65 : 2**114 */ LD_IM(ans) = ln2 + logl(x); else if (ix >= 0x3fff8000) /* x > Acrossover */ LD_IM(ans) = logl(x + sqrtl((x - one) * (x + one))); else { xm1 = x - one; LD_IM(ans) = log1pl(xm1 + sqrtl(xm1 * (x + one))); } } } else if (y <= E * fabsl(x - one)) { /* region 2: y < tiny*|x-1| */ if (ix < 0x3fff0000) { /* x < 1 */ LD_RE(ans) = asinl(x); LD_IM(ans) = y / sqrtl((one + x) * (one - x)); } else { LD_RE(ans) = pi_2 + pi_2_l; if (ix >= ip1) /* i386 ? 2**65 : 2**114 */ LD_IM(ans) = ln2 + logl(x); else if (ix >= 0x3fff8000) /* x > Acrossover */ LD_IM(ans) = logl(x + sqrtl((x - one) * (x + one))); else LD_IM(ans) = log1pl((x - one) + sqrtl((x - one) * (x + one))); } } else if (y < Foursqrtu) { /* region 3 */ t = sqrtl(y); LD_RE(ans) = pi_2 - (t - pi_2_l); LD_IM(ans) = t; } else if (E * y - one >= x) { /* region 4 */ LD_RE(ans) = x / y; /* need to fix underflow cases */ LD_IM(ans) = ln2 + logl(y); } else if (ix >= 0x5ffb0000 || iy >= 0x5ffb0000) { /* region 5: x+1 and y are both (>= sqrt(max)/8) i.e. 2**8188 */ t = x / y; LD_RE(ans) = atanl(t); LD_IM(ans) = ln2 + logl(y) + half * log1pl(t * t); } else if (x < Foursqrtu) { /* region 6: x is very small, < 4sqrt(min) */ A = sqrtl(one + y * y); LD_RE(ans) = x / A; /* may underflow */ if (iy >= 0x3fff8000) /* if y > Acrossover */ LD_IM(ans) = logl(y + A); else LD_IM(ans) = half * log1pl((y + y) * (y + A)); } else { /* safe region */ y2 = y * y; xp1 = x + one; xm1 = x - one; R = sqrtl(xp1 * xp1 + y2); S = sqrtl(xm1 * xm1 + y2); A = half * (R + S); B = x / A; if (B <= Bcrossover) LD_RE(ans) = asinl(B); else { /* use atan and an accurate approx to a-x */ Apx = A + x; if (x <= one) LD_RE(ans) = atanl(x / sqrtl(half * Apx * (y2 / (R + xp1) + (S - xm1)))); else LD_RE(ans) = atanl(x / (y * sqrtl(half * (Apx / (R + xp1) + Apx / (S + xm1))))); } if (A <= Acrossover) { /* use log1p and an accurate approx to A-1 */ if (x < one) Am1 = half * (y2 / (R + xp1) + y2 / (S - xm1)); else Am1 = half * (y2 / (R + xp1) + (S + xm1)); LD_IM(ans) = log1pl(Am1 + sqrtl(Am1 * (A + one))); } else { LD_IM(ans) = logl(A + sqrtl(A * A - one)); } } if (hx < 0) LD_RE(ans) = -LD_RE(ans); if (hy < 0) LD_IM(ans) = -LD_IM(ans); return (ans); }
ldcomplex catanl(ldcomplex z) { ldcomplex ans; long double x, y, t1, ax, ay, t; int hx, hy, ix, iy; x = LD_RE(z); y = LD_IM(z); ax = fabsl(x); ay = fabsl(y); hx = HI_XWORD(x); hy = HI_XWORD(y); ix = hx & 0x7fffffff; iy = hy & 0x7fffffff; /* x is inf or NaN */ if (ix >= 0x7fff0000) { if (isinfl(x)) { LD_RE(ans) = pi_2; LD_IM(ans) = zero; } else { LD_RE(ans) = x + x; if (iszerol(y) || (isinfl(y))) LD_IM(ans) = zero; else LD_IM(ans) = (fabsl(y) - ay) / (fabsl(y) - ay); } } else if (iy >= 0x7fff0000) { /* y is inf or NaN */ if (isinfl(y)) { LD_RE(ans) = pi_2; LD_IM(ans) = zero; } else { LD_RE(ans) = (fabsl(x) - ax) / (fabsl(x) - ax); LD_IM(ans) = y; } } else if (iszerol(x)) { /* INDENT OFF */ /* * x = 0 * 1 1 * A = --- * atan2(2x, 1-x*x-y*y) = --- atan2(0,1-|y|) * 2 2 * * 1 [ (y+1)*(y+1) ] 1 2 1 2y * B = - log [ ----------- ] = - log (1+ ---) or - log(1+ ----) * 4 [ (y-1)*(y-1) ] 2 y-1 2 1-y */ /* INDENT ON */ t = one - ay; if (ay == one) { /* y=1: catan(0,1)=(0,+inf) with 1/0 signal */ LD_IM(ans) = ay / ax; LD_RE(ans) = zero; } else if (ay > one) { /* y>1 */ LD_IM(ans) = half * log1pl(two / (-t)); LD_RE(ans) = pi_2; } else { /* y<1 */ LD_IM(ans) = half * log1pl((ay + ay) / t); LD_RE(ans) = zero; } } else if (ay < E * (one + ax)) { /* INDENT OFF */ /* * Tiny y (relative to 1+|x|) * |y| < E*(1+|x|) * where E=2**-29, -35, -60 for double, extended, quad precision * * 1 [x<=1: atan(x) * A = - * atan2(2x,1-x*x-y*y) ~ [ 1 1+x * 2 [x>=1: - atan2(2,(1-x)*(-----)) * 2 x * * y/x * B ~ t*(1-2t), where t = ----------------- is tiny * x + (y-1)*(y-1)/x * * y * (when x < 2**-60, t = ----------- ) * (y-1)*(y-1) */ /* INDENT ON */ if (ay == zero) LD_IM(ans) = ay; else { t1 = ay - one; if (ix < 0x3fc30000) t = ay / (t1 * t1); else if (ix > 0x403b0000) t = (ay / ax) / ax; else t = ay / (ax * ax + t1 * t1); LD_IM(ans) = t * (one - two * t); } if (ix < 0x3fff0000) LD_RE(ans) = atanl(ax); else LD_RE(ans) = half * atan2l(two, (one - ax) * (one + one / ax)); } else if (ay > Einv * (one + ax)) { /* INDENT OFF */ /* * Huge y relative to 1+|x| * |y| > Einv*(1+|x|), where Einv~2**(prec/2+3), * 1 * A ~ --- * atan2(2x, -y*y) ~ pi/2 * 2 * y * B ~ t*(1-2t), where t = --------------- is tiny * (y-1)*(y-1) */ /* INDENT ON */ LD_RE(ans) = pi_2; t = (ay / (ay - one)) / (ay - one); LD_IM(ans) = t * (one - (t + t)); } else if (ay == one) { /* INDENT OFF */ /* * y=1 * 1 1 * A = - * atan2(2x, -x*x) = --- atan2(2,-x) * 2 2 * * 1 [ x*x+4] 1 4 [ 0.5(log2-logx) if * B = - log [ -----] = - log (1+ ---) = [ |x|<E, else 0.25* * 4 [ x*x ] 4 x*x [ log1p((2/x)*(2/x)) */ /* INDENT ON */ LD_RE(ans) = half * atan2l(two, -ax); if (ax < E) LD_IM(ans) = half * (ln2 - logl(ax)); else { t = two / ax; LD_IM(ans) = 0.25L * log1pl(t * t); } } else if (ax > Einv * Einv) { /* INDENT OFF */ /* * Huge x: * when |x| > 1/E^2, * 1 pi * A ~ --- * atan2(2x, -x*x-y*y) ~ --- * 2 2 * y y/x * B ~ t*(1-2t), where t = --------------- = (-------------- )/x * x*x+(y-1)*(y-1) 1+((y-1)/x)^2 */ /* INDENT ON */ LD_RE(ans) = pi_2; t = ((ay / ax) / (one + ((ay - one) / ax) * ((ay - one) / ax))) / ax; LD_IM(ans) = t * (one - (t + t)); } else if (ax < E * E * E * E) { /* INDENT OFF */ /* * Tiny x: * when |x| < E^4, (note that y != 1) * 1 1 * A = --- * atan2(2x, 1-x*x-y*y) ~ --- * atan2(2x,1-y*y) * 2 2 * * 1 [ (y+1)*(y+1) ] 1 2 1 2y * B = - log [ ----------- ] = - log (1+ ---) or - log(1+ ----) * 4 [ (y-1)*(y-1) ] 2 y-1 2 1-y */ /* INDENT ON */ LD_RE(ans) = half * atan2l(ax + ax, (one - ay) * (one + ay)); if (ay > one) /* y>1 */ LD_IM(ans) = half * log1pl(two / (ay - one)); else /* y<1 */ LD_IM(ans) = half * log1pl((ay + ay) / (one - ay)); } else { /* INDENT OFF */ /* * normal x,y * 1 * A = --- * atan2(2x, 1-x*x-y*y) * 2 * * 1 [ x*x+(y+1)*(y+1) ] 1 4y * B = - log [ --------------- ] = - log (1+ -----------------) * 4 [ x*x+(y-1)*(y-1) ] 4 x*x + (y-1)*(y-1) */ /* INDENT ON */ t = one - ay; if (iy >= 0x3ffe0000 && iy < 0x40000000) { /* y close to 1 */ LD_RE(ans) = half * (atan2l((ax + ax), (t * (one + ay) - ax * ax))); } else if (ix >= 0x3ffe0000 && ix < 0x40000000) { /* x close to 1 */ LD_RE(ans) = half * atan2l((ax + ax), ((one - ax) * (one + ax) - ay * ay)); } else LD_RE(ans) = half * atan2l((ax + ax), ((one - ax * ax) - ay * ay)); LD_IM(ans) = 0.25L * log1pl((4.0L * ay) / (ax * ax + t * t)); } if (hx < 0) LD_RE(ans) = -LD_RE(ans); if (hy < 0) LD_IM(ans) = -LD_IM(ans); return (ans); }
void domathl (void) { #ifndef NO_LONG_DOUBLE long double f1; long double f2; int i1; f1 = acosl(0.0); fprintf( stdout, "acosl : %Lf\n", f1); f1 = acoshl(0.0); fprintf( stdout, "acoshl : %Lf\n", f1); f1 = asinl(1.0); fprintf( stdout, "asinl : %Lf\n", f1); f1 = asinhl(1.0); fprintf( stdout, "asinhl : %Lf\n", f1); f1 = atanl(M_PI_4); fprintf( stdout, "atanl : %Lf\n", f1); f1 = atan2l(2.3, 2.3); fprintf( stdout, "atan2l : %Lf\n", f1); f1 = atanhl(1.0); fprintf( stdout, "atanhl : %Lf\n", f1); f1 = cbrtl(27.0); fprintf( stdout, "cbrtl : %Lf\n", f1); f1 = ceill(3.5); fprintf( stdout, "ceill : %Lf\n", f1); f1 = copysignl(3.5, -2.5); fprintf( stdout, "copysignl : %Lf\n", f1); f1 = cosl(M_PI_2); fprintf( stdout, "cosl : %Lf\n", f1); f1 = coshl(M_PI_2); fprintf( stdout, "coshl : %Lf\n", f1); f1 = erfl(42.0); fprintf( stdout, "erfl : %Lf\n", f1); f1 = erfcl(42.0); fprintf( stdout, "erfcl : %Lf\n", f1); f1 = expl(0.42); fprintf( stdout, "expl : %Lf\n", f1); f1 = exp2l(0.42); fprintf( stdout, "exp2l : %Lf\n", f1); f1 = expm1l(0.00042); fprintf( stdout, "expm1l : %Lf\n", f1); f1 = fabsl(-1.123); fprintf( stdout, "fabsl : %Lf\n", f1); f1 = fdiml(1.123, 2.123); fprintf( stdout, "fdiml : %Lf\n", f1); f1 = floorl(0.5); fprintf( stdout, "floorl : %Lf\n", f1); f1 = floorl(-0.5); fprintf( stdout, "floorl : %Lf\n", f1); f1 = fmal(2.1, 2.2, 3.01); fprintf( stdout, "fmal : %Lf\n", f1); f1 = fmaxl(-0.42, 0.42); fprintf( stdout, "fmaxl : %Lf\n", f1); f1 = fminl(-0.42, 0.42); fprintf( stdout, "fminl : %Lf\n", f1); f1 = fmodl(42.0, 3.0); fprintf( stdout, "fmodl : %Lf\n", f1); /* no type-specific variant */ i1 = fpclassify(1.0); fprintf( stdout, "fpclassify : %d\n", i1); f1 = frexpl(42.0, &i1); fprintf( stdout, "frexpl : %Lf\n", f1); f1 = hypotl(42.0, 42.0); fprintf( stdout, "hypotl : %Lf\n", f1); i1 = ilogbl(42.0); fprintf( stdout, "ilogbl : %d\n", i1); /* no type-specific variant */ i1 = isfinite(3.0); fprintf( stdout, "isfinite : %d\n", i1); /* no type-specific variant */ i1 = isgreater(3.0, 3.1); fprintf( stdout, "isgreater : %d\n", i1); /* no type-specific variant */ i1 = isgreaterequal(3.0, 3.1); fprintf( stdout, "isgreaterequal : %d\n", i1); /* no type-specific variant */ i1 = isinf(3.0); fprintf( stdout, "isinf : %d\n", i1); /* no type-specific variant */ i1 = isless(3.0, 3.1); fprintf( stdout, "isless : %d\n", i1); /* no type-specific variant */ i1 = islessequal(3.0, 3.1); fprintf( stdout, "islessequal : %d\n", i1); /* no type-specific variant */ i1 = islessgreater(3.0, 3.1); fprintf( stdout, "islessgreater : %d\n", i1); /* no type-specific variant */ i1 = isnan(0.0); fprintf( stdout, "isnan : %d\n", i1); /* no type-specific variant */ i1 = isnormal(3.0); fprintf( stdout, "isnormal : %d\n", i1); /* no type-specific variant */ f1 = isunordered(1.0, 2.0); fprintf( stdout, "isunordered : %d\n", i1); f1 = j0l(1.2); fprintf( stdout, "j0l : %Lf\n", f1); f1 = j1l(1.2); fprintf( stdout, "j1l : %Lf\n", f1); f1 = jnl(2,1.2); fprintf( stdout, "jnl : %Lf\n", f1); f1 = ldexpl(1.2,3); fprintf( stdout, "ldexpl : %Lf\n", f1); f1 = lgammal(42.0); fprintf( stdout, "lgammal : %Lf\n", f1); f1 = llrintl(-0.5); fprintf( stdout, "llrintl : %Lf\n", f1); f1 = llrintl(0.5); fprintf( stdout, "llrintl : %Lf\n", f1); f1 = llroundl(-0.5); fprintf( stdout, "lroundl : %Lf\n", f1); f1 = llroundl(0.5); fprintf( stdout, "lroundl : %Lf\n", f1); f1 = logl(42.0); fprintf( stdout, "logl : %Lf\n", f1); f1 = log10l(42.0); fprintf( stdout, "log10l : %Lf\n", f1); f1 = log1pl(42.0); fprintf( stdout, "log1pl : %Lf\n", f1); f1 = log2l(42.0); fprintf( stdout, "log2l : %Lf\n", f1); f1 = logbl(42.0); fprintf( stdout, "logbl : %Lf\n", f1); f1 = lrintl(-0.5); fprintf( stdout, "lrintl : %Lf\n", f1); f1 = lrintl(0.5); fprintf( stdout, "lrintl : %Lf\n", f1); f1 = lroundl(-0.5); fprintf( stdout, "lroundl : %Lf\n", f1); f1 = lroundl(0.5); fprintf( stdout, "lroundl : %Lf\n", f1); f1 = modfl(42.0,&f2); fprintf( stdout, "lmodfl : %Lf\n", f1); f1 = nanl(""); fprintf( stdout, "nanl : %Lf\n", f1); f1 = nearbyintl(1.5); fprintf( stdout, "nearbyintl : %Lf\n", f1); f1 = nextafterl(1.5,2.0); fprintf( stdout, "nextafterl : %Lf\n", f1); f1 = powl(3.01, 2.0); fprintf( stdout, "powl : %Lf\n", f1); f1 = remainderl(3.01,2.0); fprintf( stdout, "remainderl : %Lf\n", f1); f1 = remquol(29.0,3.0,&i1); fprintf( stdout, "remquol : %Lf\n", f1); f1 = rintl(0.5); fprintf( stdout, "rintl : %Lf\n", f1); f1 = rintl(-0.5); fprintf( stdout, "rintl : %Lf\n", f1); f1 = roundl(0.5); fprintf( stdout, "roundl : %Lf\n", f1); f1 = roundl(-0.5); fprintf( stdout, "roundl : %Lf\n", f1); f1 = scalblnl(1.2,3); fprintf( stdout, "scalblnl : %Lf\n", f1); f1 = scalbnl(1.2,3); fprintf( stdout, "scalbnl : %Lf\n", f1); /* no type-specific variant */ i1 = signbit(1.0); fprintf( stdout, "signbit : %i\n", i1); f1 = sinl(M_PI_4); fprintf( stdout, "sinl : %Lf\n", f1); f1 = sinhl(M_PI_4); fprintf( stdout, "sinhl : %Lf\n", f1); f1 = sqrtl(9.0); fprintf( stdout, "sqrtl : %Lf\n", f1); f1 = tanl(M_PI_4); fprintf( stdout, "tanl : %Lf\n", f1); f1 = tanhl(M_PI_4); fprintf( stdout, "tanhl : %Lf\n", f1); f1 = tgammal(2.1); fprintf( stdout, "tgammal : %Lf\n", f1); f1 = truncl(3.5); fprintf( stdout, "truncl : %Lf\n", f1); f1 = y0l(1.2); fprintf( stdout, "y0l : %Lf\n", f1); f1 = y1l(1.2); fprintf( stdout, "y1l : %Lf\n", f1); f1 = ynl(3,1.2); fprintf( stdout, "ynl : %Lf\n", f1); #endif }
ldcomplex cacosl(ldcomplex z) { long double x, y, t, R, S, A, Am1, B, y2, xm1, xp1, Apx; int ix, iy, hx, hy; ldcomplex ans; x = LD_RE(z); y = LD_IM(z); hx = HI_XWORD(x); hy = HI_XWORD(y); ix = hx & 0x7fffffff; iy = hy & 0x7fffffff; /* x is 0 */ if (x == zero) { if (y == zero || (iy >= 0x7fff0000)) { LD_RE(ans) = pi_2 + pi_2_l; LD_IM(ans) = -y; return (ans); } } /* |y| is inf or NaN */ if (iy >= 0x7fff0000) { if (isinfl(y)) { /* cacos(x + i inf) = pi/2 - i inf */ LD_IM(ans) = -y; if (ix < 0x7fff0000) { LD_RE(ans) = pi_2 + pi_2_l; } else if (isinfl(x)) { if (hx >= 0) LD_RE(ans) = pi_4 + pi_4_l; else LD_RE(ans) = pi3_4 + pi3_4_l; } else { LD_RE(ans) = x; } } else { /* cacos(x + i NaN) = NaN + i NaN */ LD_RE(ans) = y + x; if (isinfl(x)) LD_IM(ans) = -fabsl(x); else LD_IM(ans) = y; } return (ans); } y = fabsl(y); if (ix >= 0x7fff0000) { /* x is inf or NaN */ if (isinfl(x)) { /* x is INF */ LD_IM(ans) = -fabsl(x); if (iy >= 0x7fff0000) { if (isinfl(y)) { /* INDENT OFF */ /* cacos(inf + i inf) = pi/4 - i inf */ /* cacos(-inf+ i inf) =3pi/4 - i inf */ /* INDENT ON */ if (hx >= 0) LD_RE(ans) = pi_4 + pi_4_l; else LD_RE(ans) = pi3_4 + pi3_4_l; } else /* INDENT OFF */ /* cacos(inf + i NaN) = NaN - i inf */ /* INDENT ON */ LD_RE(ans) = y + y; } else { /* INDENT OFF */ /* cacos(inf + iy ) = 0 - i inf */ /* cacos(-inf+ iy ) = pi - i inf */ /* INDENT ON */ if (hx >= 0) LD_RE(ans) = zero; else LD_RE(ans) = pi + pi_l; } } else { /* x is NaN */ /* INDENT OFF */ /* * cacos(NaN + i inf) = NaN - i inf * cacos(NaN + i y ) = NaN + i NaN * cacos(NaN + i NaN) = NaN + i NaN */ /* INDENT ON */ LD_RE(ans) = x + y; if (iy >= 0x7fff0000) { LD_IM(ans) = -y; } else { LD_IM(ans) = x; } } if (hy < 0) LD_IM(ans) = -LD_IM(ans); return (ans); } if (y == zero) { /* region 1: y=0 */ if (ix < 0x3fff0000) { /* |x| < 1 */ LD_RE(ans) = acosl(x); LD_IM(ans) = zero; } else { LD_RE(ans) = zero; x = fabsl(x); if (ix >= ip1) /* i386 ? 2**65 : 2**114 */ LD_IM(ans) = ln2 + logl(x); else if (ix >= 0x3fff8000) /* x > Acrossover */ LD_IM(ans) = logl(x + sqrtl((x - one) * (x + one))); else { xm1 = x - one; LD_IM(ans) = log1pl(xm1 + sqrtl(xm1 * (x + one))); } } } else if (y <= E * fabsl(fabsl(x) - one)) { /* region 2: y < tiny*||x|-1| */ if (ix < 0x3fff0000) { /* x < 1 */ LD_RE(ans) = acosl(x); x = fabsl(x); LD_IM(ans) = y / sqrtl((one + x) * (one - x)); } else if (ix >= ip1) { /* i386 ? 2**65 : 2**114 */ if (hx >= 0) LD_RE(ans) = y / x; else { if (ix >= ip1 + 0x00040000) LD_RE(ans) = pi + pi_l; else { t = pi_l + y / x; LD_RE(ans) = pi + t; } } LD_IM(ans) = ln2 + logl(fabsl(x)); } else { x = fabsl(x); t = sqrtl((x - one) * (x + one)); LD_RE(ans) = (hx >= 0)? y / t : pi - (y / t - pi_l); if (ix >= 0x3fff8000) /* x > Acrossover */ LD_IM(ans) = logl(x + t); else LD_IM(ans) = log1pl(t - (one - x)); } } else if (y < Foursqrtu) { /* region 3 */ t = sqrtl(y); LD_RE(ans) = (hx >= 0)? t : pi + pi_l; LD_IM(ans) = t; } else if (E * y - one >= fabsl(x)) { /* region 4 */ LD_RE(ans) = pi_2 + pi_2_l; LD_IM(ans) = ln2 + logl(y); } else if (ix >= 0x5ffb0000 || iy >= 0x5ffb0000) { /* region 5: x+1 and y are both (>= sqrt(max)/8) i.e. 2**8188 */ t = x / y; LD_RE(ans) = atan2l(y, x); LD_IM(ans) = ln2 + logl(y) + half * log1pl(t * t); } else if (fabsl(x) < Foursqrtu) { /* region 6: x is very small, < 4sqrt(min) */ LD_RE(ans) = pi_2 + pi_2_l; A = sqrtl(one + y * y); if (iy >= 0x3fff8000) /* if y > Acrossover */ LD_IM(ans) = logl(y + A); else LD_IM(ans) = half * log1pl((y + y) * (y + A)); } else { /* safe region */ t = fabsl(x); y2 = y * y; xp1 = t + one; xm1 = t - one; R = sqrtl(xp1 * xp1 + y2); S = sqrtl(xm1 * xm1 + y2); A = half * (R + S); B = t / A; if (B <= Bcrossover) LD_RE(ans) = (hx >= 0)? acosl(B) : acosl(-B); else { /* use atan and an accurate approx to a-x */ Apx = A + t; if (t <= one) LD_RE(ans) = atan2l(sqrtl(half * Apx * (y2 / (R + xp1) + (S - xm1))), x); else LD_RE(ans) = atan2l((y * sqrtl(half * (Apx / (R + xp1) + Apx / (S + xm1)))), x); } if (A <= Acrossover) { /* use log1p and an accurate approx to A-1 */ if (ix < 0x3fff0000) Am1 = half * (y2 / (R + xp1) + y2 / (S - xm1)); else Am1 = half * (y2 / (R + xp1) + (S + xm1)); LD_IM(ans) = log1pl(Am1 + sqrtl(Am1 * (A + one))); } else { LD_IM(ans) = logl(A + sqrtl(A * A - one)); } } if (hy >= 0) LD_IM(ans) = -LD_IM(ans); return (ans); }
static int testl(long double long_double_x, int int_x, long long_x) { int r = 0; r += __finitel(long_double_x); r += __fpclassifyl(long_double_x); r += __isinfl(long_double_x); r += __isnanl(long_double_x); r += __signbitl(long_double_x); r += acoshl(long_double_x); r += acosl(long_double_x); r += asinhl(long_double_x); r += asinl(long_double_x); r += atan2l(long_double_x, long_double_x); r += atanhl(long_double_x); r += atanl(long_double_x); r += cbrtl(long_double_x); r += ceill(long_double_x); r += copysignl(long_double_x, long_double_x); r += coshl(long_double_x); r += cosl(long_double_x); r += erfcl(long_double_x); r += erfl(long_double_x); r += exp2l(long_double_x); r += expl(long_double_x); r += expm1l(long_double_x); r += fabsl(long_double_x); r += fdiml(long_double_x, long_double_x); r += floorl(long_double_x); r += fmal(long_double_x, long_double_x, long_double_x); r += fmaxl(long_double_x, long_double_x); r += fminl(long_double_x, long_double_x); r += fmodl(long_double_x, long_double_x); r += frexpl(long_double_x, &int_x); r += hypotl(long_double_x, long_double_x); r += ilogbl(long_double_x); r += ldexpl(long_double_x, int_x); r += lgammal(long_double_x); r += llrintl(long_double_x); r += llroundl(long_double_x); r += log10l(long_double_x); r += log1pl(long_double_x); r += log2l(long_double_x); r += logbl(long_double_x); r += logl(long_double_x); r += lrintl(long_double_x); r += lroundl(long_double_x); r += modfl(long_double_x, &long_double_x); r += nearbyintl(long_double_x); r += nextafterl(long_double_x, long_double_x); r += nexttowardl(long_double_x, long_double_x); r += powl(long_double_x, long_double_x); r += remainderl(long_double_x, long_double_x); r += remquol(long_double_x, long_double_x, &int_x); r += rintl(long_double_x); r += roundl(long_double_x); r += scalblnl(long_double_x, long_x); r += scalbnl(long_double_x, int_x); r += sinhl(long_double_x); r += sinl(long_double_x); r += sqrtl(long_double_x); r += tanhl(long_double_x); r += tanl(long_double_x); r += tgammal(long_double_x); r += truncl(long_double_x); return r; }
long double complex clogl(long double complex z) { long double ax, ax2h, ax2l, axh, axl, ay, ay2h, ay2l, ayh, ayl; long double sh, sl, t; long double x, y, v; uint16_t hax, hay; int kx, ky; ENTERIT(long double complex); x = creall(z); y = cimagl(z); v = atan2l(y, x); ax = fabsl(x); ay = fabsl(y); if (ax < ay) { t = ax; ax = ay; ay = t; } GET_LDBL_EXPSIGN(hax, ax); kx = hax - 16383; GET_LDBL_EXPSIGN(hay, ay); ky = hay - 16383; /* Handle NaNs and Infs using the general formula. */ if (kx == MAX_EXP || ky == MAX_EXP) RETURNI(CMPLXL(logl(hypotl(x, y)), v)); /* Avoid spurious underflow, and reduce inaccuracies when ax is 1. */ if (ax == 1) { if (ky < (MIN_EXP - 1) / 2) RETURNI(CMPLXL((ay / 2) * ay, v)); RETURNI(CMPLXL(log1pl(ay * ay) / 2, v)); } /* Avoid underflow when ax is not small. Also handle zero args. */ if (kx - ky > MANT_DIG || ay == 0) RETURNI(CMPLXL(logl(ax), v)); /* Avoid overflow. */ if (kx >= MAX_EXP - 1) RETURNI(CMPLXL(logl(hypotl(x * 0x1p-16382L, y * 0x1p-16382L)) + (MAX_EXP - 2) * ln2l_lo + (MAX_EXP - 2) * ln2_hi, v)); if (kx >= (MAX_EXP - 1) / 2) RETURNI(CMPLXL(logl(hypotl(x, y)), v)); /* Reduce inaccuracies and avoid underflow when ax is denormal. */ if (kx <= MIN_EXP - 2) RETURNI(CMPLXL(logl(hypotl(x * 0x1p16383L, y * 0x1p16383L)) + (MIN_EXP - 2) * ln2l_lo + (MIN_EXP - 2) * ln2_hi, v)); /* Avoid remaining underflows (when ax is small but not denormal). */ if (ky < (MIN_EXP - 1) / 2 + MANT_DIG) RETURNI(CMPLXL(logl(hypotl(x, y)), v)); /* Calculate ax*ax and ay*ay exactly using Dekker's algorithm. */ t = (long double)(ax * (MULT_REDUX + 1)); axh = (long double)(ax - t) + t; axl = ax - axh; ax2h = ax * ax; ax2l = axh * axh - ax2h + 2 * axh * axl + axl * axl; t = (long double)(ay * (MULT_REDUX + 1)); ayh = (long double)(ay - t) + t; ayl = ay - ayh; ay2h = ay * ay; ay2l = ayh * ayh - ay2h + 2 * ayh * ayl + ayl * ayl; /* * When log(|z|) is far from 1, accuracy in calculating the sum * of the squares is not very important since log() reduces * inaccuracies. We depended on this to use the general * formula when log(|z|) is very far from 1. When log(|z|) is * moderately far from 1, we go through the extra-precision * calculations to reduce branches and gain a little accuracy. * * When |z| is near 1, we subtract 1 and use log1p() and don't * leave it to log() to subtract 1, since we gain at least 1 bit * of accuracy in this way. * * When |z| is very near 1, subtracting 1 can cancel almost * 3*MANT_DIG bits. We arrange that subtracting 1 is exact in * doubled precision, and then do the rest of the calculation * in sloppy doubled precision. Although large cancellations * often lose lots of accuracy, here the final result is exact * in doubled precision if the large calculation occurs (because * then it is exact in tripled precision and the cancellation * removes enough bits to fit in doubled precision). Thus the * result is accurate in sloppy doubled precision, and the only * significant loss of accuracy is when it is summed and passed * to log1p(). */ sh = ax2h; sl = ay2h; _2sumF(sh, sl); if (sh < 0.5 || sh >= 3) RETURNI(CMPLXL(logl(ay2l + ax2l + sl + sh) / 2, v)); sh -= 1; _2sum(sh, sl); _2sum(ax2l, ay2l); /* Briggs-Kahan algorithm (except we discard the final low term): */ _2sum(sh, ax2l); _2sum(sl, ay2l); t = ax2l + sl; _2sumF(sh, t); RETURNI(CMPLXL(log1pl(ay2l + t + sh) / 2, v)); }
npy_longdouble npy_log1pl(npy_longdouble x) { return log1pl(x); }
TEST(math, log1pl) { ASSERT_EQ(-HUGE_VALL, log1pl(-1.0L)); ASSERT_TRUE(isnan(log1pl(nanl("")))); ASSERT_TRUE(isinf(log1pl(HUGE_VALL))); ASSERT_DOUBLE_EQ(1.0L, log1pl(M_E - 1.0L)); }