Пример #1
0
        private eeNumber IntegerDivision(eeNumber divisor, out eeNumber mod)
        {
            // base case
            if (this.AbsoluteValue() < divisor.AbsoluteValue())
            {
                mod = this;
                return(new eeNumber(0));
            }

            Queue <byte>    bytesQue = new Queue <byte>(this.bytes); // a queue of the dividend as bytes
            List <eeNumber> quotient = new List <eeNumber>();        // quotient

            eeNumber divPart = null;

            while (bytesQue.Count() > 0)
            {
                /* Grab the next digit from dividend */
                var asList   = divPart == null ? new List <byte>() : divPart.bytes.ToList();
                var nextByte = bytesQue.Dequeue();
                asList.Add(nextByte);

                /* Keep grabbing until we run out or need more */
                divPart = new eeNumber(asList);
                while (bytesQue.Count() != 0 && divPart < divisor)
                {
                    quotient.Add(new eeNumber(0));

                    asList.Add(bytesQue.Dequeue());
                    divPart = new eeNumber(asList);
                    divPart.TrimZeros();
                }

                divPart.TrimZeros();

                /* Divide it and append the division to the quotient */
                eeNumber q = new eeNumber(1); // number of times divisor fits into this divPart
                while (divisor * q <= divPart)
                {
                    q += ONE;
                }
                q -= ONE;

                quotient.Add(q); // keep track of quotient

                /* Figure out the remainder*/
                divPart = divPart - (divisor * q);
            }

            // remainder
            mod = divPart;

            var intergerQuotient = new eeNumber(quotient);

            intergerQuotient.TrimZeros();

            return(intergerQuotient);
        }
Пример #2
0
        // Warning: Subtraction will destroy the contents of num2 and set the contents of num1 to the result
        // Make sure to pass a copy of num2 if you are keeping its value
        public static eeNumber operator -(eeNumber num1_orig, eeNumber num2_orig)
        {
            eeNumber num1 = num1_orig.Copy(),
                     num2 = num2_orig.Copy();

            // If either number is a fraction, cross multiply
            if (num1.IsFrac() || num2.IsFrac())
            {
                eeNumber frac1 = num1.PopDenominator(),
                         frac2 = num2.PopDenominator();

                num1 *= frac2;
                num2 *= frac1;

                var ret = (num1 - num2) / (frac1 * frac2);

                ret.TrimZeros();
                ret.Simplify();

                return(ret);
            }

            // if the two nums are the same
            if (num1 == num2)
            {
                return(ZERO.Copy());
            }
            // if first num is negative
            else if (num1.negative && !num2.negative)
            {
                // add them then negate it
                num1.negative = false;
                var sum = num1 + num2;
                sum.negative = true;
                return(sum);
            }
            // if second num is negative
            else if (num2.negative && !num1.negative)
            {
                // minus and negatives cancel
                num2.negative = false;
                return(num1 + num2);
            }
            // If they're both negative
            else if (num1.negative && num2.negative)
            {
                // Treat this as adding a negative to a positive
                num2.negative = false;
                return(num1 + num2);
            }

            // If we're going to get a negative answer
            bool negate = false;

            if (num2 > num1)
            {
                // reverse the two
                var buf = num1;
                num1 = num2;
                num2 = buf;

                // and negate
                negate = true;
            }

            // Reverse because we're subtracting from right to left.
            byte[] l_bytes = num1.bytes.Reverse().ToArray(),
            r_bytes = num2.bytes.Reverse().ToArray();

            bool carry = false;
            int  i;

            for (i = 0; i < r_bytes.Length; i++)
            {
                // Account for the previous carry
                if (carry)
                {
                    r_bytes[i]++;
                    carry = false;
                }

                // Subtract the digits
                byte digitDiff;
                if (l_bytes[i] < r_bytes[i]) // account for carry
                {
                    digitDiff = (byte)((10 + l_bytes[i]) - r_bytes[i]);
                    carry     = true;
                }
                else
                {
                    digitDiff = (byte)(l_bytes[i] - r_bytes[i]);
                }

                // Set the digit
                l_bytes[i] = digitDiff;
            }


            // If there is still carry left
            while (carry)
            {
                // subtract one from the next value
                if (l_bytes[i] == 0)
                {
                    l_bytes[i] = 9;
                    i++;
                }
                else
                {
                    l_bytes[i] -= 1;
                    carry       = false;
                }
            }

            // Put it in order again
            l_bytes = l_bytes.Reverse().ToArray();

            num1.bytes    = l_bytes;
            num1.negative = negate;
            num1.TrimZeros();

            return(num1);
        }