/// <summary> /// Calculates tan(x) /// </summary> public void Tan() { if (IsSpecialValue) { //Tan(x) has no limit as x->inf if (SpecialValue == SpecialValueType.INF_MINUS || SpecialValue == SpecialValueType.INF_PLUS) { SetNaN(); } else if (SpecialValue == SpecialValueType.ZERO) { SetZero(); } return; } if (pi == null || pi.mantissa.Precision.NumBits != mantissa.Precision.NumBits) { CalculatePi(mantissa.Precision.NumBits); } //Work out the sign change (involves replicating some rescaling). bool sign = mantissa.Sign; mantissa.Sign = false; if (mantissa.IsZero()) { return; } //Rescale into 0 <= x < pi if (GreaterThan(pi)) { //There will be an inherent loss of precision doing this. BigFloat newAngle = new BigFloat(this); newAngle.Mul(piRecip); newAngle.FPart(); newAngle.Mul(pi); Assign(newAngle); } //Rescale to -pi/2 <= x < pi/2 if (!LessThan(piBy2)) { Sub(pi); } //Now the sign of the sin determines the sign of the tan. //tan(x) = sin(x) / sqrt(1 - sin^2(x)) Sin(); BigFloat denom = new BigFloat(this); denom.Mul(this); denom.Sub(new BigFloat(1, mantissa.Precision)); denom.mantissa.Sign = !denom.mantissa.Sign; if (denom.mantissa.Sign) { denom.SetZero(); } denom.Sqrt(); Div(denom); if (sign) mantissa.Sign = !mantissa.Sign; }