Ejemplo n.º 1
0
        public static CatPrecise Divide(CatPrecise a, CatPrecise b)
        {
            var bia  = BigInteger.Parse(a.ToString().Replace(".", "")) * BigInteger.Parse("100000000000000000000");
            var bib  = BigInteger.Parse(b.ToString().Replace(".", ""));
            var aord = a.Order;
            var bord = b.Order;
            var dia  = bia / bib;
            var pra  = new CatPrecise(dia.ToString())
            {
                Order = Math.Max(0, aord - bord + (aord == bord ? 1 : 0))
            };

            return(pra);
        }
Ejemplo n.º 2
0
        public static (List <char> a, List <char> b) CreateTwoPeriods(CatPrecise a, CatPrecise b)
        {
            var aPeriod = new List <char>();
            var bPeriod = new List <char>();

            if (a.HavePeriod)
            {
                if (b.HavePeriod)
                {
                    for (var ai = 0; ai < b.Period.Count; ai++)
                    {
                        aPeriod.AddRange(a.Period);
                    }
                    for (var bi = 0; bi < a.Period.Count; bi++)
                    {
                        bPeriod.AddRange(b.Period);
                    }
                }
                else
                {
                    aPeriod = a.Period;

                    for (var bi = 0; bi < a.Period.Count; bi++)
                    {
                        bPeriod.Add('0');
                    }
                }
            }
            else
            {
                bPeriod = b.Period;

                for (var bi = 0; bi < b.Period.Count; bi++)
                {
                    aPeriod.Add('0');
                }
            }
            aPeriod.Reverse();
            bPeriod.Reverse();

            return(aPeriod, bPeriod);
        }
Ejemplo n.º 3
0
        public static CatPrecise Sum(CatPrecise a, CatPrecise b)
        {
            while (a.Order < b.Order)
            {
                a.Digits.Insert(0, '0');
                a.Order++;
            }

            while (a.Order > b.Order)
            {
                b.Digits.Insert(0, '0');
                b.Order++;
            }
            while (a.Digits.Count < b.Digits.Count)
            {
                a.Digits.Add('0');
            }

            while (a.Digits.Count > b.Digits.Count)
            {
                b.Digits.Add('0');
            }
            int asign = a.LessThanZero ? -1 : 1;
            int bsign = b.LessThanZero ? -1 : 1;

            var(lastOverflowSign, lastOverflow, result) = SumCharLists(asign, a.Digits, bsign, b.Digits);

            int ord = a.Order;

            if (lastOverflowSign < 0)
            {
                List <char> overflownNumber = new List <char>();
                overflownNumber.Add(lastOverflow);
                for (var j = 0; j < result.Count - 1; j++)
                {
                    overflownNumber.Add('0');
                }

                var overflowSum = SumCharLists(-1, overflownNumber, 1, result);
                result = overflowSum.result;
            }
            else
            {
                if (lastOverflow != '0')
                {
                    result.Insert(0, lastOverflow);
                    ord++;
                }
            }

            List <char> period = new List <char>();

            if (a.HavePeriod || b.HavePeriod)
            {
                var(aPeriodList, bPeriodList) = CreateTwoPeriods(a, b);

                var         periodSum       = SumCharLists(asign, aPeriodList, bsign, bPeriodList);
                List <char> overflownNumber = new List <char>();
                overflownNumber.Add(periodSum.overflow);
                for (var j = 0; j < result.Count - 1; j++)
                {
                    overflownNumber.Add('0');
                }
                period = periodSum.result;
                var overflowSum = SumCharLists(periodSum.sign, overflownNumber, 1, result);
                lastOverflowSign = overflowSum.sign;
                result           = overflowSum.result;
            }


            a.Validate();
            b.Validate();
            var resultPrecise = new CatPrecise(0)
            {
                Digits = result, LessThanZero = lastOverflowSign < 0, Order = ord
            };

            if (period.Count > 0)
            {
                resultPrecise.Period = period;
            }
            resultPrecise.Validate();
            return(resultPrecise);
        }
Ejemplo n.º 4
0
        public static CatPrecise Multiply(CatPrecise a, CatPrecise b)
        {
            var dIndex  = a.Digits.Count - a.Order + b.Digits.Count - b.Order + (a.HavePeriod ? PeriodLength : 0) + (b.HavePeriod ? PeriodLength : 0);
            int aSign   = a.LessThanZero ? -1 : 1;
            int bSign   = b.LessThanZero ? -1 : 1;
            var sign    = aSign * bSign;
            var resInts = new int[a.Digits.Count + (a.HavePeriod ? PeriodLength : 0) + b.Digits.Count + 1 + (b.HavePeriod ? PeriodLength : 0)];

            for (var i = 0; i < a.Digits.Count + (a.HavePeriod ? PeriodLength : 0); i++)
            {
                for (var j = 0; j < b.Digits.Count + (b.HavePeriod ? PeriodLength : 0); j++)
                {
                    var(overflow, res)  = DigitIntMult(a[a.Digits.Count - 1 - i + (a.HavePeriod ? PeriodLength : 0)], b[b.Digits.Count - 1 - j + (b.HavePeriod ? PeriodLength : 0)]);
                    resInts[i + j]     += res;
                    resInts[i + j + 1] += overflow;
                }
            }

            for (int i = 0; i < resInts.Length; i++)
            {
                var resInt   = resInts[i];
                var res      = resInt % 10;
                var overflow = resInt / 10;
                resInts[i] = res;
                if (overflow > 0)
                {
                    resInts[i + 1] += overflow;
                }
            }

            var result = new List <char>();

            for (int i = resInts.Length - 1; i >= 0; i--)
            {
                var dig = GetDigit(resInts[i]);
                result.Add(dig);
            }

            var cutLength = result.Count;

            if (a.HavePeriod)
            {
                cutLength -= PeriodLength / 2;
            }
            if (b.HavePeriod)
            {
                cutLength -= PeriodLength / 2;
            }

            var oldLength = result.Count;

            result = result.GetRange(0, cutLength);

            var resultPrecise = new CatPrecise(0)
            {
                Digits = result, LessThanZero = sign < 0, Order = oldLength - dIndex
            };

            resultPrecise.Validate();
            return(resultPrecise);
        }