示例#1
0
文件: clogl.c 项目: bahamas10/openzfs
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);
}
示例#2
0
文件: pr43730.c 项目: 0day-ci/gcc
int
bugfun(long double x, long double y)
{
  int result;

  if (isinfl(x))
    result = isinfl(y);
  else
    {
      int kx, ky;
      kx = ky = 1;
      result = (kx == ky);
    }
  return (result);
}
示例#3
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);
}
示例#4
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);
}
示例#5
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);
}
示例#6
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 {
示例#7
0
long double
hypotl(long double x, long double y) {
	int n0, n1, n2, n3;
	long double t1, t2, y1, y2, w;
	int *px = (int *) &x, *py = (int *) &y;
	int *pt1 = (int *) &t1, *py1 = (int *) &y1;
	enum fp_direction_type rd;
	int j, k, nx, ny, nz;

	if ((*(int *) &one) != 0) {	/* determine word ordering */
		n0 = 0;
		n1 = 1;
		n2 = 2;
		n3 = 3;
	} else {
		n0 = 3;
		n1 = 2;
		n2 = 1;
		n3 = 0;
	}

	px[n0] &= 0x7fffffff;	/* clear sign bit of x and y */
	py[n0] &= 0x7fffffff;
	k = 0x7fff0000;
	nx = px[n0] & k;	/* exponent of x and y */
	ny = py[n0] & k;
	if (ny > nx) {
		w = x;
		x = y;
		y = w;
		nz = ny;
		ny = nx;
		nx = nz;
	}			/* force x > y */
	if ((nx - ny) >= 0x00730000)
		return (x + y);	/* x/y >= 2**116 */
	if (nx < 0x5ff30000 && ny > 0x205b0000) {	/* medium x,y */
		/* save and set RD to Rounding to nearest */
		rd = __swapRD(fp_nearest);
		w = x - y;
		if (w > y) {
			pt1[n0] = px[n0];
			pt1[n1] = px[n1];
			pt1[n2] = pt1[n3] = 0;
			t2 = x - t1;
			x = sqrtl(t1 * t1 - (y * (-y) - t2 * (x + t1)));
		} else {
			x = x + x;
			py1[n0] = py[n0];
			py1[n1] = py[n1];
			py1[n2] = py1[n3] = 0;
			y2 = y - y1;
			pt1[n0] = px[n0];
			pt1[n1] = px[n1];
			pt1[n2] = pt1[n3] = 0;
			t2 = x - t1;
			x = sqrtl(t1 * y1 - (w * (-w) - (t2 * y1 + y2 * x)));
		}
		if (rd != fp_nearest)
			(void) __swapRD(rd);	/* restore rounding mode */
		return (x);
	} else {
		if (nx == k || ny == k) {	/* x or y is INF or NaN */
			if (isinfl(x))
				t2 = x;
			else if (isinfl(y))
				t2 = y;
			else
				t2 = x + y;	/* invalid if x or y is sNaN */
			return (t2);
		}
		if (ny == 0) {
			if (y == zero || x == zero)
				return (x + y);
			t1 = scalbnl(one, 16381);
			x *= t1;
			y *= t1;
			return (scalbnl(one, -16381) * hypotl(x, y));
		}
		j = nx - 0x3fff0000;
		px[n0] -= j;
		py[n0] -= j;
		pt1[n0] = nx;
		pt1[n1] = pt1[n2] = pt1[n3] = 0;
		return (t1 * hypotl(x, y));
	}
}
示例#8
0
文件: builtins-63.c 项目: 0day-ci/gcc
int test1l(long double x)
{
  return isinfl(x);
}
示例#9
0
static int
print_float (struct printf_info *pinfo, char *startp, char *endp, int *signp, snv_long_double n)
{
  int prec, fmtch;
  char *p, *t;
  snv_long_double fract;
  int expcnt, gformat = 0;
  snv_long_double integer, tmp;
  char expbuf[10];

  prec = pinfo->prec;
  fmtch = pinfo->spec;
  t = startp;
  *signp = 0;

  /* Do the special cases: nans, infinities, zero, and negative numbers. */
  if (isnanl (n))
    {
      /* Not-a-numbers are printed as a simple string. */
      *t++ = fmtch < 'a' ? 'N' : 'n';
      *t++ = fmtch < 'a' ? 'A' : 'a';
      *t++ = fmtch < 'a' ? 'N' : 'n';
      return t - startp;
    }

  /* Zero and infinity also can have a sign in front of them. */
  if (copysignl (1.0, n) < 0.0)
    {
      n = -1.0 * n;
      *signp = '-';
    }

  if (isinfl (n))
    {
      /* Infinities are printed as a simple string. */
      *t++ = fmtch < 'a' ? 'I' : 'i';
      *t++ = fmtch < 'a' ? 'N' : 'n';
      *t++ = fmtch < 'a' ? 'F' : 'f';
      goto set_signp;
    }

  expcnt = 0;
  fract = modfl (n, &integer);

  /* get an extra slot for rounding. */
  *t++ = '0';

  /* get integer portion of number; put into the end of the buffer; the
     .01 is added for modfl (356.0 / 10, &integer) returning .59999999...  */
  for (p = endp - 1; p >= startp && integer; ++expcnt)
    {
      tmp = modfl (integer / 10, &integer);
      *p-- = '0' + ((int) ((tmp + .01L) * 10));
    }

  switch (fmtch)
    {
    case 'g':
    case 'G':
      gformat = 1;

      /* a precision of 0 is treated as a precision of 1. */
      if (!prec)
	pinfo->prec = ++prec;

      /* ``The style used depends on the value converted; style e
         will be used only if the exponent resulting from the
         conversion is less than -4 or greater than the precision.''
                -- ANSI X3J11 */
      if (expcnt > prec || (!expcnt && fract && fract < .0001L))
	{
	  /* g/G format counts "significant digits, not digits of
	     precision; for the e/E format, this just causes an
	     off-by-one problem, i.e. g/G considers the digit
	     before the decimal point significant and e/E doesn't
	     count it as precision.  */
	  --prec;
	  fmtch -= 2;		/* G->E, g->e */
	  goto eformat;
	}
      else
	{
          /* Decrement precision */
          if (n != 0.0L)
	    prec -= (endp - p) - 1;
	  else
	    prec--;

	  goto fformat;
	}

    case 'f':
    case 'F':
    fformat:
      /* reverse integer into beginning of buffer */
      if (expcnt)
	for (; ++p < endp; *t++ = *p);
      else
	*t++ = '0';

      /* If precision required or alternate flag set, add in a
         decimal point.  */
      if (pinfo->prec || pinfo->alt)
	*t++ = '.';

      /* if requires more precision and some fraction left */
      if (fract)
	{
	  if (prec)
	    {
	      /* For %g, if no integer part, don't count initial
	         zeros as significant digits. */
	      do
		{
		  fract = modfl (fract * 10, &tmp);
		  *t++ = '0' + ((int) tmp);
		}
	      while (!tmp && !expcnt && gformat);

	      while (--prec && fract)
		{
		  fract = modfl (fract * 10, &tmp);
		  *t++ = '0' + ((int) tmp);
		}
	    }

	  if (fract)
	    startp =
	      print_float_round (fract, (int *) NULL, startp, t - 1, (char) 0, signp);
	}

      break;

    case 'e':
    case 'E':
    eformat:
      if (expcnt)
	{
	  *t++ = *++p;
	  if (pinfo->prec || pinfo->alt)
	    *t++ = '.';

	  /* if requires more precision and some integer left */
	  for (; prec && ++p < endp; --prec)
	    *t++ = *p;

	  /* if done precision and more of the integer component,
	     round using it; adjust fract so we don't re-round
	     later.  */
	  if (!prec && ++p < endp)
	    {
	      fract = 0;
	      startp = print_float_round ((snv_long_double) 0, &expcnt, startp, t - 1, *p, signp);
	    }

	  /* adjust expcnt for digit in front of decimal */
	  --expcnt;
	}

      /* until first fractional digit, decrement exponent */
      else if (fract)
	{
	  /* adjust expcnt for digit in front of decimal */
	  for (expcnt = -1;; --expcnt)
	    {
	      fract = modfl (fract * 10, &tmp);
	      if (tmp)
		break;
	    }
	  *t++ = '0' + ((int) tmp);
	  if (pinfo->prec || pinfo->alt)
	    *t++ = '.';
	}

      else
	{
	  *t++ = '0';
	  if (pinfo->prec || pinfo->alt)
	    *t++ = '.';
	}

      /* if requires more precision and some fraction left */
      if (fract)
	{
	  if (prec)
	    do
	      {
		fract = modfl (fract * 10, &tmp);
		*t++ = '0' + ((int) tmp);
	      }
	    while (--prec && fract);

	  if (fract)
	    startp = print_float_round (fract, &expcnt, startp, t - 1, (char) 0, signp);
	}
      break;

    default:
      abort ();
    }

  /* %e/%f/%#g add 0's for precision, others trim 0's */
  if (gformat && !pinfo->alt)
    {
      while (t > startp && *--t == '0');
      if (*t != '.')
        ++t;
    }
  else
    for (; prec--; *t++ = '0');

  if (fmtch == 'e' || fmtch == 'E')
    {
      *t++ = fmtch;
      if (expcnt < 0)
        {
          expcnt = -expcnt;
          *t++ = '-';
        }
      else
        *t++ = '+';

      p = expbuf;
      do
        *p++ = '0' + (expcnt % 10);
      while ((expcnt /= 10) > 9);
      *p++ = '0' + expcnt;
      while (p > expbuf)
	*t++ = *--p;
    }

set_signp:
  if (!*signp)
    {
      if (pinfo->showsign)
        *signp = '+';
      else if (pinfo->space)
        *signp = ' ';
    }

  return (t - startp);
}