strictmathtest.java

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

JAVA
1,689
字号
/*
 * $Id: StrictMathTest.java,v 1.2 2004/01/27 20:54:02 epr Exp $
 */
package org.jnode.test;

import java.util.Random;

/**
 * A copy of StrictMap from classpath.org. The copy is here to allow
 * testing the functions in a normal JVM, without class conflicts.
 * 
 * @author epr
 */
public class StrictMathTest {
	
	/**
	 * A random number generator, initialized on first use.
	 *
	 * @see #random()
	 */
	private static Random rand;

	/**
	 * The most accurate approximation to the mathematical constant <em>e</em>:
	 * <code>2.718281828459045</code>. Used in natural log and exp.
	 *
	 * @see #log(double)
	 * @see #exp(double)
	 */
	public static final double E = 2.718281828459045; // Long bits 0x4005bf0z8b145769L.

	/**
	 * The most accurate approximation to the mathematical constant <em>pi</em>:
	 * <code>3.141592653589793</code>. This is the ratio of a circle's diameter
	 * to its circumference.
	 */
	public static final double PI = 3.141592653589793; // Long bits 0x400921fb54442d18L.

	/**
	 * Take the absolute value of the argument. (Absolute value means make
	 * it positive.)
	 *
	 * <p>Note that the the largest negative value (Integer.MIN_VALUE) cannot
	 * be made positive.  In this case, because of the rules of negation in
	 * a computer, MIN_VALUE is what will be returned.
	 * This is a <em>negative</em> value.  You have been warned.
	 *
	 * @param i the number to take the absolute value of
	 * @return the absolute value
	 * @see Integer#MIN_VALUE
	 */
	public static int abs(int i) {
		return (i < 0) ? -i : i;
	}

	/**
	 * Take the absolute value of the argument. (Absolute value means make
	 * it positive.)
	 *
	 * <p>Note that the the largest negative value (Long.MIN_VALUE) cannot
	 * be made positive.  In this case, because of the rules of negation in
	 * a computer, MIN_VALUE is what will be returned.
	 * This is a <em>negative</em> value.  You have been warned.
	 *
	 * @param l the number to take the absolute value of
	 * @return the absolute value
	 * @see Long#MIN_VALUE
	 */
	public static long abs(long l) {
		return (l < 0) ? -l : l;
	}

	/**
	 * Take the absolute value of the argument. (Absolute value means make
	 * it positive.)
	 *
	 * @param f the number to take the absolute value of
	 * @return the absolute value
	 */
	public static float abs(float f) {
		return (f <= 0) ? 0 - f : f;
	}

	/**
	 * Take the absolute value of the argument. (Absolute value means make
	 * it positive.)
	 *
	 * @param d the number to take the absolute value of
	 * @return the absolute value
	 */
	public static double abs(double d) {
		return (d <= 0) ? 0 - d : d;
	}

	/**
	 * Return whichever argument is smaller.
	 *
	 * @param a the first number
	 * @param b a second number
	 * @return the smaller of the two numbers
	 */
	public static int min(int a, int b) {
		return (a < b) ? a : b;
	}

	/**
	 * Return whichever argument is smaller.
	 *
	 * @param a the first number
	 * @param b a second number
	 * @return the smaller of the two numbers
	 */
	public static long min(long a, long b) {
		return (a < b) ? a : b;
	}

	/**
	 * Return whichever argument is smaller. If either argument is NaN, the
	 * result is NaN, and when comparing 0 and -0, -0 is always smaller.
	 *
	 * @param a the first number
	 * @param b a second number
	 * @return the smaller of the two numbers
	 */
	public static float min(float a, float b) {
		// this check for NaN, from JLS 15.21.1, saves a method call
		if (a != a)
			return a;
		// no need to check if b is NaN; < will work correctly
		// recall that -0.0 == 0.0, but [+-]0.0 - [+-]0.0 behaves special
		if (a == 0 && b == 0)
			return - (-a - b);
		return (a < b) ? a : b;
	}

	/**
	 * Return whichever argument is smaller. If either argument is NaN, the
	 * result is NaN, and when comparing 0 and -0, -0 is always smaller.
	 *
	 * @param a the first number
	 * @param b a second number
	 * @return the smaller of the two numbers
	 */
	public static double min(double a, double b) {
		// this check for NaN, from JLS 15.21.1, saves a method call
		if (a != a)
			return a;
		// no need to check if b is NaN; < will work correctly
		// recall that -0.0 == 0.0, but [+-]0.0 - [+-]0.0 behaves special
		if (a == 0 && b == 0)
			return - (-a - b);
		return (a < b) ? a : b;
	}

	/**
	 * Return whichever argument is larger.
	 *
	 * @param a the first number
	 * @param b a second number
	 * @return the larger of the two numbers
	 */
	public static int max(int a, int b) {
		return (a > b) ? a : b;
	}

	/**
	 * Return whichever argument is larger.
	 *
	 * @param a the first number
	 * @param b a second number
	 * @return the larger of the two numbers
	 */
	public static long max(long a, long b) {
		return (a > b) ? a : b;
	}

	/**
	 * Return whichever argument is larger. If either argument is NaN, the
	 * result is NaN, and when comparing 0 and -0, 0 is always larger.
	 *
	 * @param a the first number
	 * @param b a second number
	 * @return the larger of the two numbers
	 */
	public static float max(float a, float b) {
		// this check for NaN, from JLS 15.21.1, saves a method call
		if (a != a)
			return a;
		// no need to check if b is NaN; > will work correctly
		// recall that -0.0 == 0.0, but [+-]0.0 - [+-]0.0 behaves special
		if (a == 0 && b == 0)
			return a - -b;
		return (a > b) ? a : b;
	}

	/**
	 * Return whichever argument is larger. If either argument is NaN, the
	 * result is NaN, and when comparing 0 and -0, 0 is always larger.
	 *
	 * @param a the first number
	 * @param b a second number
	 * @return the larger of the two numbers
	 */
	public static double max(double a, double b) {
		// this check for NaN, from JLS 15.21.1, saves a method call
		if (a != a)
			return a;
		// no need to check if b is NaN; > will work correctly
		// recall that -0.0 == 0.0, but [+-]0.0 - [+-]0.0 behaves special
		if (a == 0 && b == 0)
			return a - -b;
		return (a > b) ? a : b;
	}

	/**
	 * The trigonometric function <em>sin</em>. The sine of NaN or infinity is
	 * NaN, and the sine of 0 retains its sign.
	 *
	 * @param a the angle (in radians)
	 * @return sin(a)
	 */
	public static double sin(double a) {
		if (a == Double.NEGATIVE_INFINITY || !(a < Double.POSITIVE_INFINITY))
			return Double.NaN;

		if (abs(a) <= PI / 4)
			return sin(a, 0);

		// Argument reduction needed.
		double[] y = new double[2];
		int n = remPiOver2(a, y);
		switch (n & 3) {
			case 0 :
				return sin(y[0], y[1]);
			case 1 :
				return cos(y[0], y[1]);
			case 2 :
				return -sin(y[0], y[1]);
			default :
				return -cos(y[0], y[1]);
		}
	}

	/**
	 * The trigonometric function <em>cos</em>. The cosine of NaN or infinity is
	 * NaN.
	 *
	 * @param a the angle (in radians).
	 * @return cos(a).
	 */
	public static double cos(double a) {
		if (a == Double.NEGATIVE_INFINITY || !(a < Double.POSITIVE_INFINITY))
			return Double.NaN;

		if (abs(a) <= PI / 4)
			return cos(a, 0);

		// Argument reduction needed.
		double[] y = new double[2];
		int n = remPiOver2(a, y);
		switch (n & 3) {
			case 0 :
				return cos(y[0], y[1]);
			case 1 :
				return -sin(y[0], y[1]);
			case 2 :
				return -cos(y[0], y[1]);
			default :
				return sin(y[0], y[1]);
		}
	}

	/**
	 * The trigonometric function <em>tan</em>. The tangent of NaN or infinity
	 * is NaN, and the tangent of 0 retains its sign.
	 *
	 * @param a the angle (in radians)
	 * @return tan(a)
	 */
	public static double tan(double a) {
		if (a == Double.NEGATIVE_INFINITY || !(a < Double.POSITIVE_INFINITY))
			return Double.NaN;

		if (abs(a) <= PI / 4)
			return tan(a, 0, false);

		// Argument reduction needed.
		double[] y = new double[2];
		int n = remPiOver2(a, y);
		return tan(y[0], y[1], (n & 1) == 1);
	}

	/**
	 * The trigonometric function <em>arcsin</em>. The range of angles returned
	 * is -pi/2 to pi/2 radians (-90 to 90 degrees). If the argument is NaN or
	 * its absolute value is beyond 1, the result is NaN; and the arcsine of
	 * 0 retains its sign.
	 *
	 * @param x the sin to turn back into an angle
	 * @return arcsin(x)
	 */
	public static double asin(double x) {
		boolean negative = x < 0;
		if (negative)
			x = -x;
		if (!(x <= 1))
			return Double.NaN;
		if (x == 1)
			return negative ? -PI / 2 : PI / 2;
		if (x < 0.5) {
			if (x < 1 / TWO_27)
				return negative ? -x : x;
			double t = x * x;
			double p = t * (PS0 + t * (PS1 + t * (PS2 + t * (PS3 + t * (PS4 + t * PS5)))));
			double q = 1 + t * (QS1 + t * (QS2 + t * (QS3 + t * QS4)));
			return negative ? -x - x * (p / q) : x + x * (p / q);
		}
		double w = 1 - x; // 1>|x|>=0.5.
		double t = w * 0.5;
		double p = t * (PS0 + t * (PS1 + t * (PS2 + t * (PS3 + t * (PS4 + t * PS5)))));
		double q = 1 + t * (QS1 + t * (QS2 + t * (QS3 + t * QS4)));
		double s = sqrt(t);
		if (x >= 0.975) {
			w = p / q;
			t = PI / 2 - (2 * (s + s * w) - PI_L / 2);
		} else {
			w = (float) s;
			double c = (t - w * w) / (s + w);
			p = 2 * s * (p / q) - (PI_L / 2 - 2 * c);
			q = PI / 4 - 2 * w;
			t = PI / 4 - (p - q);
		}
		return negative ? -t : t;
	}

	/**
	 * The trigonometric function <em>arccos</em>. The range of angles returned
	 * is 0 to pi radians (0 to 180 degrees). If the argument is NaN or
	 * its absolute value is beyond 1, the result is NaN.
	 *
	 * @param x the cos to turn back into an angle
	 * @return arccos(x)
	 */
	public static double acos(double x) {
		boolean negative = x < 0;
		if (negative)
			x = -x;
		if (!(x <= 1))
			return Double.NaN;
		if (x == 1)
			return negative ? PI : 0;
		if (x < 0.5) {
			if (x < 1 / TWO_57)
				return PI / 2;
			double z = x * x;
			double p = z * (PS0 + z * (PS1 + z * (PS2 + z * (PS3 + z * (PS4 + z * PS5)))));
			double q = 1 + z * (QS1 + z * (QS2 + z * (QS3 + z * QS4)));
			double r = x - (PI_L / 2 - x * (p / q));
			return negative ? PI / 2 + r : PI / 2 - r;
		}
		if (negative) // x<=-0.5.
			{
			double z = (1 + x) * 0.5;
			double p = z * (PS0 + z * (PS1 + z * (PS2 + z * (PS3 + z * (PS4 + z * PS5)))));
			double q = 1 + z * (QS1 + z * (QS2 + z * (QS3 + z * QS4)));
			double s = sqrt(z);
			double w = p / q * s - PI_L / 2;
			return PI - 2 * (s + w);
		}
		double z = (1 - x) * 0.5; // x>0.5.
		double s = sqrt(z);
		double df = (float) s;
		double c = (z - df * df) / (s + df);
		double p = z * (PS0 + z * (PS1 + z * (PS2 + z * (PS3 + z * (PS4 + z * PS5)))));
		double q = 1 + z * (QS1 + z * (QS2 + z * (QS3 + z * QS4)));
		double w = p / q * s + c;
		return 2 * (df + w);
	}

	/**
	 * The trigonometric function <em>arcsin</em>. The range of angles returned
	 * is -pi/2 to pi/2 radians (-90 to 90 degrees). If the argument is NaN, the
	 * result is NaN; and the arctangent of 0 retains its sign.
	 *
	 * @param x the tan to turn back into an angle
	 * @return arcsin(x)
	 * @see #atan2(double, double)
	 */
	public static double atan(double x) {
		double lo;
		double hi;
		boolean negative = x < 0;
		if (negative)
			x = -x;
		if (x >= TWO_66)
			return negative ? -PI / 2 : PI / 2;
		if (!(x >= 0.4375)) // |x|<7/16, or NaN.
			{
			if (!(x >= 1 / TWO_29)) // Small, or NaN.
				return negative ? -x : x;
			lo = hi = 0;
		} else if (x < 1.1875) {
			if (x < 0.6875) // 7/16<=|x|<11/16.
				{
				x = (2 * x - 1) / (2 + x);
				hi = ATAN_0_5H;
				lo = ATAN_0_5L;
			} else // 11/16<=|x|<19/16.
				{
				x = (x - 1) / (x + 1);
				hi = PI / 4;
				lo = PI_L / 4;
			}
		} else if (x < 2.4375) // 19/16<=|x|<39/16.
			{
			x = (x - 1.5) / (1 + 1.5 * x);
			hi = ATAN_1_5H;
			lo = ATAN_1_5L;
		} else // 39/16<=|x|<2**66.
			{
			x = -1 / x;
			hi = PI / 2;
			lo = PI_L / 2;

⌨️ 快捷键说明

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