コード例 #1
0
 public static ArbitraryNumber Sub(ArbitraryNumber a, ArbitraryNumber b)
 {
     if (a.IsNegative)
     {
         if (b.IsNegative)
         {
             return(-SubstractPositives(-a, -b));
         }
         else
         {
             return(-AddPositives(-a, b));
         }
     }
     else
     {
         if (b.IsNegative)
         {
             return(AddPositives(a, -b));
         }
         else
         {
             return(SubstractPositives(a, b));
         }
     }
 }
コード例 #2
0
        private static ArbitraryNumber Abs(ArbitraryNumber num)
        {
            var abs = new ArbitraryNumber(num);

            abs.IsNegative = false;
            return(abs);
        }
コード例 #3
0
        private static ArbitraryNumber MultBySingleDigit(ArbitraryNumber an, int digit)
        {
            Guard.Requires(0 <= digit && digit < 10, $"Requires 0 <= {nameof(digit)} < 10, but actual value was {digit}");

            var result = new ArbitraryNumber();

            int carryOver = 0;

            foreach (int d in an.Digits.AsEnumerable().Reverse())
            {
                int mul = d * digit + carryOver;
                int val = mul % 10;
                carryOver = (mul - val) / 10;

                result.Digits.Insert(0, val);
            }

            while (carryOver > 0)
            {
                int val = carryOver % 10;
                result.Digits.Insert(0, val);
                carryOver = (carryOver - val) / 10;
            }

            result.DecimalsCount = an.DecimalsCount;

            Trim(result);

            return(result);
        }
コード例 #4
0
 private static void InsertdecimalShift(ArbitraryNumber intermediateResult, int decimalShift)
 {
     for (int i = 0; i < decimalShift; i++)
     {
         intermediateResult.Digits.Insert(0, 0);
     }
 }
コード例 #5
0
 public static ArbitraryNumber Mult(ArbitraryNumber a, ArbitraryNumber b)
 {
     if (a.IsNegative == b.IsNegative)
     {
         return(MultPositives(Abs(a), Abs(b)));
     }
     else
     {
         return(-MultPositives(Abs(a), Abs(b)));
     }
 }
コード例 #6
0
        private static void AlignFractionalDigits(ArbitraryNumber num1, ArbitraryNumber num2)
        {
            if (num1.FractionalPart.Count == num2.FractionalPart.Count)
            {
                return;
            }

            ArbitraryNumber lessFractional = Selector.Min(an => an.FractionalPart.Count, num1, num2);
            ArbitraryNumber mostFractional = Selector.Max(an => an.FractionalPart.Count, num1, num2);

            lessFractional.Digits.AddRange(Enumerable.Repeat(0, mostFractional.FractionalPart.Count - lessFractional.FractionalPart.Count));
            lessFractional.DecimalsCount += mostFractional.FractionalPart.Count - lessFractional.FractionalPart.Count;
        }
コード例 #7
0
 private static void Trim(ArbitraryNumber num)
 {
     if (num.DecimalsCount > 0)
     {
         int initialDigitsCount = num.Digits.Count;
         num.Digits.TrimRight(0, num.DecimalsCount);
         num.DecimalsCount -= initialDigitsCount - num.Digits.Count;
     }
     num.Digits.TrimLeft(0);
     if (!num.Digits.Any())
     {
         num.DecimalsCount = 0;
     }
 }
コード例 #8
0
        private static ArbitraryNumber SubstractPositives(ArbitraryNumber a, ArbitraryNumber b)
        {
            var num1 = new ArbitraryNumber(a);
            var num2 = new ArbitraryNumber(b);

            AlignFractionalDigits(num1, num2);

            var result = new ArbitraryNumber();

            var enumerator = new ParallelEnumerator <int>(num1.Digits.AsEnumerable().Reverse(), num2.Digits.AsEnumerable().Reverse());

            int carryOver = 0;

            while (enumerator.Next())
            {
                int val1 = enumerator.Current[0];
                int val2 = enumerator.Current[1];
                int sub  = val1 - val2 - carryOver;

                int val = 0;
                if (sub < 0)
                {
                    val       = 10 + sub;
                    carryOver = 1;
                }
                else
                {
                    val       = sub;
                    carryOver = 0;
                }

                result.Digits.Insert(0, val);
            }

            if (carryOver > 0)
            {
                result.Digits.Insert(0, carryOver);
                result.IsNegative = true;
            }

            result.DecimalsCount = num1.DecimalsCount;

            Trim(result);

            return(result);
        }
コード例 #9
0
        private static ArbitraryNumber MultPositives(ArbitraryNumber arbitraryNumber1, ArbitraryNumber arbitraryNumber2)
        {
            var result = new ArbitraryNumber();
            var an     = new ArbitraryNumber(arbitraryNumber1);

            foreach (int digit in arbitraryNumber2.Digits.AsEnumerable().Reverse())
            {
                result += MultBySingleDigit(an, digit);
                an.Digits.Add(0);
            }


            result.DecimalsCount += arbitraryNumber2.DecimalsCount;

            Trim(result);

            return(result);
        }
コード例 #10
0
        public static ArbitraryNumber Pow(this ArbitraryNumber a, int pow)
        {
            if (pow == 0)
            {
                return(1);
            }

            ArbitraryNumber result = 1;

            for (int i = 0; i < pow; i++)
            {
                result *= a;
            }

            Trim(result);

            return(pow > 0 ? result : 1 / result);
        }
コード例 #11
0
 public static ArbitraryNumber Min(ArbitraryNumber a, ArbitraryNumber b)
 {
     if (a.IntegerPart.Count < b.IntegerPart.Count)
     {
         return(a);
     }
     if (a.IntegerPart.Count > b.IntegerPart.Count)
     {
         return(b);
     }
     if (a.Digits[0] <= b.Digits[0])
     {
         return(a);
     }
     else
     {
         return(b);
     }
 }
コード例 #12
0
        private static ArbitraryNumber AddPositives(ArbitraryNumber a, ArbitraryNumber b)
        {
            var num1 = new ArbitraryNumber(a);
            var num2 = new ArbitraryNumber(b);

            AlignFractionalDigits(num1, num2);

            var result = new ArbitraryNumber();

            var enumerator = new ParallelEnumerator <int>(num1.Digits.AsEnumerable().Reverse(), num2.Digits.AsEnumerable().Reverse());

            int carryOver = 0;

            while (enumerator.Next())
            {
                int val1  = enumerator.Current[0];
                int val2  = enumerator.Current[1];
                int added = val1 + val2 + carryOver;

                int val = added % 10;
                carryOver = (added - val) / 10;

                result.Digits.Insert(0, val);
            }

            if (carryOver > 0)
            {
                result.Digits.Insert(0, carryOver);
            }

            result.DecimalsCount = num1.DecimalsCount;

            Trim(result);

            return(result);
        }
コード例 #13
0
 public static ArbitraryNumber Pow(ArbitraryNumber a, ArbitraryNumber pow)
 {
     throw new System.NotImplementedException();
 }
コード例 #14
0
 public ArbitraryNumber(ArbitraryNumber other) : this(new List <int>(other?.Digits ?? new List <int>()), other?.DecimalsCount ?? 0)
 {
 }