private HugeInteger larger(HugeInteger hugeInt)
        {
            if (length() > hugeInt.length())
            {
                return(this);
            }
            if (hugeInt.length() > length())
            {
                return(hugeInt);
            }
            var larger = this;

            for (int i = DIGITS_SIZE - 1; i >= 0; i--)
            {
                if (digits[i] > hugeInt.digits[i])
                {
                    larger = this;
                    break;
                }
                else if (digits[i] < hugeInt.digits[i])
                {
                    larger = hugeInt;
                    break;
                }
            }
            return(larger);
        }
        public HugeInteger sum(HugeInteger hugeInt)
        {
            var  carry   = 0;
            bool summing = true;

            //only summing if signs equal
            if (sign != hugeInt.sign)
            {
                summing = false;
            }
            var newDigits = new int[30];
            var newSign   = Sign.Positive;

            if (summing)
            {
                //add from lowest index/place to highest index/place
                for (int i = 0; i < DIGITS_SIZE; i++)
                {
                    newDigits[i] = (digits[i] + hugeInt.digits[i] + carry) % 10;
                    carry        = (digits[i] + hugeInt.digits[i] + carry) / 10;
                }
                newSign = sign;
            }
            else
            {
                //clone to prevent mutation of original
                var clone = hugeInt.clone();
                clone.sign = Sign.Positive;
                return(diff(clone));
            }
            return(new HugeInteger(newDigits, newSign));
        }
        public HugeInteger mod(HugeInteger hugeInt)
        {
            var newSign = sign != hugeInt.sign ? Sign.Negative : Sign.Positive;

            //return numerator if it is less than denominator
            if (larger(hugeInt) == hugeInt)
            {
                var result = clone();
                result.sign = newSign;
                return(result);
            }
            else
            {
                //clone to prevent mutation of original
                var divisor = hugeInt.clone();
                divisor.sign = Sign.Positive;
                //clone to prevent mutation of original
                var dividend = clone();
                dividend.sign = Sign.Positive;
                //repeatedly subtract divisor from dividend until dividend is smaller than divisor
                while (dividend.larger(divisor) != divisor)
                {
                    dividend = dividend.diff(divisor);
                }
                return(dividend);
            }
        }
 public HugeInteger div(HugeInteger hugeInt)
 {
     //return zero if numerator is less than denominator
     if (larger(hugeInt) == hugeInt)
     {
         return(new HugeInteger());
     }
     else
     {
         var newSign = sign != hugeInt.sign ? Sign.Negative : Sign.Positive;
         var divisor = hugeInt.clone();
         divisor.sign = Sign.Positive;
         var dividend = clone();
         dividend.sign = Sign.Positive;
         var quotient = new HugeInteger();
         //repeatedly subtract divisor from dividend until dividend is smaller than divisor
         while (dividend.larger(divisor) != divisor)
         {
             quotient = quotient.sum(Input("1"));
             dividend = dividend.diff(divisor);
         }
         quotient.sign = newSign;
         return(quotient);
     }
 }
        public HugeInteger prod(HugeInteger hugeInt)
        {
            var carry       = 0;
            var accumulator = new HugeInteger(new int[DIGITS_SIZE], Sign.Positive);
            var thisLength  = length();

            //Add one to length if room to account for carry
            thisLength = thisLength == DIGITS_SIZE ? thisLength : thisLength + 1;
            var hugeIntLength = hugeInt.length();

            //Add one to length if room to account for carry
            hugeIntLength = hugeIntLength == DIGITS_SIZE ? hugeIntLength : hugeIntLength + 1;
            for (int i = 0; i < thisLength; i++)
            {
                var product        = new int[DIGITS_SIZE];
                var coefficientOne = digits[i];
                //build an addend, partial product to be added to running sum
                for (int j = 0; j < hugeIntLength; j++)
                {
                    var coefficientTwo = hugeInt.digits[j];
                    var total          = coefficientOne * coefficientTwo + carry;
                    product[i + j] = (total) % 10;
                    carry          = total >= 10 ? total / 10 : 0;
                }
                //add addened, partial product to running sum
                accumulator = accumulator.sum(new HugeInteger(product, Sign.Positive));
            }
            var newSign = sign != hugeInt.sign ? Sign.Negative : Sign.Positive;

            return(new HugeInteger(accumulator.digits, newSign));
        }
        private HugeInteger preBorrow(HugeInteger larger, HugeInteger smaller)
        {
            //clone to prevent mutation of original
            var largerClone = larger.clone();

            for (int i = DIGITS_SIZE - 1; i >= 0; i--)
            {
                if (larger.digits[i] < smaller.digits[i])
                {
                    //find index to borrow from
                    var greaterThanIndex = 0;
                    for (int p = i + 1; p < DIGITS_SIZE; p++)
                    {
                        if (largerClone.digits[p] > smaller.digits[p])
                        {
                            greaterThanIndex = p;
                            break;
                        }
                    }
                    //borrow
                    largerClone.digits[greaterThanIndex]--;
                    //distribute the borrow to intermediate indicies
                    for (int j = greaterThanIndex - 1; j > i; j--)
                    {
                        largerClone.digits[j] += 9;
                    }
                    //distribute borrow to digit needing it
                    largerClone.digits[i] += 10;
                }
            }
            return(largerClone);
        }
Beispiel #7
0
        public static void FactorialTest()
        {
            var FACTORIAL   = 25;
            var accumulator = HugeInteger.Input("1");

            for (int i = 2; i <= FACTORIAL; i++)
            {
                var multiplier = HugeInteger.Input(i.ToString());
                accumulator = accumulator.prod(multiplier);
            }
            Console.WriteLine(FACTORIAL + "! = " + accumulator.toString());
        }
Beispiel #8
0
 public static void MethodTests()
 {
     string[,] pairs = { { "100", "7" }, { "2019", "2310" }, { "8384724", "2395" } };
     for (int i = 0; i < pairs.GetLength(0); i++)
     {
         var hugeIntOne = HugeInteger.Input(pairs[i, 0]);
         var hugeIntTwo = HugeInteger.Input(pairs[i, 1]);
         var sum        = hugeIntOne.sum(hugeIntTwo);
         var diff       = hugeIntOne.diff(hugeIntTwo);
         var prod       = hugeIntOne.prod(hugeIntTwo);
         var div        = hugeIntOne.div(hugeIntTwo);
         var mod        = hugeIntOne.mod(hugeIntTwo);
         Console.WriteLine(hugeIntOne.toString() + " + " + hugeIntTwo.toString() + " = " + sum.toString());
         Console.WriteLine(hugeIntOne.toString() + " - " + hugeIntTwo.toString() + " = " + diff.toString());
         Console.WriteLine(hugeIntOne.toString() + " * " + hugeIntTwo.toString() + " = " + prod.toString());
         Console.WriteLine(hugeIntOne.toString() + " / " + hugeIntTwo.toString() + " = " + div.toString());
         Console.WriteLine(hugeIntOne.toString() + " % " + hugeIntTwo.toString() + " = " + mod.toString());
     }
 }
        public HugeInteger diff(HugeInteger hugeInt)
        {
            //signs match so add
            if (sign == Sign.Negative && hugeInt.sign == Sign.Positive)
            {
                //clone to prevent mutation of original
                var clone = hugeInt.clone();
                clone.sign = Sign.Negative;
                return(sum(clone));
            }
            //signs match so add
            if (sign == Sign.Positive && hugeInt.sign == Sign.Negative)
            {
                //clone to prevent mutation of original
                var clone = hugeInt.clone();
                clone.sign = Sign.Positive;
                return(sum(clone));
            }

            var largest  = larger(hugeInt);
            var smallest = largest == this ? hugeInt : this;

            //pre borrow if any digits in larger number are smaller than
            //any digits in the smaller number in respective indicies
            largest = preBorrow(largest, smallest);

            var newDigits = new int[30];
            var newSign   = largest.sign;

            //subtract from highest index/place to lowest index/place
            for (int i = DIGITS_SIZE - 1; i >= 0; i--)
            {
                newDigits[i] = (largest.digits[i] - smallest.digits[i]) % 10;
            }
            return(new HugeInteger(newDigits, newSign));
        }
Beispiel #10
0
        public HugeInteger clone()
        {
            var zero = new HugeInteger();

            return(sum(zero));
        }