Ejemplo n.º 1
0
ldcomplex
csinhl(ldcomplex z) {
	long double t, x, y, S, C;
	int hx, ix, hy, iy, n;
	ldcomplex ans;

	x = LD_RE(z);
	y = LD_IM(z);
	hx = HI_XWORD(x);
	ix = hx & 0x7fffffff;
	hy = HI_XWORD(y);
	iy = hy & 0x7fffffff;
	x = fabsl(x);
	y = fabsl(y);

	(void) sincosl(y, &S, &C);
	if (ix >= 0x4004e000) {	/* |x| > 60 = prec/2 (14,28,34,60) */
		if (ix >= 0x400C62E4) {	/* |x| > 11356.52... ~ log(2**16384) */
			if (ix >= 0x7fff0000) {	/* |x| is inf or NaN */
				if (y == zero) {
					LD_RE(ans) = x;
					LD_IM(ans) = y;
				} else if (iy >= 0x7fff0000) {
					LD_RE(ans) = x;
					LD_IM(ans) = x - y;
				} else {
					LD_RE(ans) = C * x;
					LD_IM(ans) = S * x;
				}
			} else {
				/* return exp(x)=t*2**n */
				t = __k_cexpl(x, &n);
				LD_RE(ans) = scalbnl(C * t, n - 1);
				LD_IM(ans) = scalbnl(S * t, n - 1);
			}
		} else {
			t = expl(x) * half;
			LD_RE(ans) = C * t;
			LD_IM(ans) = S * t;
		}
	} else {
		if (x == zero) {	/* x = 0, return (0,S) */
			LD_RE(ans) = zero;
			LD_IM(ans) = S;
		} else {
			LD_RE(ans) = C * sinhl(x);
			LD_IM(ans) = S * coshl(x);
		}
	}
	if (hx < 0)
		LD_RE(ans) = -LD_RE(ans);
	if (hy < 0)
		LD_IM(ans) = -LD_IM(ans);
	return (ans);
}
Ejemplo n.º 2
0
ldcomplex
casinhl(ldcomplex z) {
	ldcomplex w, r, ans;

	LD_RE(w) = -LD_IM(z);
	LD_IM(w) = LD_RE(z);
	r = casinl(w);
	LD_RE(ans) = LD_IM(r);
	LD_IM(ans) = -LD_RE(r);
	return (ans);
}
Ejemplo n.º 3
0
ldcomplex
catanhl(ldcomplex z) {
	long double x, y;
	ldcomplex ans, ct;

	x = LD_RE(z);
	y = LD_IM(z);
	LD_RE(z) = -y;
	LD_IM(z) = x;
	ct = catanl(z);
	LD_RE(ans) = LD_IM(ct);
	LD_IM(ans) = -LD_RE(ct);
	return (ans);
}
Ejemplo n.º 4
0
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);
}
Ejemplo n.º 5
0
ldcomplex
clogl(ldcomplex z) {
	ldcomplex ans;
	long double x, y, t, ax, ay;
	int n, ix, iy, hx, hy;

	x = LD_RE(z);
	y = LD_IM(z);
	hx = HI_XWORD(x);
	hy = HI_XWORD(y);
	ix = hx & 0x7fffffff;
	iy = hy & 0x7fffffff;
	ay = fabsl(y);
	ax = fabsl(x);
	LD_IM(ans) = atan2l(y, x);
	if (ix < iy || (ix == iy && ix < 0x7fff0000 && ax < ay)) {
			/* swap x and y to force ax>=ay */
		t = ax;
		ax = ay;
		ay = t;
		n = ix, ix = iy;
		iy = n;
	}
	n = (ix - iy) >> 16;
	if (ix >= 0x7fff0000) {	/* x or y is Inf or NaN */
		if (isinfl(ax))
			LD_RE(ans) = ax;
		else if (isinfl(ay))
			LD_RE(ans) = ay;
		else
			LD_RE(ans) = ax + ay;
	} else if (ay == zero)
		LD_RE(ans) = logl(ax);
	else if (((0x3fffffff - ix) ^ (ix - 0x3ffe0000)) >= 0) {
							/* 0.5 <= x < 2 */
		if (ix >= 0x3fff0000) {
			if (ax == one)
				LD_RE(ans) = half * log1pl(ay * ay);
			else if (n >= SIGP7)
				LD_RE(ans) = logl(ax);
			else
				LD_RE(ans) = half * (log1pl(ay * ay + (ax -
					one) * (ax + one)));
		} else if (n >= SIGP7)
			LD_RE(ans) = logl(ax);
		else
			LD_RE(ans) = __k_clog_rl(x, y, &t);
	} else if (n >= HSIGP7)
		LD_RE(ans) = logl(ax);
	else if (ix < 0x5f3f0000 && iy >= 0x20bf0000)
		/* 2**-8000 < y < x < 2**8000 */
		LD_RE(ans) = half * logl(ax * ax + ay * ay);
	else {
		t = ay / ax;
		LD_RE(ans) = logl(ax) + half * log1pl(t * t);
	}
	return (ans);
}
Ejemplo n.º 6
0
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);
}
Ejemplo n.º 7
0
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);
}
Ejemplo n.º 8
0
ldcomplex
csqrtl(ldcomplex z) {
	ldcomplex ans;
	long double x, y, t, ax, ay;
	int n, ix, iy, hx, hy;

	x = LD_RE(z);
	y = LD_IM(z);
	hx = HI_XWORD(x);
	hy = HI_XWORD(y);
	ix = hx & 0x7fffffff;
	iy = hy & 0x7fffffff;
	ay = fabsl(y);
	ax = fabsl(x);
	if (ix >= 0x7fff0000 || iy >= 0x7fff0000) {
		/* x or y is Inf or NaN */
		if (isinfl(y))
			LD_IM(ans) = LD_RE(ans) = ay;
		else if (isinfl(x)) {
			if (hx > 0) {
				LD_RE(ans) = ax;
				LD_IM(ans) = ay * zero;
			} else {
				LD_RE(ans) = ay * zero;
				LD_IM(ans) = ax;
			}
		} else
			LD_IM(ans) = LD_RE(ans) = ax + ay;
	} else if (y == zero) {
		if (hx >= 0) {
			LD_RE(ans) = sqrtl(ax);
			LD_IM(ans) = zero;
		} else {
			LD_IM(ans) = sqrtl(ax);
			LD_RE(ans) = zero;
		}
	} else if (ix >= iy) {
		n = (ix - iy) >> 16;
#if defined(__x86)		/* 64 significant bits */
		if (n >= 35)
#else				/* 113 significant bits  */
		if (n >= 60)
#endif
			t = sqrtl(ax);
		else if (ix >= 0x5f3f0000) {	/* x > 2**8000 */
			ax *= twom9001;
			y *= twom9001;
			t = two4500 * sqrtl(ax + sqrtl(ax * ax + y * y));
		} else if (iy <= 0x20bf0000) {	/* y < 2**-8000 */
			ax *= two8999;
			y *= two8999;
			t = twom4500 * sqrtl(ax + sqrtl(ax * ax + y * y));
		} else
			t = sqrtl(half * (ax + sqrtl(ax * ax + y * y)));

		if (hx >= 0) {
			LD_RE(ans) = t;
			LD_IM(ans) = ay / (t + t);
		} else {
			LD_IM(ans) = t;
			LD_RE(ans) = ay / (t + t);
		}
	} else {
Ejemplo n.º 9
0
long double
cabsl(ldcomplex z) {
	return (hypotl(LD_RE(z), LD_IM(z)));
}
Ejemplo n.º 10
0
long double
cargl(ldcomplex z) {
    return (atan2l(LD_IM(z), LD_RE(z)));
}
Ejemplo n.º 11
0
ldcomplex
cpowl(ldcomplex z, ldcomplex w) {
	ldcomplex ans;
	long double x, y, u, v, t, c, s, r;
	long double t1, t2, t3, t4, x1, x2, y1, y2, u1, v1, b[4], w1, w2;
	int ix, iy, hx, hy, hv, hu, iu, iv, i, j, k;

	x = LD_RE(z);
	y = LD_IM(z);
	u = LD_RE(w);
	v = LD_IM(w);
	hx = HI_XWORD(x);
	hy = HI_XWORD(y);
	hu = HI_XWORD(u);
	hv = HI_XWORD(v);
	ix = hx & 0x7fffffff;
	iy = hy & 0x7fffffff;
	iu = hu & 0x7fffffff;
	iv = hv & 0x7fffffff;

	j = 0;
	if (v == zero) {	/* z**(real) */
		if (u == one) {	/* (anything) ** 1  is itself */
			LD_RE(ans) = x;
			LD_IM(ans) = y;
		} else if (u == zero) {	/* (anything) ** 0  is 1 */
			LD_RE(ans) = one;
			LD_IM(ans) = zero;
		} else if (y == zero) {	/* real ** real */
			LD_IM(ans) = zero;
			if (hx < 0 && ix < hiinf && iu < hiinf) {
			/* -x ** u  is exp(i*pi*u)*pow(x,u) */
				r = powl(-x, u);
				sincospil(u, &s, &c);
				LD_RE(ans) = (c == zero)? c: c * r;
				LD_IM(ans) = (s == zero)? s: s * r;
			} else
				LD_RE(ans) = powl(x, u);
		} else if (x == zero || ix >= hiinf || iy >= hiinf) {
			if (isnanl(x) || isnanl(y) || isnanl(u))
				LD_RE(ans) = LD_IM(ans) = x + y + u;
			else {
				if (x == zero)
					r = fabsl(y);
				else
					r = fabsl(x) + fabsl(y);
				t = atan2pil(y, x);
				sincospil(t * u, &s, &c);
				LD_RE(ans) = (c == zero)? c: c * r;
				LD_IM(ans) = (s == zero)? s: s * r;
			}
		} else if (fabsl(x) == fabsl(y)) {    /* |x| = |y| */
			if (hx >= 0) {
				t = (hy >= 0)? 0.25L : -0.25L;
				sincospil(t * u, &s, &c);
			} else if ((LAST(u) & 3) == 0) {
				t = (hy >= 0)? 0.75L : -0.75L;
				sincospil(t * u, &s, &c);
			} else {
				r = (hy >= 0)? u : -u;
				t = -0.25L * r;
				w1 = r + t;
				w2 = t - (w1 - r);
				sincospil(w1, &t1, &t2);
				sincospil(w2, &t3, &t4);
				s = t1 * t4 + t3 * t2;
				c = t2 * t4 - t1 * t3;
			}
			if (ix < 0x3ffe0000)	/* |x| < 1/2 */
				r = powl(fabsl(x + x), u) * exp2l(-0.5L * u);
			else if (ix >= 0x3fff0000 || iu < 0x400cfff8)
				/* |x| >= 1 or |u| < 16383 */
				r = powl(fabsl(x), u) * exp2l(0.5L * u);
			else   /* special treatment */
				j = 2;
			if (j == 0) {
				LD_RE(ans) = (c == zero)? c: c * r;
				LD_IM(ans) = (s == zero)? s: s * r;
			}
		} else
			j = 1;
		if (j == 0)
			return (ans);
	}
	if (iu >= hiinf || iv >= hiinf || ix >= hiinf || iy >= hiinf) {
		/*
		 * non-zero imag part(s) with inf component(s) yields NaN
		 */
		t = fabsl(x) + fabsl(y) + fabsl(u) + fabsl(v);
		LD_RE(ans) = LD_IM(ans) = t - t;
	} else {
		k = 0;	/* no scaling */
		if (iu > 0x7ffe0000 || iv > 0x7ffe0000) {
			u *= 1.52587890625000000000e-05L;
			v *= 1.52587890625000000000e-05L;
			k = 1;	/* scale u and v by 2**-16 */
		}
		/*
		 * Use similated higher precision arithmetic to compute:
		 * r = u * log(hypot(x, y)) - v * atan2(y, x)
		 * q = u * atan2(y, x) + v * log(hypot(x, y))
		 */

		t1 = __k_clog_rl(x, y, &t2);
		t3 = __k_atan2l(y, x, &t4);
		x1 = t1; HALF(x1);
		y1 = t3; HALF(y1);
		u1 = u; HALF(u1);
		v1 = v; HALF(v1);
		x2 = t2 - (x1 - t1);    /* log(hypot(x,y)) = x1 + x2 */
		y2 = t4 - (y1 - t3);    /* atan2(y,x) = y1 + y2 */
		/* compute q = u * atan2(y, x) + v * log(hypot(x, y)) */
		if (j != 2) {
			b[0] = u1 * y1;
			b[1] = (u - u1) * y1 + u * y2;
			if (j == 1) {	/* v = 0 */
				w1 = b[0] + b[1];
				w2 = b[1] - (w1 - b[0]);
			} else {
				b[2] = v1 * x1;
				b[3] = (v - v1) * x1 + v * x2;
				w1 = sum4fpl(b, &w2);
			}
			sincosl(w1, &t1, &t2);
			sincosl(w2, &t3, &t4);
			s = t1 * t4 + t3 * t2;
			c = t2 * t4 - t1 * t3;
			if (k == 1)	/* square j times */
				for (i = 0; i < 10; i++) {
					t1 = s * c;
					c = (c + s) * (c - s);
					s = t1 + t1;
				}
		}
		/* compute r = u * (t1, t2) - v * (t3, t4) */
		b[0] = u1 * x1;
		b[1] = (u - u1) * x1 + u * x2;
		if (j == 1) {   /* v = 0 */
			w1 = b[0] + b[1];
			w2 = b[1] - (w1 - b[0]);
		} else {
			b[2] = -v1 * y1;
			b[3] = (v1 - v) * y1 - v * y2;
			w1 = sum4fpl(b, &w2);
		}
		/* scale back unless w1 is large enough to cause exception */
		if (k != 0 && fabsl(w1) < 20000.0L) {
			w1 *= 65536.0L; w2 *= 65536.0L;
		}
		hx = HI_XWORD(w1);
		ix = hx & 0x7fffffff;
		/* compute exp(w1 + w2) */
		k = 0;
		if (ix < 0x3f8c0000) /* exp(tiny < 2**-115) = 1 */
			r = one;
		else if (ix >= 0x400c6760) /* overflow/underflow */
			r = (hx < 0)? tiny * tiny : huge * huge;
		else {  /* compute exp(w1 + w2) */
			k = (int) (invln2 * w1 + ((hx >= 0)? 0.5L : -0.5L));
			t1 = (long double) k;
			t2 = w1 - t1 * ln2hil;
			t3 = w2 - t1 * ln2lol;
			r = expl(t2 + t3);
		}
		if (c != zero) c *= r;
		if (s != zero) s *= r;
		if (k != 0) {
			c = scalbnl(c, k);
			s = scalbnl(s, k);
		}
		LD_RE(ans) = c;
		LD_IM(ans) = s;
	}
	return (ans);
}