示例#1
0
        private static void AddSubTest(LongNumber a, LongNumber b)
        {// всякие тесты
            Console.WriteLine("***********************");
            Console.ForegroundColor = ConsoleColor.DarkRed;
            Console.WriteLine("add-sub test");
            Console.ForegroundColor = ConsoleColor.DarkYellow;
            Console.Write("a = ");
            Console.ResetColor();
            Console.WriteLine(a + " ( " + a.ToDecString() + " )");
            Console.ForegroundColor = ConsoleColor.DarkYellow;
            Console.Write("b = ");
            Console.ResetColor();
            Console.WriteLine(b + " ( " + b.ToDecString() + " )");
            var c = a + b;

            Console.ForegroundColor = ConsoleColor.DarkYellow;
            Console.Write("a + b = ");
            Console.ResetColor();
            Console.WriteLine(c + " ( " + c.ToDecString() + " )");
            var d = a - b;

            Console.ForegroundColor = ConsoleColor.DarkYellow;
            Console.Write("a - b = ");
            Console.ResetColor();
            Console.WriteLine(d + " ( " + d.ToDecString() + " )");
            a.ChandgeSing();
            var k = a + b;

            Console.ForegroundColor = ConsoleColor.DarkYellow;
            Console.Write("-a + b = ");
            Console.ResetColor();
            Console.WriteLine(k + " ( " + k.ToDecString() + " )");
            a.ChandgeSing();
            Console.WriteLine("***********************");
        }
示例#2
0
        private static void MulTest(LongNumber a, LongNumber b)
        {// тесты
            Console.WriteLine("***********************");
            Console.ForegroundColor = ConsoleColor.DarkRed;
            Console.WriteLine("Multiply test");
            Console.ForegroundColor = ConsoleColor.DarkYellow;
            Console.Write("a = ");
            Console.ResetColor();
            Console.WriteLine(a + " ( " + a.ToDecString() + " )");
            Console.ForegroundColor = ConsoleColor.DarkYellow;
            Console.Write("b = ");
            Console.ResetColor();
            Console.WriteLine(b + " ( " + b.ToDecString() + " )");
            var c = a * b;

            Console.ForegroundColor = ConsoleColor.DarkYellow;
            Console.Write("a * b = ");
            Console.ResetColor();
            Console.WriteLine(c + " ( " + c.ToDecString() + " )");
            var d = c / b;

            Console.ForegroundColor = ConsoleColor.DarkYellow;
            Console.Write("c / b = ");
            Console.ResetColor();
            Console.WriteLine(d + " ( " + d.First.ToDecString() + " , " + d.Second.ToDecString() + " )");
            var e = c / a;

            Console.ForegroundColor = ConsoleColor.DarkYellow;
            Console.Write("c / a = ");
            Console.ResetColor();
            Console.WriteLine(e + " ( " + e.First.ToDecString() + " , " + e.Second.ToDecString() + " )");
            Console.WriteLine("***********************");
        }
示例#3
0
        private static void DivTest(LongNumber a, LongNumber b)
        { //тесты
            Console.WriteLine("***********************");
            Console.ForegroundColor = ConsoleColor.DarkRed;
            Console.WriteLine("Divide test");
            Console.ForegroundColor = ConsoleColor.DarkYellow;
            Console.Write("a = ");
            Console.ResetColor();
            Console.WriteLine(a + " ( " + a.ToDecString() + " )");
            Console.ForegroundColor = ConsoleColor.DarkYellow;
            Console.Write("b = ");
            Console.ResetColor();
            Console.WriteLine(b + " ( " + b.ToDecString() + " )");
            var c = a / b;

            Console.ForegroundColor = ConsoleColor.DarkYellow;
            Console.Write("a / b = ");
            Console.ResetColor();
            Console.WriteLine(c + " ( " + c.First.ToDecString() + " , " + c.Second.ToDecString() + " )");
            var d = (b * c.First + c.Second);

            Console.ForegroundColor = ConsoleColor.DarkYellow;
            Console.Write("c * a + b = ");
            Console.ResetColor();
            Console.WriteLine(d + " ( " + d.ToDecString() + " )");
            Console.WriteLine("***********************");
        }
示例#4
0
        static void ComplexTest(LongNumber a, LongNumber b)
        {// общий тест, компелексный так сказать
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("######### Test set #" + (++_orderNumber) + " #########");
            Console.ResetColor();

            var st  = DateTime.Now;
            var slt = DateTime.Now;

            AddSubTest(a, b);
            var lt = DateTime.Now - slt;

            Console.ForegroundColor = ConsoleColor.Magenta;
            Console.WriteLine("AddSubTest time " + lt.Seconds + " sec " + lt.Milliseconds + " msec");
            Console.ResetColor();
            slt = DateTime.Now;
            MulTest(a, b);
            lt = DateTime.Now - slt;
            Console.ForegroundColor = ConsoleColor.Magenta;
            Console.WriteLine("MulTest time " + lt.Seconds + " sec " + lt.Milliseconds + " msec");
            Console.ResetColor();
            slt = DateTime.Now;
            DivTest(a, b);
            lt = DateTime.Now - slt;
            Console.ForegroundColor = ConsoleColor.Magenta;
            Console.WriteLine("DivTest time " + lt.Seconds + " sec " + lt.Milliseconds + " msec");
            Console.ResetColor();
            var t = DateTime.Now - st;

            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("Total time " + t.Seconds + " sec " + t.Milliseconds + " msec");
            Console.ResetColor();
            Console.WriteLine();
        }
示例#5
0
        // сложение
        public static LongNumber Add(LongNumber first, LongNumber second)
        {

            var sum = new LongNumber(first._discharges);
            var isCarry = false;
            for (int i = 0; i < second._discharges.Count; i++)
            {
                var add = sum._discharges[i] + second._discharges[i] + (isCarry ? 1 : 0);
                isCarry = (add >> 8) > 0;
                sum._discharges[i] = (byte)add;
            }
            var carryIndex = second._discharges.Count;
            while (isCarry)
            {
                if (sum._discharges.Count > carryIndex)
                {
                    sum._discharges[carryIndex] += 1;
                    if (sum._discharges[carryIndex] != 0) isCarry = false;
                    carryIndex++;
                }
                else
                {
                    sum._discharges.Add(1);
                    isCarry = false;
                }
            }
            return sum;
        }
示例#6
0
        // специальное сложение для умножения. чтоб быстрее
        private static void multuADD(LongNumber output, LongNumber longNumber, int index)
        {

            var isCarry = false;
            for (int i = 0; i < longNumber._discharges.Count; i++)
            {
                if (output._discharges.Count == i + index) output._discharges.Add(0);
                var add = output._discharges[i+index] + longNumber._discharges[i] + (isCarry ? 1 : 0);

                isCarry = (add >> 8) > 0;
                output._discharges[i+index] = (byte)add;

            }
            var carryIndex = longNumber._discharges.Count+index;
            while (isCarry)
            {
                if (output._discharges.Count > carryIndex)
                {
                    output._discharges[carryIndex] += 1;
                    if (output._discharges[carryIndex] != 0) isCarry = false;
                    carryIndex++;
                }
                else
                {
                    output._discharges.Add(1);
                    isCarry = false;
                }
            }
            
        }
示例#7
0
        static void Main(string[] args)
        {
            var a = new LongNumber(new List <byte> {
                255, 1
            });
            var b = new LongNumber(new List <byte> {
                1, 255
            });

            ComplexTest(a, b);


            a = new LongNumber(new List <byte> {
                255, 255, 255, 255
            });
            b = new LongNumber(new List <byte> {
                1, 0, 0, 0, 1
            });

            ComplexTest(a, b);



            a = LongNumber.FromDecString("+1000000000000000000000000000");
            b = LongNumber.FromDecString("+1000000000000000000000000000");

            ComplexTest(a, b);
        }
示例#8
0
 // сранение 1 - первое больше, -1 первое меньше, 0 - равны
 public static int AbsCompare(LongNumber first, LongNumber second)
 {
     if (first._discharges.Count < second._discharges.Count) return -1;
     if (first._discharges.Count > second._discharges.Count) return 1;
     for (int i = first._discharges.Count - 1; i >= 0; i--)
     {
         if (first._discharges[i] < second._discharges[i]) return -1;
         if (first._discharges[i] > second._discharges[i]) return 1;
     }
     return 0;
 }
示例#9
0
 // перегруз оператора. учтено, что иногда сложение - это вычитание (например -5+3 - это 3 - 5)
 public static LongNumber operator -(LongNumber first, LongNumber second)
 {
     if (first.Equals(second))
         second = new LongNumber(second._discharges) {_isNegative = !first._isNegative};
     
     else
     second._isNegative = ! second._isNegative;
     var output = first + second;
     second._isNegative = !second._isNegative;
     return output;
 }
示例#10
0
 // из десятичной строки
 public static LongNumber FromDecString(string s)
 {
     var output = new LongNumber(new List<byte> { 0 });
     for (int i = 1; i < s.Length; i++)
     {
         output *= 10;
         output += new LongNumber(new List<byte> { (byte)(s[i] - '0') });
     }
     output._isNegative = s[0] == '-';
     return output;
 }
示例#11
0
        public static LongNumber Factorial(int inputValue)
        {
            LongNumber[] fact = new LongNumber[inputValue + 1];
            fact[0] = new LongNumber("0");
            fact[1] = new LongNumber("1");
            fact[2] = new LongNumber("2");
            LongNumber j = new LongNumber("3");

            for (int i = 3; i <= inputValue - 2; i++)
            {
                fact[i] = fact[i - 1] * j;
            }
            return(fact[inputValue - 2]);
        }
示例#12
0
        // умножение длинного на байт
        public static LongNumber operator *(LongNumber ln, byte b)
        {
            var output = new LongNumber(ln._discharges);
            byte carry = 0;
            for (int i = 0; i < output._discharges.Count; i++)
            {
                int intermediate = output._discharges[i]*b;
                var addCarry = ((intermediate & 255) + carry) >> 8;
                output._discharges[i] = (byte) ((intermediate & 255) + carry);
                carry = (byte) ((intermediate >> 8)+addCarry);
            }
            if (carry>0) output._discharges.Add(carry);
           

            return output;
        }
示例#13
0
        // в десятичную строку
        public string ToDecString()
        {
            var sb = new StringBuilder();
            sb.Append(Sign());
            var forOut = new LongNumber(_discharges);
            var ten = new LongNumber(new byte[] { 10 });
            while (forOut._discharges.Count>1||forOut._discharges[0] > 9)
            {
                var div = forOut / ten;
                forOut = div.First;
                sb.Insert(1, (char)('0' + div.Second._discharges[0]));
            }
            sb.Insert(1, (char)('0' + forOut._discharges[0]));
            return sb.ToString();

        }
示例#14
0
        public static void Main()
        {
            LongNumber a = new LongNumber(new List <int>()
            {
                0, 0, 1
            }, true);
            LongNumber c = new LongNumber(new List <int>()
            {
                0, 2
            }, true);
            // int b = 200;
            // LongNumber d = new LongNumber(new List<int>() { 0, 1 }, true);
            // d += b;
            LongNumber q = new LongNumber("-123");

            Console.WriteLine(Factorial(10));
        }
示例#15
0
        // деление (частное, остаток)
        public static Cont <LongNumber,LongNumber> operator /(LongNumber first, LongNumber second)
        {

            var output = new LongNumber();
            var residue = new LongNumber(first._discharges,first._isNegative);

            if (AbsCompare(first, second) == -1)
            {
                output._discharges.Add(0);
                return new Cont<LongNumber, LongNumber>(output, residue);
            }
            var discharge = residue._discharges.Count - second._discharges.Count;

            for (int i = 0; i < discharge; i++) second._discharges.Insert(0,0);

            for (int i = 0; i < discharge; i++)
            {
                if (AbsCompare(residue, second) == -1)
                    output._discharges.Insert(0, 0);
                else
                {
                    var cont = getDivider(residue, second);
                    output._discharges.Insert(0, cont.First);
                    residue = cont.Second;

                }
                second._discharges.RemoveAt(0);
            }
            if (AbsCompare(residue, second) == -1)
                output._discharges.Insert(0, 0);
            else
            {
                var cont = getDivider(residue, second);
                output._discharges.Insert(0, cont.First);
                residue = cont.Second;

            }


            var lastIndex = output._discharges.Count;
            while (lastIndex != 0 && output._discharges[--lastIndex] == 0) ;
            output._discharges.RemoveRange(lastIndex + 1, output._discharges.Count - lastIndex - 1);
            output._isNegative = first._isNegative != second._isNegative;
            return new Cont<LongNumber, LongNumber>(output,residue);
        }
示例#16
0
        // широкую на широкую! умножаем
        public static LongNumber operator *(LongNumber first, LongNumber second)
        {

            var output = new LongNumber();
            if (AbsCompare(first, second) == -1)
            {
                var temp = second;
                second = first;
                first = temp;
            }

            for (int i = 0; i < second._discharges.Count; i++)
                multuADD (output, first*second._discharges[i], i);
            var lastIndex = output._discharges.Count;
            while (lastIndex != 0 && output._discharges[--lastIndex] == 0) ;
            output._discharges.RemoveRange(lastIndex + 1, output._discharges.Count - lastIndex - 1);
            output._isNegative = first._isNegative != second._isNegative;
            return output;
        }
示例#17
0
        // подбор очередного байта частного методом дихотомии. (гуглить "окулов длинная арифметика")
        private static Cont<Byte,LongNumber> getDivider(LongNumber residue, LongNumber second)
        {
            var down = 0;
            var up = 256;
            while (down + 1 < up)
            {
                var newValue = second*(byte) ((down + up)/2);

                if (AbsCompare(residue, newValue) == -1)
                {
                    up = (down + up) / 2;
                }
                else
                {
                    down = (down + up) / 2;
                }
            }

            var residueOut = Subtract(residue, second * (byte)down);
            residueOut._isNegative = residue._isNegative;

            return new Cont<Byte,LongNumber>((byte)down, residueOut);
        }
示例#18
0
        // вычитание
        public static LongNumber Subtract(LongNumber first, LongNumber second)
        {
            var sum = new LongNumber(first._discharges);
            var isCarry = false;
            for (int i = 0; i < second._discharges.Count; i++)
            {
                var isCarryNext = sum._discharges[i] < second._discharges[i] ;
                sum._discharges[i] -= (byte)(second._discharges[i] + (isCarry ? 1 : 0));
                isCarry = isCarryNext;
            }
            var carryIndex = second._discharges.Count;
            while (isCarry)
            {
                    if (sum._discharges[carryIndex] != 0) isCarry = false;
                    sum._discharges[carryIndex] -= 1;
                    carryIndex++;
            }
            var lastIndex = sum._discharges.Count;
            while (lastIndex !=0 && sum._discharges[--lastIndex] == 0);
            sum._discharges.RemoveRange(lastIndex + 1, sum._discharges.Count-lastIndex-1);

            return sum;
        }
示例#19
0
 public LongNumber(LongNumber ln)
 {
     _discharges = ln._discharges;
 }