4 * Mathematical functions.
6 * @author <a href="mailto:bbagnall@escape.ca">Brian Bagnall</a>
8 public final class Math {
11 public static final double E = 2.718281828459045;
12 public static final double PI = 3.141592653589793;
13 public static final double NaN = 0.0f / 0.0f;
15 static final float PI2 = 1.570796326794897f;
16 static final double ln10 = 2.30258509299405;
17 static final double ln2 = 0.69314718055995;
19 // Used by log() and exp() methods
20 private static final float LOWER_BOUND = 0.9999999f;
21 private static final float UPPER_BOUND = 1.0f;
23 // Used to generate random numbers.
24 private static java.util.Random RAND = new java.util.Random(System.currentTimeMillis());
26 //public static boolean isNaN (double d) {
30 private Math() {} // To make sure this class is not instantiated
32 // Private because it only works when -1 < x < 1 but it is used by atan2
33 private static double ArcTan(double x) // Using a Chebyshev-Pade approximation
36 return (0.7162721433f+0.2996857769f*x2)*x/(0.7163164576f+(0.5377299313f+0.3951620469e-1f*x2)*x2);
41 * Returns the smallest (closest to negative infinity) double value that is not
42 * less than the argument and is equal to a mathematical integer.
44 public static double ceil(double a) {
45 return ((a<0)?(int)a:(int)(a+1));
49 * Returns the largest (closest to positive infinity) double value that is not
50 * greater than the argument and is equal to a mathematical integer.
52 public static double floor(double a) {
53 return ((a<0)?(int)(a-1):(int)a);
57 * Returns the closest int to the argument.
59 public static int round(float a) {
60 return (int)floor(a + 0.5f);
64 * Returns the lesser of two integer values.
66 public static int min(int a, int b) {
71 *Returns the lesser of two double values.
73 public static double min(double a, double b) {
78 *Returns the greater of two integer values.
80 public static int max(int a, int b) {
85 *Returns the greater of two double values.
87 public static double max(double a, double b) {
92 * Random number generator.
93 * Returns a double greater than 0.0 and less than 1.0
95 public static double random()
97 final int MAX_INT = 2147483647;
100 // Just to ensure it does not return 1.0
102 n = abs (RAND.nextInt());
104 return n * (1.0 / MAX_INT);
108 * Exponential function. Returns E^x (where E is the base of natural logarithms).
109 * Thanks to David Edwards of England for conceiving the code and Martin E. Nielsen
110 * for modifying it to handle large arguments.
111 * = sum a^n/n!, i.e. 1 + x + x^2/2! + x^3/3!
113 * Seems to work better for +ve numbers so force argument to be +ve.
115 public static double exp(double a)
117 boolean neg = a < 0 ? true : false;
134 } while (end < LOWER_BOUND || end > UPPER_BOUND);
138 return neg ? 1.0f/sum : sum;
142 * Natural log function. Returns log(a) to base E
143 * Replaced with an algorithm that does not use exponents and so
144 * works with large arguments.
145 * @see <a href="http://www.geocities.com/zabrodskyvlada/aat/a_contents.html">here</a>
147 public static double log(double x)
162 double zeta = (1.0 - z)/(1.0 + z);
165 double zetasup = zeta * zeta;
167 for (int j=1; true; j++)
170 double newln = ln + n / (2 * j + 1);
171 double term = ln/newln;
172 if (term >= LOWER_BOUND && term <= UPPER_BOUND)
173 return m * ln2 - 2 * ln;
179 * Power function. This is a slow but accurate method.
180 * Thanks to David Edwards of England for conceiving the code.
182 public static double pow(double a, double b) {
183 return exp(b * log(a));
187 * Returns the absolute value of a double value. If the argument is not negative, the argument is
188 * returned. If the argument is negative, the negation of the argument is returned.
190 public static double abs(double a) {
195 * Returns the absolute value of an integer value. If the argument is not negative, the argument is
196 * returned. If the argument is negative, the negation of the argument is returned.
198 public static int abs(int a) {
203 * Sine function using a Chebyshev-Pade approximation. Thanks to Paulo Costa for donating the code.
205 public static double sin(double x) // Using a Chebyshev-Pade approximation
207 int n=(int)(x/PI2)+1; // reduce to the 4th and 1st quadrants
209 if ((n&2)==0) x=x-(n&0xFFFFFFFE)*PI2; // if it from the 2nd or the 3rd quadrants
210 else x=-(x-(n&0xFFFFFFFE)*PI2);
213 return (0.9238318854f-0.9595498071e-1f*x2)*x/(0.9238400690f+(0.5797298195e-1f+0.2031791179e-2f*x2)*x2);
217 * Cosine function using a Chebyshev-Pade approximation. Thanks to Paulo Costa for donating the code.
219 public static double cos(double x)
221 int n=(int)(x/PI2)+1;
223 x=x-(n&0xFFFFFFFE)*PI2; // reduce to the 4th and 1st quadrants
228 if ((n&2)!=0) si=-1f; // if it from the 2nd or the 3rd quadrants
229 return si*(0.9457092528f+(-0.4305320537f+0.1914993010e-1f*x2)*x2)/(0.9457093212f+(0.4232119630e-1f+0.9106317690e-3f*x2)*x2);
233 * Square root - thanks to Paulo Costa for donating the code.
235 public static double sqrt(double x)
237 double root = x, guess=0;
241 // the accuarcy test is percentual
242 for(int i=0; (i<16) && ((guess > x*(1+5e-7f)) || (guess < x*(1-5e-7f))); i++)
244 root = (root+x/root)*0.5f; // a multiplication is faster than a division
245 guess=root*root; // cache the square to the test
253 public static double tan(double a) {
254 return sin(a)/cos(a);
258 * Arc tangent function. Thanks to Paulo Costa for donating the code.
260 public static double atan(double x)
266 * Arc tangent function valid to the four quadrants
267 * y and x can have any value without sigificant precision loss
268 * atan2(0,0) returns 0. Thanks to Paulo Costa for donating the code.
270 public static double atan2(double y, double x)
272 float ax=(float)abs(x);
273 float ay=(float)abs(y);
275 if ((ax<1e-7) && (ay<1e-7)) return 0f;
281 if (y>=0) return ArcTan(y/x)+PI;
282 else return ArcTan(y/x)-PI;
284 else return ArcTan(y/x);
288 if (y<0) return ArcTan(-x/y)-PI/2;
289 else return ArcTan(-x/y)+PI/2;
294 * Arc cosine function.
296 public static double acos(double a) {
300 return PI/2 - atan(a/sqrt(1 - a * a));
306 public static double asin(double a) {
307 return atan(a/sqrt(1-a*a));
311 * Converts radians to degrees.
313 public static double toDegrees(double angrad) {
314 return angrad * (360.0 / (2 * PI));
318 * Converts degrees to radians.
320 public static double toRadians(double angdeg) {
321 return angdeg * ((2 * PI) / 360.0);