Россия, Москва, МИЭМ |
Опубликован: 21.03.2012 | Уровень: для всех | Доступ: платный
Лекция 4:
Задачи "Операции со сверхбольшими числами"
const mm=100; var a,b, sum: array [1..mm] of byte; i, n, m,max, x, k: integer; strokaA, strokaB: string; begin writeln ('первое слагаемое'); readln (strokaA); writeln ('второе слагаемое'); readln (strokaB); n:= length (strokaA); m:= length (strokaB); if n>m then max:=n else max:=m; for i:=1 to n do begin val(copy(strokaA, i, 1),x,k); a[i+(max-n)]:=x; end; for i:=1 to m do begin val(copy(strokaB, i, 1),x,k); b[i+(max-m)]:=x; end; {======суммирование===========} for i:=1 to max do sum[i]:= a[i]+b[i]; for i:=max downto 2 do begin sum[i-1]:=sum[i-1] + sum[i] div 10; sum[i]:= sum[i] mod 10; end; {====вывод результата===========} for i:=1 to max do write (sum[i]); end.
Тест:
Задача Найти произведение двух сверхбольших чисел.
Идею решения иллюстрирует схема (рис. 3.3):
- возьмем последний элемент массива В; умножаем его на все элементы массива А. Результат храним в массиве Rez;
- суммируем два массива - Sum и сдвинутые на 1 позицию влево элементы массива Rez; Результат заносим в Sum;
- берем следующий элемент массива В (находящийся левее); повторяем с шага 2;
- выводим на экран содержимое массива Sum.
input "первое слагаемое"; a$ input "второе слагаемое"; b$ n = len(a$) m = len(b$) dim a(n), b(m), rez(n), sum(n + m) rem======разбор на цифры============ for i = 1 to n a(i) = val(mid$(a$, i, 1)) next for i = 1 to m b(i) = val(mid$(b$, i, 1)) next rem==произведение на j-ую цифру========= for j = m to 1 step -1 for i = 1 to n rez(i) = a(i) * b(j) next for i = n to 2 step -1 rez(i - 1) = rez(i - 1) + rez(i) \ 10 rez(i) = rez(i) mod 10 next rem====сумма со сдвигом========== for i = 1 to n sum(i + j - 1) = sum(i + j - 1) + rez(i) next for i = n to 2 step -1 sum(i - 1) = sum(i - 1) + sum(i) \ 10 sum(i) = sum(i) mod 10 next next rem====вывод результата============== for i = 1 to n + m - 1 print sum(i); next
const mm=100; var a,b, rez,sum: array [1..mm] of byte; i, j, n, m, max, x, k: integer; strokaA, strokaB: string; begin writeln ( 'первый сомножитель'); readln (strokaA); writeln ( 'второй сомножитель'); readln (strokaB); n:= length(strokaA); m:= length(strokaB); {======разбор на цифры===============} for i:= 1 to n do begin val(copy(strokaA, i, 1),x,k); a[i]:= x; end; for i:= 1 to m do begin val(copy(strokaB, i, 1),x,k); b[i]:= x; end; {==произведение на j-ую цифру============} for j:= m downto 1 do begin for i:= 1 to n do rez[i]:= a[i] * b[j]; for i:= n downto 2 do begin rez[i - 1]:= rez[i - 1] + rez[i] div 10; rez[i]:= rez[i] mod 10; end; {====сумма со сдвигом==============} for i:= 1 to n do sum[i + j - 1]:= sum[i + j - 1] + rez[i]; for i:= n downto 2 do begin sum[i - 1]:= sum[i - 1] + sum[i] div 10; sum[i]:= sum[i] mod 10; end; end; {====вывод результата=================} for i:= 1 to n + m - 1 do write (sum[i]); end.
Тест:
Ключевые термины
- "Сверхбольшое число" - число, величина которого выходит за пределы диапазона допустимых значений выделенной для хранения числа ячейки памяти.
Краткие итоги
Операции со "сверхбольшими" числами выполняются по алгоритму:
- число вводится в строковую переменную.
- строка "разбирается на символы, каждый символ помещается в элемент массива, затем переводится в число.
- дальнейшие действия выполняются "поразрядно": умножение каждого элемента на другое число, организация переноса переполнения в старший разряд перенос.
- аналогично (поразрядно) выполняется операция суммирования двух "сверхбольших" чисел.
Набор для практики
Вопросы.
- Каким образом можно ввести с клавиатуры в переменную число, значение которого превышает 2147483647?
- Каким образом можно удвоить введенное с клавиатуры число, значение которого превышает 2147483647?
Упражнения.
- Вычислить NK, (N и K>10).
- Вычислить N! (N-факториал) - произведение чисел натурального ряда до N включительно.