Поиск по этому блогу

четверг, 6 апреля 2017 г.

Пять в пятьсот пятьдесят пятой степени

Рассмотрим решение задачи повышенной сложности:
«Вывести все цифры числа 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 не единицей, а числом цифр в основании. Так же надо изменить процесс разделения на цифры. Если необходимо,  можно рассмотреть в отдельной публикации эту задачу. Успехов Вам!!!

Если обнаружите ошибку, опишите ее в комментарии под записью. Буду признателен за уточнение и с радостью ее исправлю.

Комментариев нет:

Отправить комментарий