Рассмотрим решение задачи повышенной сложности:
«Вывести все цифры числа 5 в 555 степени».
Основная сложность заключается в сохранении всех цифр. В
Паскале существует только вторая степень, т.е. квадрат. Если степень больше
двух, то можно заменить ее произведением основания. Например, 2 в степени 5
можно вычислить так: 2*2*2*2*2. Здесь проблемы возникают ограниченность типов
целых чисел: integer –
[-32768 ...32767], longint – [-2147483648
...2147483647]. То есть, если произведение (степень) достаточно велики, то
возникнет ошибка типа.
В Паскале степень так же можно найти используя свойства
логарифмов. Так два в пятой степени запишется exp(5*ln(2)). Результат этой
операции уже имеет тип real и даже перевод этого
результата с помощью специальных функций в целое число не сохранит все цифры.
Проблему можно решить искусственно используя для хранения цифр ячейки массива.
Главное в этом правильно организовать очередное умножение. Вариант такого
решения записан в программе расположенной ниже.
program stepen_5;
uses crt;
var a:array [1..400] of integer;
i,j,k,m,n:integer;
f:boolean;
begin
clrscr;
a[1]:=1; k:=1;
for i:=1 to 555 do
begin
m:=0;
for j:=1 to k do
begin
f:=false;
n:=a[j]*5+m;
m:=0;
if n>9 then
begin
m:=n div 10;
n:=n mod 10;
f:=true;
end;
a[j]:=n;
end;
if f then
begin
k:=k+1;
a[k]:=m;
end;
end;
{wywod rezultata}
for i:=k downto 1 do
write(a[i]);
end.
Разберем решение.
В разделе описания:
Ø
указан модуль очистки экрана, т.к.
в классическом Паскале окно работы программы само не очищается. uses crt;
Ø
Описывается массив a:array [1..400] of integer;
Ø
Описываются вспомогательные
переменные, одна из которых логического типа - f:boolean;
В разделе операторов:
Ø
Очищаем окно работы программы - clrscr;
Ø
Задаем начальные значения a[1]:=1;
k:=1;, т.о. начальная цифра в массиве равна 1 (1 нейтральное число для
умножения) и количество цифр в текущем числе (k).
Ø
С помощью цикла организуем
возведение в степень путем умножения. В нашем случае это 555 степень - for i:=1
to 555 do
Ø
Память пока равна нулю m:=0;
Ø
Цикл for j:=1 to k do организует поцифренное
умножение.
Ø
Логическая переменная f:=false; будет отражать полна ли память.
Сейчас она пуста.
Ø
Умножаем очередную цифру n:=a[j]*5+m;,
добавляя к произведению число хранящееся в памяти и результат сохраняем в
переменной n.
Ø
Т.к. память в предыдущем действии
уже использовалась, обнуляем ее m:=0;
Ø
Проверяем получившийся результат
произведения очередной цифры на пять на то, что он больше 9 (т.е. состоит из
двух цифр) if n>9
then
Ø
Если это так, то первую цифру
результата убираем в память m:=n div
10;, последнюю - n:=n mod 10; сохраняем в
результате.
Ø
Т.к. память не пуста логическая
переменная изменяет свое значение на Истину f:=true;
Ø
Сохраняем результат в ячейку
массива a[j]:=n;
Ø
Если в произведении уже несколько
цифр (т.е. k>1),
они все пройдут через этот алгоритм поцифренного умножения на пять, на этом
цикл for j:=1
to k do закончит свою работу.
Ø
Если после умножения последней
цифры промежуточного числа память оказалась не пустой, об этом говорит
логическая переменная f,
она в этом случае равна Истине. if f then
– проверяет это. Тогда мы промежуточный результат увеличивает еще на одну цифру
k:=k+1; и положим туда цифру, хранящуюся в
памяти a[k]:=m;
Ø
После этого заканчивает работу
цикл возведения в степень for i:=1 to
555 do.
Ø
Все цифры конечного результата
хранятся в ячейках массива, правда в обратном порядке.
Ø
Поэтому для вывода результата используем
цикл с уменьшающимся индексом, от к (количество цифр результата) до 1. for i:=k downto 1 do
Таким же об разом можно возводить любое число в любую
степень. главное подобрать массив определенного размера. Некоторые сложности могут
возникнуть при основании большем 9. Это можно обойти задав начальное значение k не
единицей, а числом цифр в основании. Так же надо изменить процесс разделения на
цифры. Если необходимо, можно
рассмотреть в отдельной публикации эту задачу. Успехов Вам!!!
Если обнаружите ошибку, опишите ее в комментарии под
записью. Буду признателен за уточнение и с радостью ее исправлю.
Комментариев нет:
Отправить комментарий