Exemplo n.º 1
0
            static bool IsSignOfSinePositive(EDecimal x, ConstantCache consts, EContext context)
            {
                //truncating to  [-2*PI;2*PI]
                TruncateToPeriodicInterval(ref x, consts, context);

                //now x in [-2*PI;2*PI]
                if (x.GreaterThanOrEquals(-consts.TwoPi) && x.LessThanOrEquals(-consts.Pi))
                {
                    return(true);
                }
                if (x.GreaterThanOrEquals(-consts.Pi) && (x.IsNegative || x.IsZero))
                {
                    return(false);
                }
                if (!x.IsNegative && x.LessThanOrEquals(consts.Pi))
                {
                    return(true);
                }
                if (x.GreaterThanOrEquals(consts.Pi) && x.LessThanOrEquals(consts.TwoPi))
                {
                    return(false);
                }

                throw new Core.Exceptions.AngouriBugException("Should not be reached");
            }
Exemplo n.º 2
0
 public static ConstantCache Lookup(EContext context)
 {
     if (!constants.TryGetValue(context, out var cache))
     {
         lock (constants)
             if (!constants.TryGetValue(context, out cache))
             {
                 cache = new ConstantCache(context);
                 constants.Add(context, cache);
             }
     }
     return(cache);
 }
Exemplo n.º 3
0
        /// <summary>Analogy of <see cref="Math.Cos(double)"/></summary>
        public static EDecimal Cos(this EDecimal x, EContext context)
        {
            if (!x.IsFinite)
            {
                return(EDecimal.NaN);
            }

            // TODO: this check should be here to improve the performance a little bit, but tests won't work with that
            // if (Utils.IsGoodAsDouble(x)) return EDecimal.FromDouble(Math.Cos(x.ToDouble()));

            // Of course this will fail! Math.Cos works with double - only ~15 digits of accuracy.
            // We have precision of 100 by default - which is over 95 digits of accuracy,
            // albeit the last few digits are off. You have rejected the use of double early on
            // - as well as the entirety of System.Math.                        -- Happypig375

            var consts = ConstantCache.Lookup(context);

            //truncating to  [-2*PI;2*PI]
            TruncateToPeriodicInterval(ref x, consts, context);

            // now x in (-2pi,2pi)
            if (x.GreaterThanOrEquals(consts.Pi) && x.LessThanOrEquals(consts.TwoPi))
            {
                return(-Cos(x.Subtract(consts.Pi, context), context));
            }
            if (x.GreaterThanOrEquals(-consts.TwoPi) && x.LessThanOrEquals(-consts.Pi))
            {
                return(-Cos(x.Add(consts.Pi, context), context));
            }

            x = x.Multiply(x, context);
            //y=1-x/2!+x^2/4!-x^3/6!...
            var xx      = -x.Multiply(consts.Half, context);
            var y       = xx.Increment();
            var cachedY = y.Decrement();//init cache  with different value

            for (var i = 1; !cachedY.Equals(y); i++)
            {
                cachedY = y;
                EDecimal factor = i * ((i << 1) + 3) + 1; //2i^2+2i+i+1=2i^2+3i+1
                factor = -consts.Half.Divide(factor, context);
                xx     = xx.Multiply(x.Multiply(factor, context), context);
                y      = y.Add(xx, context);
            }

            return(y);
        }
Exemplo n.º 4
0
        /// <summary>Analogy of <see cref="Math.Tan(double)"/></summary>
        public static EDecimal Tan(this EDecimal x, EContext context)
        {
            if (!x.IsFinite)
            {
                return(EDecimal.NaN);
            }
            var consts = ConstantCache.Lookup(context);
            var cos    = Cos(x, context);

            if (cos.IsZero)
            {
                return(EDecimal.NaN);
            }
            //calculate sin using cos
            var sin = CalculateSinFromCos(x, cos, consts, context);

            return(sin.Divide(cos, context));
        }
Exemplo n.º 5
0
 /// <summary>Helper function for calculating sin(x) from cos(x)</summary>
 static EDecimal CalculateSinFromCos(EDecimal x, EDecimal cos, ConstantCache consts, EContext context)
 {