Пример #1
0
 LargeNumbers(NumSign sign, IEnumerable <int> digits, int decimalPlaces)
 {
     Sign          = sign;
     Digits        = new ReadOnlyCollection <int>(digits.ToList());
     DecimalPlaces = decimalPlaces;
 }
Пример #2
0
        public static LargeNumbers Sub(LargeNumbers first, LargeNumbers second)
        {
            if (first.Sign == NumSign.Negative && second.Sign == NumSign.Positive)
            {
                LargeNumbers positiveFirst = new LargeNumbers(NumSign.Positive, first.Digits, first.DecimalPlaces);
                LargeNumbers sum           = Add(positiveFirst, second);
                return(new LargeNumbers(NumSign.Negative, sum.Digits, sum.DecimalPlaces));
            }
            else if (first.Sign == NumSign.Positive && second.Sign == NumSign.Negative)
            {
                LargeNumbers positiveSecond = new LargeNumbers(NumSign.Positive, second.Digits, second.DecimalPlaces);

                return(Add(first, positiveSecond));
            }
            else
            {
                List <int> digits1      = first.Digits.ToList();
                List <int> digits2      = second.Digits.ToList();
                List <int> resultDigits = new List <int>();
                NumSign    resultSign   = new NumSign();
                if ((digits1.Count - first.DecimalPlaces) < (digits2.Count - second.DecimalPlaces))
                {
                    if (first.Sign == NumSign.Positive && second.Sign == NumSign.Positive)
                    {
                        LargeNumbers sum = Sub(second, first);
                        return(new LargeNumbers(NumSign.Negative, sum.Digits, sum.DecimalPlaces));
                    }
                    else if (first.Sign == NumSign.Negative && second.Sign == NumSign.Negative)
                    {
                        LargeNumbers sum = Sub(second, first);
                        return(new LargeNumbers(NumSign.Positive, sum.Digits, sum.DecimalPlaces));
                    }
                }

                int maxDigitsBeforeDecimalPoint = Math.Max(
                    (digits1.Count - first.DecimalPlaces),
                    (digits2.Count - second.DecimalPlaces));

                digits1.InsertRange(0, Enumerable.Repeat(0, maxDigitsBeforeDecimalPoint - (digits1.Count - first.DecimalPlaces)));
                digits2.InsertRange(0, Enumerable.Repeat(0, maxDigitsBeforeDecimalPoint - (digits2.Count - second.DecimalPlaces)));

                int maxDigitsAfterDecimalPoint = Math.Max(
                    first.DecimalPlaces,
                    second.DecimalPlaces
                    );

                digits1.AddRange(Enumerable.Repeat(0, maxDigitsAfterDecimalPoint - first.DecimalPlaces));
                digits2.AddRange(Enumerable.Repeat(0, maxDigitsAfterDecimalPoint - second.DecimalPlaces));
                int carry = 0;
                if (digits1[0] < digits2[0])
                {
                    if (first.Sign == NumSign.Positive && second.Sign == NumSign.Positive)
                    {
                        LargeNumbers sum = Sub(second, first);
                        return(new LargeNumbers(NumSign.Negative, sum.Digits, sum.DecimalPlaces));
                    }
                    else if (first.Sign == NumSign.Negative && second.Sign == NumSign.Negative)
                    {
                        LargeNumbers sum = Sub(second, first);
                        return(new LargeNumbers(NumSign.Positive, sum.Digits, sum.DecimalPlaces));
                    }
                }
                else if (digits1[0] == digits2[0])
                {
                    int i = -1;
                    do
                    {
                        ++i;
                        if (i == digits1.Count - 1 && i == digits2.Count - 1 && digits1[i] == digits2[i])
                        {
                            break;
                        }
                        else if (digits1[i] < digits2[i])
                        {
                            if (first.Sign == NumSign.Positive && second.Sign == NumSign.Positive)
                            {
                                LargeNumbers sum = Sub(second, first);
                                return(new LargeNumbers(NumSign.Negative, sum.Digits, sum.DecimalPlaces));
                            }
                            else if (first.Sign == NumSign.Negative && second.Sign == NumSign.Negative)
                            {
                                LargeNumbers sum = Sub(second, first);
                                return(new LargeNumbers(NumSign.Positive, sum.Digits, sum.DecimalPlaces));
                            }
                        }
                    } while (digits1[i] == digits2[i] && i != digits2.Count);
                }


                for (int i = digits1.Count - 1; i >= 0; i--)
                {
                    if (digits1[i] - digits2[i] - carry < 0)
                    {
                        resultDigits.Insert(0, (10 - digits2[i] + digits1[i] - carry));
                        carry = 1;
                    }
                    else
                    {
                        resultDigits.Insert(0, ((digits1[i] - carry) - digits2[i]));
                        carry = 0;
                    }
                }
                if (carry == 0)
                {
                    resultSign = first.Sign;
                }
                if (carry == 1)
                {
                    resultSign = second.Sign;
                }
                return(new LargeNumbers(resultSign, resultDigits, maxDigitsAfterDecimalPoint));
            }
        }