Пример #1
0
        /// <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;
        }