Beispiel #1
0
        private static void TestSin(Double a)
        {
            String di = System.Math.Sin(a).ToString();
            String ni = BigMath.Sin(BigNum.Create(a)).ToString();

            Console.WriteLine("Sin({0,6}) = {1,6} : {2,6} -> {3,6}", a, di, ni, di == ni ? "Pass" : "Fail");
        }
Beispiel #2
0
        private static BigNum EvaluateFunction(Function function, BigNum num)
        {
            switch (function)
            {
            case Function.Sin: return(BigMath.Sin(num));

            case Function.Cos: return(BigMath.Cos(num));

            case Function.Tan: return(BigMath.Tan(num));

            case Function.Csc: return(BigMath.Csc(num));

            case Function.Sec: return(BigMath.Sec(num));

            case Function.Cot: return(BigMath.Cot(num));

            case Function.Abs:   return(BigMath.Abs(num));

            case Function.Ceil:  return(BigMath.Ceiling(num));

            case Function.Floor: return(BigMath.Floor(num));

            case Function.Fact:  return(BigMath.Gamma(num));

            default:
                throw new ExpressionException("Unknown or invalid function");
            }
        }
Beispiel #3
0
        private static void TestPow(Double a, Double b)
        {
            Int32 power = (Int32)System.Math.Round(100 * b);

            String di = System.Math.Pow(a, power).ToString();
            String ni = BigMath.Pow(a, power).ToString();

            Console.WriteLine("{0,6} ^ {1,6} = {2,6} : {3,6} -> {4,6}", a, power, di, ni, di == ni ? "Pass" : "Fail");
        }
Beispiel #4
0
        public static BigNum Sin(BigNum theta)
        {
            BigNumFactory f = theta.Factory;

            // calculate sine using the taylor series, the infinite sum of x^r/r! but to n iterations
            BigNum retVal = f.Zero;

            // first, reduce this to between 0 and 2Pi
            if (theta > f.TwoPi || theta < f.Zero)
            {
                theta = theta % f.TwoPi;
            }

            Boolean subtract = false;

            // using bignums for sine computation is too heavy. It's faster (and just as accurate) to use Doubles
        #if DoubleTrig
            Double thetaDbl = Double.Parse(theta.ToString(), Cult.InvariantCulture);
            for (Int32 r = 0; r < 20; r++)        // 20 iterations is enough, any more just yields inaccurate less-significant digits

            {
                Double xPowerR = Math.Pow(thetaDbl, 2 * r + 1);
                Double factori = BigMath.Factorial((double)(2 * r + 1));

                Double element = xPowerR / factori;

                Double addThis = subtract ? -element : element;

                BigNum addThisBig = f.Create(addThis);

                retVal += addThisBig;

                subtract = !subtract;
            }
        #else
            for (Int32 r = 0; r < _iterations; r++)
            {
                BigNum xPowerR = theta.Power(2 * r + 1);
                BigNum factori = Factorial(2 * r + 1);

                BigNum element = xPowerR / factori;

                retVal += subtract ? -element : element;

                subtract = !subtract;
            }
        #endif

            // TODO: This calculation generates useless and inaccurate trailing digits that must be truncated
            // so truncate them, when I figure out how many digits can be removed

            retVal.Truncate(10);

            return(retVal);
        }
Beispiel #5
0
        private static void Normalise(BigInt oldNum, BigInt oldDen, out BigInt newNum, out BigInt newDen)
        {
            // TODO: Maybe also ensure that the denominator is positive, only the numerator can be negative

            // find the GCD of oldNum and oldDen, then apply it to find and return newNum and newDen

            BigInt gcd = (BigInt)BigMath.Gcd(oldNum, oldDen);

            newNum = (BigInt)(oldNum / gcd);
            newDen = (BigInt)(oldDen / gcd);
        }
Beispiel #6
0
        private static BigNum Modulo(BigNum x, BigNum y)
        {
            // a % b == a  - ( b * Floor[a / b] )

            if (y == 0)
            {
                throw new DivideByZeroException("Divisor y cannot be zero");
            }
            if (x.IsZero)
            {
                return(new BigFloat(0));
            }

            BigNum floored = BigMath.Floor(x / y);
            BigNum multbyb = y * floored;
            BigNum retval  = x - multbyb;

            return(retval);
        }
Beispiel #7
0
        private void Reduce()
        {
            BigNum one = _factory.Unity;
            BigNum zer = _factory.Zero;

            Operator op = _operatorStack.Peek();

            switch (op)
            {
            case Operator.Add:

                // Apply E := E + E
                EnsureVal(2);
                BigNum aa = _valueStack.Pop();
                BigNum ab = _valueStack.Pop();
                _valueStack.Push(aa + ab);

                break;

            case Operator.Sub:

                // Apply E := E - E
                EnsureVal(2);
                BigNum sa = _valueStack.Pop();
                BigNum sb = _valueStack.Pop();
                _valueStack.Push(sb - sa);

                break;

            case Operator.Mul:

                EnsureVal(2);
                BigNum ma = _valueStack.Pop();
                BigNum mb = _valueStack.Pop();
                _valueStack.Push(ma * mb);

                break;

            case Operator.Div:

                EnsureVal(2);
                BigNum da = _valueStack.Pop();
                BigNum db = _valueStack.Pop();
                _valueStack.Push(db / da);

                break;

            case Operator.Neg:

                EnsureVal(1);
                BigNum na = _valueStack.Pop();
                _valueStack.Push(-na);

                break;

            case Operator.Pow:

                EnsureVal(2);
                BigNum pa = _valueStack.Pop();
                BigNum pb = _valueStack.Pop();

                _valueStack.Push(BigMath.Pow(pb, pa));

                //Int32 exponent = Int32.Parse( pa.ToString(), N.Integer | N.AllowExponent, Cult.InvariantCulture );
                // _valueStack.Push( pb.Power( exponent ) );

                break;

            case Operator.PaR:

                _operatorStack.Pop();
                break;

            case Operator.CoE:
            case Operator.CoN:
            case Operator.CoL:
            case Operator.CLE:
            case Operator.CoG:
            case Operator.CGE:

                EnsureVal(2);
                BigNum ea = _valueStack.Pop();
                BigNum eb = _valueStack.Pop();

                Boolean eq = ea == eb;
                Boolean lt = eb < ea;
                Boolean gt = eb > ea;

                if (op == Operator.CoE)
                {
                    _valueStack.Push(eq       ? one : zer);
                }
                else if (op == Operator.CoN)
                {
                    _valueStack.Push(eq       ? zer : one);
                }
                else if (op == Operator.CoL)
                {
                    _valueStack.Push(lt       ? one : zer);
                }
                else if (op == Operator.CLE)
                {
                    _valueStack.Push(lt || eq ? one : zer);
                }
                else if (op == Operator.CoG)
                {
                    _valueStack.Push(gt       ? one : zer);
                }
                else if (op == Operator.CGE)
                {
                    _valueStack.Push(gt || eq ? one : zer);
                }

                break;

            case Operator.And:
            case Operator.Or:
            case Operator.Xor:

                EnsureVal(2);
                BigNum binA = _valueStack.Pop();
                BigNum binB = _valueStack.Pop();

                switch (op)
                {
                case Operator.And:

                    Boolean and = binA == one && binB == one;
                    _valueStack.Push(and ? one : zer);
                    break;

                case Operator.Or:

                    Boolean or = binA == one || binB == one;
                    _valueStack.Push(or  ? one : zer);
                    break;

                case Operator.Xor:

                    Boolean xor = (binA == one && binB != one) || (binA != one && binB == one);
                    _valueStack.Push(xor ? one : zer);
                    break;
                }

                break;

            case Operator.Not:

                EnsureVal(1);
                BigNum notA = _valueStack.Pop();
                if (notA == one)
                {
                    notA = zer;
                }
                else
                {
                    notA = one;
                }

                _valueStack.Push(notA);

                break;

//				Else, ignore it. Do not throw an exception
            }

            _operatorStack.Pop();
        }