Длинная арифметика. Сложение и вычитание целых чисел.

Цитирую:
Числа, для представления которых в стандартных компьютерных типах данных не хватает количества двоичных разрядов, называются "длинными". Реализация арифметических операций над такими "длинными" числами получила название "длинной арифметики".

С.М. Окулов      
  1. Поразрядное сложения и вычитания длинных целых чисел, представленных строками символов
  2. Функция Сложения длинных чисел
  3. Функция Вычитания длинных чисел
  4. Интерфейс простейшего приложения длинной арифметики

Если не заморачиваться быстродействием, то одним из наиболее простых и удобных представлений ДЛИННЫХ ЧИСЕЛ будет тип string, т.е. массив символов цифр.

Удобство здесь в том, что не надо думать о длине массива. Тип string обеспечит необходимые размеры массивов, как для операндов, так и для результатов любых вычислений.

Поразрядное сложения и вычитания длинных целых чисел, представленных строками символов

Предоставляя пользователю возможность вводить числа, автоматически приходится контролировать результаты его ввода... Иначе... бедный процессор может получить такую "ерунду" вместо чисел, что сломает голову.

Поэтому

  1. Запрещаю ввод любых символов кроме десятичных цифр
  2. И кроме того, удаляю все нули слева



Функция Сложения длинных чисел

Таким образом, остается написать функции поочередной обработки пар цифр (из одинаковых разрядов двух операндов) и при необходимости сохранять и переносить в соседний разряд значение «переноса» (или то, что «на ум пошло», как говорили в первом классе, когда учили складывать и перемножать столбиком).

//------------------------------
string SUM_StringNum(string st1, string st2)
{
    string res="", s1, s2;
   
    int i, su, carri=0; //сумма и перенос

    if(st1.Length > st2.Length)    { s1=Revers(st1); s2=Revers(st2);}//s1 не меньше s2
else { s1=Revers(st2); s2=Revers(st1); }

for(i=0;i<(s1.Length);i++)
        {    int si1=s1[i]-48;           
            if(i<s2.Length)
            {
                int si2=s2[i]-48;
                su = si1 + si2+ carri;
            }
            else su = si1+ carri;   

            carri=su/10;    //целочисленное деление
            res+= System.Convert.ToString(su % 10);
}

        while (carri>0) //возможна цепочка увеличений
        {       
            res+= System.Convert.ToString(carri % 10);
            carri=carri/10;    //целочисленное деление
        }       

    return Revers(res);
}
//------------------------------

Реверс - чтение числа-строки в обратном порядке необходим для синхронизации разрядов, начиная с младших.


Функция Вычитания длинных чисел

Здесь прежде всего важно сравнить числа... И если "Вычитаемое" больше "Уменьшаемого", то поменять их местами и установить знак "-" (минус) для результата.

//------------------------------
string SUB_StringNum(string st1, string st2)
{
string res = "", znak = "", s1, s2;
   
    int i, su, carri=0; //сумма и перенос

if (st1.Length < st2.Length) znak = "-";        //s1 меньше s2
    if(st1.Length == st2.Length)
        for(i=0;i<(st1.Length);i++){
if (st1[i] < st2[i]) znak = "-";    //s1 меньше s2
            if(st1[i]>st2[i])break;
        }

if (znak == "-") { s2 = Revers(st1); s1 = Revers(st2); }
else { s1 = Revers(st1); s2 = Revers(st2); }
               
       
for(i=0;i<(s1.Length);i++)
        {    int si1=s1[i]-48;           
            if(i<s2.Length)
            {
                int si2=s2[i]-48;
                su = si1 - si2- carri;
                if(su<0){
                    su+=10;
                    carri=1;
                }
                else carri=0;   
               
            }
            else {
                su = si1- carri;
                if(su<0){
                    su+=10;
                    carri=1;
                }
                else carri=0;
            }
            res+= System.Convert.ToString(su);
}
    //удалить последние нули
    for(i=res.Length-1;i>0;i--){
        if(res[i]=='0'){
            res=res.Remove(i,1);           
        }
        else break;//если любая другая цифра кроме 0
    }
return znak+Revers(res);
}
//------------------------------

Реверс - чтение числа-строки в обратном порядке необходим для синхронизации разрядов, начиная с младших.


Интерфейс простейшего приложения длинной арифметики

Пример на C# Visual Studio 20XX (любая).

Пользователю остается ввести без ошибок два длинных числа и щелкнуть одну из кнопок операций...

Длинная арифметика. Сложение и вычитание целых чисел
Рис.1        Интерфейс приложения

Переписать на другой язык - дело времени (не долго).

Тестирование - это наиболее важный этап в жизненном цикле программного продукта. Поэтому не верьте картинкам, фильмам и сказкам…

Только личное тестирование во всех наиболее сложных сочетаниях данных - должно убедить Вас в доброкачественности алгоритма и исходного кода!

скачать ехе-файл для тестирования



Другие примеры на тему «Длинная арифметика»

Другие примеры на языке «C#»





Если у Вас остались вопросы, то задать их Вы можете, нажав на эту кнопочку ...


исходный код на заказ. orenstudent.ru Автоматизация документов MS Office. orenstudent.ru исходный код на заказ. orenstudent.ru Помогите найти и устранить ошибку в исходном коде программы. orenstudent.ru Skype-консультирование по программированию
Скайп-консультации

Акция !!!
исходный код комментарии цена минимальная


Не попадайтесь на удочку мошенников-кидал...
Сайт помощи студентам по программированию и информатике

Program code