Created an inner class to collect statements that were duplicated.


git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1366400 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Gilles Sadowski 2012-07-27 14:56:10 +00:00
parent b451fdc8e4
commit e64d8653d1
1 changed files with 97 additions and 118 deletions

View File

@ -2127,9 +2127,10 @@ public class FastMath {
} }
/** /**
* Sine function. * Sine function.
* @param x a number *
* @return sin(x) * @param x Argument.
* @return sin(x)
*/ */
public static double sin(double x) { public static double sin(double x) {
boolean negative = false; boolean negative = false;
@ -2168,42 +2169,10 @@ public class FastMath {
xa = reduceResults[1]; xa = reduceResults[1];
xb = reduceResults[2]; xb = reduceResults[2];
} else if (xa > 1.5707963267948966) { } else if (xa > 1.5707963267948966) {
/* Inline the Cody/Waite reduction for performance */ final CodyWaite cw = new CodyWaite(xa, xb);
quadrant = cw.getK() & 3;
// Estimate k xa = cw.getRemA();
//k = (int)(xa / 1.5707963267948966); xb = cw.getRemB();
int k = (int)(xa * 0.6366197723675814);
// Compute remainder
double remA;
double remB;
while (true) {
double a = -k * 1.570796251296997;
remA = xa + a;
remB = -(remA - xa - a);
a = -k * 7.549789948768648E-8;
double b = remA;
remA = a + b;
remB += -(remA - b - a);
a = -k * 6.123233995736766E-17;
b = remA;
remA = a + b;
remB += -(remA - b - a);
if (remA > 0.0) {
break;
}
// Remainder is negative, so decrement k and try again.
// This should only happen if the input is very close
// to an even multiple of pi/2
k--;
}
quadrant = k & 3;
xa = remA;
xb = remB;
} }
if (negative) { if (negative) {
@ -2225,9 +2194,10 @@ public class FastMath {
} }
/** /**
* Cosine function * Cosine function.
* @param x a number *
* @return cos(x) * @param x Argument.
* @return cos(x)
*/ */
public static double cos(double x) { public static double cos(double x) {
int quadrant = 0; int quadrant = 0;
@ -2254,42 +2224,10 @@ public class FastMath {
xa = reduceResults[1]; xa = reduceResults[1];
xb = reduceResults[2]; xb = reduceResults[2];
} else if (xa > 1.5707963267948966) { } else if (xa > 1.5707963267948966) {
/* Inline the Cody/Waite reduction for performance */ final CodyWaite cw = new CodyWaite(xa, xb);
quadrant = cw.getK() & 3;
// Estimate k xa = cw.getRemA();
//k = (int)(xa / 1.5707963267948966); xb = cw.getRemB();
int k = (int)(xa * 0.6366197723675814);
// Compute remainder
double remA;
double remB;
while (true) {
double a = -k * 1.570796251296997;
remA = xa + a;
remB = -(remA - xa - a);
a = -k * 7.549789948768648E-8;
double b = remA;
remA = a + b;
remB += -(remA - b - a);
a = -k * 6.123233995736766E-17;
b = remA;
remA = a + b;
remB += -(remA - b - a);
if (remA > 0.0) {
break;
}
// Remainder is negative, so decrement k and try again.
// This should only happen if the input is very close
// to an even multiple of pi/2
k--;
}
quadrant = k & 3;
xa = remA;
xb = remB;
} }
//if (negative) //if (negative)
@ -2310,9 +2248,10 @@ public class FastMath {
} }
/** /**
* Tangent function * Tangent function.
* @param x a number *
* @return tan(x) * @param x Argument.
* @return tan(x)
*/ */
public static double tan(double x) { public static double tan(double x) {
boolean negative = false; boolean negative = false;
@ -2350,46 +2289,14 @@ public class FastMath {
xa = reduceResults[1]; xa = reduceResults[1];
xb = reduceResults[2]; xb = reduceResults[2];
} else if (xa > 1.5707963267948966) { } else if (xa > 1.5707963267948966) {
/* Inline the Cody/Waite reduction for performance */ final CodyWaite cw = new CodyWaite(xa, xb);
quadrant = cw.getK() & 3;
// Estimate k xa = cw.getRemA();
//k = (int)(xa / 1.5707963267948966); xb = cw.getRemB();
int k = (int)(xa * 0.6366197723675814);
// Compute remainder
double remA;
double remB;
while (true) {
double a = -k * 1.570796251296997;
remA = xa + a;
remB = -(remA - xa - a);
a = -k * 7.549789948768648E-8;
double b = remA;
remA = a + b;
remB += -(remA - b - a);
a = -k * 6.123233995736766E-17;
b = remA;
remA = a + b;
remB += -(remA - b - a);
if (remA > 0.0) {
break;
}
// Remainder is negative, so decrement k and try again.
// This should only happen if the input is very close
// to an even multiple of pi/2
k--;
}
quadrant = k & 3;
xa = remA;
xb = remB;
} }
if (xa > 1.5) { if (xa > 1.5) {
// Accurracy suffers between 1.5 and PI/2 // Accuracy suffers between 1.5 and PI/2
final double pi2a = 1.5707963267948966; final double pi2a = 1.5707963267948966;
final double pi2b = 6.123233995736766E-17; final double pi2b = 6.123233995736766E-17;
@ -3795,4 +3702,76 @@ public class FastMath {
} }
} }
} }
/** Enclose the Cody/Waite reduction (used in "sin", "cos" and "tan"). */
private static class CodyWaite {
/** k */
private final int finalK;
/** remA */
private final double finalRemA;
/** remB */
private final double finalRemB;
/**
* @param xa Argument.
* @param xb Argument.
*/
CodyWaite(double xa,
double xb) {
// Estimate k.
//k = (int)(xa / 1.5707963267948966);
int k = (int)(xa * 0.6366197723675814);
// Compute remainder.
double remA;
double remB;
while (true) {
double a = -k * 1.570796251296997;
remA = xa + a;
remB = -(remA - xa - a);
a = -k * 7.549789948768648E-8;
double b = remA;
remA = a + b;
remB += -(remA - b - a);
a = -k * 6.123233995736766E-17;
b = remA;
remA = a + b;
remB += -(remA - b - a);
if (remA > 0) {
break;
}
// Remainder is negative, so decrement k and try again.
// This should only happen if the input is very close
// to an even multiple of pi/2.
--k;
}
this.finalK = k;
this.finalRemA = remA;
this.finalRemB = remB;
}
/**
* @return k
*/
int getK() {
return finalK;
}
/**
* @return remA
*/
double getRemA() {
return finalRemA;
}
/**
* @return remB
*/
double getRemB() {
return finalRemB;
}
}
} }