/** * Cosine function. * * @param x Argument. * @return cos(x) */ public static double Calc(double x) { int quadrant = 0; /* Take absolute value of the input */ double xa = x; if (x < 0) { xa = -xa; } if (xa == double.PositiveInfinity) { return(Double.NaN); } /* Perform any argument reduction */ double xb = 0; if (xa > 3294198.0) { // PI * (2**20) // Argument too big for CodyWaite reduction. Must use // PayneHanek. double[] reduceResults = new double[3]; PayneHanek.Reduce(xa, reduceResults); quadrant = ((int)reduceResults[0]) & 3; xa = reduceResults[1]; xb = reduceResults[2]; } else if (xa > 1.5707963267948966) { CodyWaite cw = new CodyWaite(xa); quadrant = cw.getK() & 3; xa = cw.getRemA(); xb = cw.getRemB(); } //if (negative) // quadrant = (quadrant + 2) % 4; switch (quadrant) { case 0: return(cosQ(xa, xb)); case 1: return(-sinQ(xa, xb)); case 2: return(-cosQ(xa, xb)); case 3: return(sinQ(xa, xb)); default: return(Double.NaN); } }
/** * Tangent function. * * @param x Argument. * @return tan(x) */ public static double Calc(double x) { bool negative = false; int quadrant = 0; /* Take absolute value of the input */ double xa = x; if (x < 0) { negative = true; xa = -xa; } /* Check for zero and negative zero */ if (xa == 0.0) { long bits = BitConverter.DoubleToInt64Bits(x); if (bits < 0) { return(-0.0); } return(0.0); } if (xa == Double.PositiveInfinity) { return(Double.NaN); } /* Perform any argument reduction */ double xb = 0; if (xa > 3294198.0) { // PI * (2**20) // Argument too big for CodyWaite reduction. Must use // PayneHanek. double[] reduceResults = new double[3]; PayneHanek.Reduce(xa, reduceResults); quadrant = ((int)reduceResults[0]) & 3; xa = reduceResults[1]; xb = reduceResults[2]; } else if (xa > 1.5707963267948966) { CodyWaite cw = new CodyWaite(xa); quadrant = cw.getK() & 3; xa = cw.getRemA(); xb = cw.getRemB(); } if (xa > 1.5) { // Accuracy suffers between 1.5 and PI/2 double pi2a = 1.5707963267948966; double pi2b = 6.123233995736766E-17; double a = pi2a - xa; double b = -(a - pi2a + xa); b += pi2b - xb; xa = a + b; xb = -(xa - a - b); quadrant ^= 1; negative ^= true; } double result; if ((quadrant & 1) == 0) { result = Quadrant(xa, xb, false); } else { result = -Quadrant(xa, xb, true); } if (negative) { result = -result; } return(result); }
/** * Sine function. * * @param x Argument. * @return sin(x) */ public static double Calc(double x) { bool negative = false; int quadrant = 0; double xa; double xb = 0.0; /* Take absolute value of the input */ xa = x; if (x < 0) { negative = true; xa = -xa; } /* Check for zero and negative zero */ if (xa == 0.0) { long bits = BitConverter.DoubleToInt64Bits(x); if (bits < 0) { return(-0.0); } return(0.0); } if (xa == Double.PositiveInfinity) { return(Double.NaN); } /* Perform any argument reduction */ if (xa > 3294198.0) { // PI * (2**20) // Argument too big for CodyWaite reduction. Must use // PayneHanek. double[] reduceResults = new double[3]; PayneHanek.Reduce(xa, reduceResults); quadrant = ((int)reduceResults[0]) & 3; xa = reduceResults[1]; xb = reduceResults[2]; } else if (xa > 1.5707963267948966) { CodyWaite cw = new CodyWaite(xa); quadrant = cw.getK() & 3; xa = cw.getRemA(); xb = cw.getRemB(); } if (negative) { quadrant ^= 2; // Flip bit 1 } switch (quadrant) { case 0: return(Quadrant(xa, xb)); case 1: return(Cosine.Quadrant(xa, xb)); case 2: return(-Quadrant(xa, xb)); case 3: return(-Cosine.Quadrant(xa, xb)); default: return(Double.NaN); } }