strictmathtest.java

来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 1,689 行 · 第 1/4 页

JAVA
1,689
字号
		}

		// Break sum from i=0 to 10 ATi*z**(i+1) into odd and even poly.
		double z = x * x;
		double w = z * z;
		double s1 = z * (AT0 + w * (AT2 + w * (AT4 + w * (AT6 + w * (AT8 + w * AT10)))));
		double s2 = w * (AT1 + w * (AT3 + w * (AT5 + w * (AT7 + w * AT9))));
		if (hi == 0)
			return negative ? x * (s1 + s2) - x : x - x * (s1 + s2);
		z = hi - ((x * (s1 + s2) - lo) - x);
		return negative ? -z : z;
	}

	/**
	 * A special version of the trigonometric function <em>arctan</em>, for
	 * converting rectangular coordinates <em>(x, y)</em> to polar
	 * <em>(r, theta)</em>. This computes the arctangent of x/y in the range
	 * of -pi to pi radians (-180 to 180 degrees). Special cases:<ul>
	 * <li>If either argument is NaN, the result is NaN.</li>
	 * <li>If the first argument is positive zero and the second argument is
	 * positive, or the first argument is positive and finite and the second
	 * argument is positive infinity, then the result is positive zero.</li>
	 * <li>If the first argument is negative zero and the second argument is
	 * positive, or the first argument is negative and finite and the second
	 * argument is positive infinity, then the result is negative zero.</li>
	 * <li>If the first argument is positive zero and the second argument is
	 * negative, or the first argument is positive and finite and the second
	 * argument is negative infinity, then the result is the double value
	 * closest to pi.</li>
	 * <li>If the first argument is negative zero and the second argument is
	 * negative, or the first argument is negative and finite and the second
	 * argument is negative infinity, then the result is the double value
	 * closest to -pi.</li>
	 * <li>If the first argument is positive and the second argument is
	 * positive zero or negative zero, or the first argument is positive
	 * infinity and the second argument is finite, then the result is the
	 * double value closest to pi/2.</li>
	 * <li>If the first argument is negative and the second argument is
	 * positive zero or negative zero, or the first argument is negative
	 * infinity and the second argument is finite, then the result is the
	 * double value closest to -pi/2.</li>
	 * <li>If both arguments are positive infinity, then the result is the
	 * double value closest to pi/4.</li>
	 * <li>If the first argument is positive infinity and the second argument
	 * is negative infinity, then the result is the double value closest to
	 * 3*pi/4.</li>
	 * <li>If the first argument is negative infinity and the second argument
	 * is positive infinity, then the result is the double value closest to
	 * -pi/4.</li>
	 * <li>If both arguments are negative infinity, then the result is the
	 * double value closest to -3*pi/4.</li>
	 *
	 * </ul><p>This returns theta, the angle of the point. To get r, albeit
	 * slightly inaccurately, use sqrt(x*x+y*y).
	 *
	 * @param y the y position
	 * @param x the x position
	 * @return <em>theta</em> in the conversion of (x, y) to (r, theta)
	 * @see #atan(double)
	 */
	public static double atan2(double y, double x) {
		if (x != x || y != y)
			return Double.NaN;
		if (x == 1)
			return atan(y);
		if (x == Double.POSITIVE_INFINITY) {
			if (y == Double.POSITIVE_INFINITY)
				return PI / 4;
			if (y == Double.NEGATIVE_INFINITY)
				return -PI / 4;
			return 0 * y;
		}
		if (x == Double.NEGATIVE_INFINITY) {
			if (y == Double.POSITIVE_INFINITY)
				return 3 * PI / 4;
			if (y == Double.NEGATIVE_INFINITY)
				return -3 * PI / 4;
			return (1 / (0 * y) == Double.POSITIVE_INFINITY) ? PI : -PI;
		}
		if (y == 0) {
			if (1 / (0 * x) == Double.POSITIVE_INFINITY)
				return y;
			return (1 / y == Double.POSITIVE_INFINITY) ? PI : -PI;
		}
		if (y == Double.POSITIVE_INFINITY || y == Double.NEGATIVE_INFINITY || x == 0)
			return y < 0 ? -PI / 2 : PI / 2;

		double z = abs(y / x); // Safe to do y/x.
		if (z > TWO_60)
			z = PI / 2 + 0.5 * PI_L;
		else if (x < 0 && z < 1 / TWO_60)
			z = 0;
		else
			z = atan(z);
		if (x > 0)
			return y > 0 ? z : -z;
		return y > 0 ? PI - (z - PI_L) : z - PI_L - PI;
	}

	/**
	 * Take <em>e</em><sup>a</sup>.  The opposite of <code>log()</code>. If the
	 * argument is NaN, the result is NaN; if the argument is positive infinity,
	 * the result is positive infinity; and if the argument is negative
	 * infinity, the result is positive zero.
	 *
	 * @param x the number to raise to the power
	 * @return the number raised to the power of <em>e</em>
	 * @see #log(double)
	 * @see #pow(double, double)
	 */
	public static double exp(double x) {
		if (x != x)
			return x;
		if (x > EXP_LIMIT_H)
			return Double.POSITIVE_INFINITY;
		if (x < EXP_LIMIT_L)
			return 0;

		// Argument reduction.
		double hi;
		double lo;
		int k;
		double t = abs(x);
		if (t > 0.5 * LN2) {
			if (t < 1.5 * LN2) {
				hi = t - LN2_H;
				lo = LN2_L;
				k = 1;
			} else {
				k = (int) (INV_LN2 * t + 0.5);
				hi = t - k * LN2_H;
				lo = k * LN2_L;
			}
			if (x < 0) {
				hi = -hi;
				lo = -lo;
				k = -k;
			}
			x = hi - lo;
		} else if (t < 1 / TWO_28)
			return 1;
		else
			lo = hi = k = 0;

		// Now x is in primary range.
		t = x * x;
		double c = x - t * (P1 + t * (P2 + t * (P3 + t * (P4 + t * P5))));
		if (k == 0)
			return 1 - (x * c / (c - 2) - x);
		double y = 1 - (lo - x * c / (2 - c) - hi);
		return scale(y, k);
	}

	/**
	 * Take ln(a) (the natural log).  The opposite of <code>exp()</code>. If the
	 * argument is NaN or negative, the result is NaN; if the argument is
	 * positive infinity, the result is positive infinity; and if the argument
	 * is either zero, the result is negative infinity.
	 *
	 * <p>Note that the way to get log<sub>b</sub>(a) is to do this:
	 * <code>ln(a) / ln(b)</code>.
	 *
	 * @param x the number to take the natural log of
	 * @return the natural log of <code>a</code>
	 * @see #exp(double)
	 */
	public static double log(double x) {
		if (x == 0)
			return Double.NEGATIVE_INFINITY;
		if (x < 0)
			return Double.NaN;
		if (!(x < Double.POSITIVE_INFINITY))
			return x;

		// Normalize x.
		long bits = Double.doubleToLongBits(x);
		int exp = (int) (bits >> 52);
		if (exp == 0) // Subnormal x.
			{
			x *= TWO_54;
			bits = Double.doubleToLongBits(x);
			exp = (int) (bits >> 52) - 54;
		}
		exp -= 1023; // Unbias exponent.
		bits = (bits & 0x000fffffffffffffL) | 0x3ff0000000000000L;
		x = Double.longBitsToDouble(bits);
		if (x >= SQRT_2) {
			x *= 0.5;
			exp++;
		}
		x--;
		if (abs(x) < 1 / TWO_20) {
			if (x == 0)
				return exp * LN2_H + exp * LN2_L;
			double r = x * x * (0.5 - 1 / 3.0 * x);
			if (exp == 0)
				return x - r;
			return exp * LN2_H - ((r - exp * LN2_L) - x);
		}
		double s = x / (2 + x);
		double z = s * s;
		double w = z * z;
		double t1 = w * (LG2 + w * (LG4 + w * LG6));
		double t2 = z * (LG1 + w * (LG3 + w * (LG5 + w * LG7)));
		double r = t2 + t1;
		if (bits >= 0x3ff6174a00000000L && bits < 0x3ff6b85200000000L) {
			double h = 0.5 * x * x; // Need more accuracy for x near sqrt(2).
			if (exp == 0)
				return x - (h - s * (h + r));
			return exp * LN2_H - ((h - (s * (h + r) + exp * LN2_L)) - x);
		}
		if (exp == 0)
			return x - s * (x - r);
		return exp * LN2_H - ((s * (x - r) - exp * LN2_L) - x);
	}

	/**
	 * Take a square root. If the argument is NaN or negative, the result is
	 * NaN; if the argument is positive infinity, the result is positive
	 * infinity; and if the result is either zero, the result is the same.
	 *
	 * <p>For other roots, use pow(x, 1/rootNumber).
	 *
	 * @param x the numeric argument
	 * @return the square root of the argument
	 * @see #pow(double, double)
	 */
	public static double sqrt(double x) {
		if (x < 0)
			return Double.NaN;
		if (x == 0 || !(x < Double.POSITIVE_INFINITY))
			return x;

		// Normalize x.
		long bits = Double.doubleToLongBits(x);
		int exp = (int) (bits >> 52);
		if (exp == 0) // Subnormal x.
			{
			x *= TWO_54;
			bits = Double.doubleToLongBits(x);
			exp = (int) (bits >> 52) - 54;
		}
		exp -= 1023; // Unbias exponent.
		bits = (bits & 0x000fffffffffffffL) | 0x0010000000000000L;
		if ((exp & 1) == 1) // Odd exp, double x to make it even.
			bits <<= 1;
		exp >>= 1;

		// Generate sqrt(x) bit by bit.
		bits <<= 1;
		long q = 0;
		long s = 0;
		long r = 0x0020000000000000L; // Move r right to left.
		while (r != 0) {
			long t = s + r;
			if (t <= bits) {
				s = t + r;
				bits -= t;
				q += r;
			}
			bits <<= 1;
			r >>= 1;
		}

		// Use floating add to round correctly.
		if (bits != 0)
			q += q & 1;
		return Double.longBitsToDouble((q >> 1) + ((exp + 1022L) << 52));
	}

	/**
	 * Raise a number to a power. Special cases:<ul>
	 * <li>If the second argument is positive or negative zero, then the result
	 * is 1.0.</li>
	 * <li>If the second argument is 1.0, then the result is the same as the
	 * first argument.</li>
	 * <li>If the second argument is NaN, then the result is NaN.</li>
	 * <li>If the first argument is NaN and the second argument is nonzero,
	 * then the result is NaN.</li>
	 * <li>If the absolute value of the first argument is greater than 1 and
	 * the second argument is positive infinity, or the absolute value of the
	 * first argument is less than 1 and the second argument is negative
	 * infinity, then the result is positive infinity.</li>
	 * <li>If the absolute value of the first argument is greater than 1 and
	 * the second argument is negative infinity, or the absolute value of the
	 * first argument is less than 1 and the second argument is positive
	 * infinity, then the result is positive zero.</li>
	 * <li>If the absolute value of the first argument equals 1 and the second
	 * argument is infinite, then the result is NaN.</li>
	 * <li>If the first argument is positive zero and the second argument is
	 * greater than zero, or the first argument is positive infinity and the
	 * second argument is less than zero, then the result is positive zero.</li>
	 * <li>If the first argument is positive zero and the second argument is
	 * less than zero, or the first argument is positive infinity and the
	 * second argument is greater than zero, then the result is positive
	 * infinity.</li>
	 * <li>If the first argument is negative zero and the second argument is
	 * greater than zero but not a finite odd integer, or the first argument is
	 * negative infinity and the second argument is less than zero but not a
	 * finite odd integer, then the result is positive zero.</li>
	 * <li>If the first argument is negative zero and the second argument is a
	 * positive finite odd integer, or the first argument is negative infinity
	 * and the second argument is a negative finite odd integer, then the result
	 * is negative zero.</li>
	 * <li>If the first argument is negative zero and the second argument is
	 * less than zero but not a finite odd integer, or the first argument is
	 * negative infinity and the second argument is greater than zero but not a
	 * finite odd integer, then the result is positive infinity.</li>
	 * <li>If the first argument is negative zero and the second argument is a
	 * negative finite odd integer, or the first argument is negative infinity
	 * and the second argument is a positive finite odd integer, then the result
	 * is negative infinity.</li>
	 * <li>If the first argument is less than zero and the second argument is a
	 * finite even integer, then the result is equal to the result of raising
	 * the absolute value of the first argument to the power of the second
	 * argument.</li>
	 * <li>If the first argument is less than zero and the second argument is a
	 * finite odd integer, then the result is equal to the negative of the
	 * result of raising the absolute value of the first argument to the power
	 * of the second argument.</li>
	 * <li>If the first argument is finite and less than zero and the second
	 * argument is finite and not an integer, then the result is NaN.</li>
	 * <li>If both arguments are integers, then the result is exactly equal to
	 * the mathematical result of raising the first argument to the power of
	 * the second argument if that result can in fact be represented exactly as
	 * a double value.</li>
	 *
	 * </ul><p>(In the foregoing descriptions, a floating-point value is
	 * considered to be an integer if and only if it is a fixed point of the
	 * method {@link #ceil(double)} or, equivalently, a fixed point of the
	 * method {@link #floor(double)}. A value is a fixed point of a one-argument
	 * method if and only if the result of applying the method to the value is
	 * equal to the value.)
	 *
	 * @param x the number to raise
	 * @param y the power to raise it to
	 * @return x<sup>y</sup>
	 */
	public static double pow(double x, double y) {
		// Special cases first.
		if (y == 0)
			return 1;
		if (y == 1)
			return x;
		if (y == -1)
			return 1 / x;
		if (x != x || y != y)
			return Double.NaN;

		// When x < 0, yisint tells if y is not an integer (0), even(1),
		// or odd (2).
		int yisint = 0;
		if (x < 0 && floor(y) == y)
			yisint = (y % 2 == 0) ? 2 : 1;
		double ax = abs(x);
		double ay = abs(y);

		// More special cases, of y.
		if (ay == Double.POSITIVE_INFINITY) {
			if (ax == 1)
				return Double.NaN;
			if (ax > 1)
				return y > 0 ? y : 0;
			return y < 0 ? -y : 0;
		}
		if (y == 2)
			return x * x;
		if (y == 0.5)
			return sqrt(x);

		// More special cases, of x.
		if (x == 0 || ax == Double.POSITIVE_INFINITY || ax == 1) {
			if (y < 0)
				ax = 1 / ax;
			if (x < 0) {
				if (x == -1 && yisint == 0)
					ax = Double.NaN;
				else if (yisint == 1)
					ax = -ax;
			}
			return ax;
		}
		if (x < 0 && yisint == 0)
			return Double.NaN;

		// Now we can start!
		double t;
		double t1;
		double t2;
		double u;
		double v;
		double w;
		if (ay > TWO_31) {
			if (ay > TWO_64) // Automatic over/underflow.
				return ((ax < 1) ? y < 0 : y > 0) ? Double.POSITIVE_INFINITY : 0;
			// Over/underflow if x is not close to one.
			if (ax < 0.9999995231628418)
				return y < 0 ? Double.POSITIVE_INFINITY : 0;
			if (ax >= 1.0000009536743164)
				return y > 0 ? Double.POSITIVE_INFINITY : 0;
			// Now |1-x| is <= 2**-20, sufficient to compute
			// log(x) by x-x^2/2+x^3/3-x^4/4.
			t = x - 1;
			w = t * t * (0.5 - t * (1 / 3.0 - t * 0.25));
			u = INV_LN2_H * t;
			v = t * INV_LN2_L - w * INV_LN2;
			t1 = (float) (u + v);
			t2 = v - (t1 - u);
		} else {
			long bits = Double.doubleToLongBits(ax);
			int exp = (int) (bits >> 52);
			if (exp == 0) // Subnormal x.
				{
				ax *= TWO_54;
				bits = Double.doubleToLongBits(ax);
				exp = (int) (bits >> 52) - 54;
			}
			exp -= 1023; // Unbias exponent.
			ax = Double.longBitsToDouble((bits & 0x000fffffffffffffL) | 0x3ff0000000000000L);
			boolean k;
			if (ax < SQRT_1_5) // |x|<sqrt(3/2).
				k = false;
			else if (ax < SQRT_3) // |x|<sqrt(3).

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?