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 + -
显示快捷键?