Учебная работа. Реферат: Задачи на длинную арифметику

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Загрузка...
Контрольные рефераты

Учебная работа. Реферат: Задачи на длинную арифметику

Разглядим довольно пользующуюся популярностью в программировании задачку на работу с «длинноватыми» числами. Реально с «астрономическими» либо «микроскопичными» числами приходится сталкиваться не так и нередко. Тем не наименее, упражнения, рассматриваемые в данной публикации, могут послужить неплохой тренировкой в области программирования и занять достойное пространство в классах с углубленным исследованием информатики либо на кружках по программированию. методы, выставленные ниже, записаны на Turbo Pascal, версия7.0. При желании либо необходимости они могут просто быть приспособлены к хоть какой иной программной среде.

Спектр представления целых чисел (Integer, Word, LongInt) ограничен, о чем не раз уже говорилось (вообщем, для реальных величин это замечание тоже животрепещуще). Потому при решении задач постоянно приходится действовать с оглядкой, — вроде бы не допустить появления ошибки выхода за спектр либо переполнения. к примеру, вычисляя факториал (n!=1*2*3*…*n), в спектре представления величин типа Integer получится верно получить лишь 7!=5040, а в спектре представления типа LongInt — 12!=479001600. Для огромных значений, естественно, можно употреблять действительные типы данных, но это уже не гарантирует четкого результата. Потому полезно для получения четких значений при действиях с неоднозначными числами создать остальные методы представления таковых чисел, методы выполнения арифметических и остальных операций, процедуры ввода и вывода результатов и т.д.

Покажем реализацию решения такового рода задач на примере умножения 1-го неоднозначного числа на другое. Конкретно эта арифметическая операция более нередко употребляется при решении остальных задач.

Более естественным методом представления неоднозначного числа является запись всякого его разряда в виде отдельного элемента линейного массива (либо перечня, где память под цифру будет отводиться по мере надобности, в то время как в массиве приходится заблаговременно задавать наибольшее количество частей в нем). Пусть (для удобства последующих действий) разряды «длинноватого» числа при записи в массив нумеруются с единицы, начиная с разряда единиц, т.е. цифра из разряда единиц — элемент массива с номером один, цифра из разряда 10-ов — элемент массива с номером два и т.д. Определим для работы с «длинноватыми» неотрицательными числами тип данных:

Const MNax = 2000;

Type Digit = 0..9;

DlChislo = Array[1..Nmax] Of Digit;

Для решения поставленной задачки нужно уметь делать последующие деяния:

1) ввод «длинноватого» числа;

2) фактически умножение 2-ух «длинноватых» чисел;

3) вывод «длинноватого» числа;

4) определение количества цифр в записи числа.

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

{Процедура преобразования длинноватого числа, записанного

в виде строчки, в массив цифр; переменная OK воспринимает

если в записи числа нет сторонних знаков, хороших от десятичных

цифр, по другому — false}

Procedure Translate(S : String; Var A : DlChislo; Var OK : Boolean);

Var I : Word;

Begin

Zero(A); I := Length(S); OK := True;

While (I >= 1) And OK Do

Begin

If S[I] In [‘0’..’9′]

Then A[Length(S)- I + 1]:= Ord(S[I]) — 48

Else OK := False; I := I — 1

End

End;

В процедуре вызывается подпрограмма Zero(A), предназначение которой — запись нуля в любой разряд длинноватого числа. Вот текст данной процедуры:

{Процедура обнуления длинноватого числа}

Procedure Zero(Var A : DlChislo);

Var I : Integer;

Begin

For I := 1 To NMax Do A[I] := 0;

End;

Таковым образом, длинноватое число записано в массив, где впереди (в качестве частей с большенными номерами) стоят незначащие нули. При выполнении действий и выводе ответа они не учитываются.

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

{Функция определения количества цифр в записи длинноватого числа}

Function Dlina(C : DlChislo) : Integer;

Var I : Integer;

Begin

I := NMax;

While (I > 1) And (C[I] = 0) Do I := I — 1;

Dlina := I

End;

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

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

{Процедура умножения длинноватых чисел.

A, B — множители, C — произведение}

Procedure Multiplication(A, B : DlChislo; Var C : DlChislo);

Var I, J : Integer; P : Digit; VspRez : 0..99;

Begin

Zero(C);

For I := 1 To Dlina(A) Do {Цикл по количеству цифр

в первом числе}

Begin

P := 0; {Сначало перенос равен нулю}

For J := 1 To Dlina(B) Do {Цикл по количеству цифр

во 2-м числе}

Begin

VspRez := A[I] * B[J] + P + C[I + J — 1];

C[I + J — 1] := VspRez Mod 10; {Еще одно

разряде I + J — 1}

P := VspRez Div 10 {Перенос в последующий разряд}

End;

C[I + J] := P {крайний перенос быть может отличен от нуля,

запишем его в пока ещё вольный разряд}

End

End;

на данный момент приведем листинг программки полностью.

Program DlUmn;

Const NMax = 2000;

Type Digit = 0..9; DlChislo = Array[1..Nmax] Of Digit;

Var S : String;

M, N, R, F : DlChislo;

I, MaxF : Word;

Logic : Boolean;

{Процедура обнуления длинноватого числа}

Procedure Zero(Var A : DlChislo);

Var I : Integer;

Begin

For I := 1 To NMax Do A[I] := 0;

End;

{Функция определения количества цифр в записи длинноватого числа}

Function Dlina(C : DlChislo) : Integer;

Var I : Integer;

Begin

I := NMax;

While (I > 1) And (C[I] = 0) Do I := I — 1;

Dlina := I

End;

{Процедура печати длинноватого числа}

Procedure Print(A : DlChislo);

Var I : Integer;

Begin

For I := Dlina(A) DownTo 1 Do Write(A[I] : 1);

WriteLn

End;

{Процедура преобразования длинноватого числа в массив цифр}

Procedure Translate(S : String; Var A : DlChislo;

Var OK : Boolean);

Var I : Word;

Begin

Zero(A); I := Length(S); OK := True;

While (I >= 1) And OK Do

Begin

If S[I] In [‘0’..’9′]

Then A[Length(S) — I+ 1] := Ord(S[I]) — 48

Else OK := False;

I := I — 1

End

End;

Procedure Multiplication(A, B : DlChislo; Var C : DlChislo);

Var I, J : Integer; P : Digit; VspRez : 0..99;

Begin

Zero(C);

For I := 1 To Dlina(A) Do

Begin P := 0;

For J := 1 To Dlina(B) Do

Begin

VspRez := A[I] * B[J] + P + C[I + J — 1];

C[I + J — 1] := VspRez Mod 10;

P := VspRez Div 10

End;

C[I + J] := P

End

End;

{Основная программка}

Begin

Repeat {повторяем ввод, пока число не будет введено верно}

Write(‘Введите 1-ый множитель: ‘);

ReadLn(S); Translate(S, M, Logic)

Until Logic;

Repeat

Write(‘Введите 2-ой множитель: ‘);

ReadLn(S); Translate(S, N, Logic)

Until Logic;

Multiplication(M, N, R); Print(R)

End.

В приведенном листинге Print — процедура вывода длинноватого числа. Предоставим читателю без помощи других разобраться в методе ее работы.

Вернемся к вычислению факториала. Используя разработанные подпрограммы, определим,

Вот модифицированный фрагмент главный программки, решающий поставленную задачку.

Begin

MaxF := 810;

Zero(F);

F[1] := 1;

For I := 1 To MaxF Do

Begin

Str(I, S); {преобразование числа I к строковому типу S}

Translate(S, M, Logic);

Multiplication(F, M, F);

Print(F);

WriteLn(‘Факториал числа ‘, I : 4, ‘ содержит ‘, Dlina(F), ‘ цифр.’)

End

End.

Расчеты проявили, что можно вычислять факториалы до значения 810! включительно, в записи которого 1999 цифр. Дальше вновь возникает переполнение. Расчеты по программке длятся около 5 минут (IBM PC с микропроцессором Pentium–100).

Ниже будет предложен перечень задач для самостоятельного выполнения. Из их, по воззрению создателя, самую большую сложность представляют реализации алгоритмов деления 1-го длинноватого числа на другое и извлечение квадратного корня. метод извлечения квадратного корня тщательно описан в справочнике В.А. Гусева и А.Г. Мордковича [7]. В неких вариантах составленные программки могут выступать как подпрограммы при разработке алгоритмов решения остальных, наиболее сложных (как в примере с факториалом), задач. Не считая авторских задач и задач из перечня литературы тут приведены задания из олимпиад школьников по программированию, проводившихся в Пермской области в 1989-99гг.

Задачки для самостоятельного решения

Составить программку сопоставления 2-ух неоднозначных чисел (количество символов в записи чисел наиболее20).

Составить программку, суммирующую два натуральных неоднозначных числа с количеством символов наиболее20.

Составить программку вычисления степени an, если a > MaxInt, n>10.

Составить программку вычисления числа 264 – 1, в итоге сохранить все числа.

Составить программку вычисления 100!.

Составить программку извлечения четкого квадратного корня из n-разрядного числа (n>40).

Составить программку вычисления четкого значения n!, где n > 12.

Составить программку вычисления четкого значения nn, где n > 10.

Составить программку деления числа a на число b, если a, b — неоднозначные числа.

Вычислить 100! + 2100.

Вычислить 100! – 2100.

Вычислить 7123.

Встречаются ли посреди цифр числа 211213 – 1 две попорядку идущие девятки?

Вычислить 2–200.

Составить программку нахождения личного и остатка от деления m-значного числа на n–значное (m, n > 20).

Узнать, какое из чисел am, bn больше и на сколько (a, b<=40000; m, n<=10).

Отыскать n символов в десятичной записи квадратного корня из целого числа m (n >= 50).

Отыскать количество делителей n-значного натурального числа (n > 20).

Вычислить четкое

Составить программку вычисления четкого значения суммы 1! + 2! + 3! + … + n! при n>10.

Составить программку вычисления четкого значения суммы дробей

при n > 10. Ответ должен быть представлен в виде несократимой дроби P / Q, где P, Q — натуральные числа.

Вычислить четкое

Составить программку вычисления четкого значения суммы первых n членов последовательности 1, k, k2, k3, …, kn (n > MaxInt). Указание: используйте формулу суммы n членов геометрической прогрессии.

Составить программку вычисления четкого значения суммы первых n членов последовательности чисел, кратных данному натуральному числу k (n>MaxInt). Указание: используйте формулу суммы n членов арифметической прогрессии.

Вычислить четкое

Вычислить четкое

Отыскать 1-ое обычное число, которое больше 1011.

Составить программку вычисления четкого значения многочлена anxn + an — 1xn — 1 + … + a1x + a0, где aiиx — целые числа больше 1011.

Отыскать больший общий делитель и меньшее общее кратное чисел m и n (m, n>=1011).

Проверить, являются ли числа m и n (m, n>=1011) взаимно ординарными.

Обоснуйте, что число 219936 * (219937 – 1) является совершенным, т.е. равно сумме всех собственных делителей, не считая самого себя.

«Крутящееся число». Написать программку, которая находит число, владеющее последующими качествами:

1) число оканчивается на 5;

2) при умножении его на 5 появляется новое число, которое быть может получено из начального вычеркиванием числа 5 на конце и переписыванием ее в начало числа.

33. Дана последовательность, данная рекуррентной формулой

an + 1 = 7an mod 2023, a1 = 1,

где x mod y значит остаток от деления x на y. Написать программку, вычисляющую an при 1<=n<=1000000000000000000000.

Дана последовательность

Написать программку, находящую четкое

Пример. При n = 58 получаем an = 10359022039470231387111424.

35. Напишите программку перевода неоднозначного числа (с количеством символов больше 20) в системы счисления с основанием два, восемь, шестнадцать.

36. Разложить на обыкновенные множители натуральное число с количеством символов наиболее 11.

37. Умножение повторяющейся дроби. Задана некая положительная верная повторяющаяся дробь Q и натуральное число N. Числа Q и N таковы, что количество цифр, применяемых для их описания, не превосходит 100. При изображении дроби Q повторяющаяся часть заключается в круглые скобки.

Требуется написать программку, которая описывает итог умножения Q на N, другими словами непериодическую часть и малый период числа Q*N.

В случае получения результата умножения в виде конечной дроби скобки опускаются.

Пример работы правильной программки

Введите повторяющуюся дробь: 0.1(6)

Введите натуральное число: 2

Ответ: 0.(3)

Перечень литературы

Абрамов С.А., Гнездилова Г.Г., Капустина Е.Н., Селюн М.И. задачки по программированию. М.: Наука, 1988.

Олимпиады по информатике. задачки и решения. Методические советы для учителей и учащихся школ. Красноярск, 1991.

Пильщиков В.Н. Сборник упражнений по языку Паскаль. М.: Наука, 1989.

Касаткин В.Н. информация. Методы. ЭВМ . М.: Просвещение, 1991.

Хонсбергер Р. Математические изюминки. М.: Наука, 1992.

Семакин И.Г., Шестаков А.П. Лекции по программированию. Пермь: изд-во ПГУ, 1998.

Гусев В.А., Мордкович А.Г. Математика. Справочные материалы. М.: Просвещение, 1990.

Гладков В.П. Курс лабораторных работ по программированию. Пермь: изд-во ПГТУ, 1998.

Шестаков А.П. задачки на длинноватую математику/

]]>