Опубликован: 21.03.2012 | Доступ: свободный | Студентов: 2958 / 225 | Оценка: 4.44 / 4.19 | Длительность: 06:43:00
Специальности: Программист
Лекция 4:

Задачи "Операции со сверхбольшими числами"

< Лекция 3 || Лекция 4: 12 || Лекция 5 >

Программа на Паскале:

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.

Тест:

Дано:

236754569081

937501

Результат: 236755506582

Задача Найти произведение двух сверхбольших чисел.

Идею решения иллюстрирует схема (рис. 3.3):


Рис. 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.

Тест:

Дано:

123456789

1234567

Результат: 1524156752330241363

Ключевые термины

  • "Сверхбольшое число" - число, величина которого выходит за пределы диапазона допустимых значений выделенной для хранения числа ячейки памяти.

Краткие итоги

Операции со "сверхбольшими" числами выполняются по алгоритму:

  • число вводится в строковую переменную.
  • строка "разбирается на символы, каждый символ помещается в элемент массива, затем переводится в число.
  • дальнейшие действия выполняются "поразрядно": умножение каждого элемента на другое число, организация переноса переполнения в старший разряд перенос.
  • аналогично (поразрядно) выполняется операция суммирования двух "сверхбольших" чисел.

Набор для практики

Вопросы.

  • Каким образом можно ввести с клавиатуры в переменную число, значение которого превышает 2147483647?
  • Каким образом можно удвоить введенное с клавиатуры число, значение которого превышает 2147483647?

Упражнения.

  • Вычислить NK, (N и K>10).
  • Вычислить N! (N-факториал) - произведение чисел натурального ряда до N включительно.
< Лекция 3 || Лекция 4: 12 || Лекция 5 >