Согласие на обработку персональных данных.



04.09.2017
Новая задача Программа вычисления суммы.

03.09.2017
Новое видео Стековый калькулятор и обратная польская запись.

26.08.2017
Новая статья Версии Делфи.

23.08.2017
Новая статья Для кого пишется программа.

13.08.2017
Новая статья Стандарт C++: общие сведения.

Раздел: Стандартные функции Паскаля

Функция Power

Как стать программистом 2.0 Как стать программистом 2.0

Эта книга для тех, кто хочет стать программистом. На самом деле хочет, а не просто мечтает. И хочет именно стать программистом с большой буквы, а не просто научиться кулебякать какие-то примитивные программки… Подробнее...

Функция Power в Паскале (и многих других языках программирования) выполняет возведение числа в степень.

Синтаксис для вещественных чисел:

function Power(Base: Double; Expon: Double) : Double;

Синтаксис для целых чисел:

function Power(Base: LongInt; Expon: LongInt) : LongInt;

Эта функция возводит число Base в степень Expon и возвращает результат. В реальности функция возвращает результат выражения:

Exp(Expon * Ln(Base))

ВАЖНО!

Всё, что сказано выше, взято из официальной документации FreePascal. Однако документация иногда расходится с действительностью. Во всяком случае, мой компилятор не соответствует документации. А именно:
  • В документации сказано, что функция объявлена в модуле SYSTEM. Однако без подключения модуля MATH компилятор выдаёт ошибку. Из этого следует, что на самом деле функция объявлена в модуле MATH.
  • В документации приведён синтаксис как для целых, так и для вещественных чисел. Однако на самом деле функция работает только с вещественными числами. При попытке использовать целые числа компилятор также выдаёт ошибку.
  • Возможно, в более новых версиях эти проблемы уже исправлены. Но у меня было именно так (версия FPC 3.0.0).

Пример использования функции Power

Пример приведён ниже:

program funcpower;

uses Math;        

var x, y, z : single;

begin
  x := 2;
  y := 3;
  z := Power(x, y);   //Z = X в степени Y
  WriteLn(z:0:2);  

  ReadLn;
end.

Здесь мы число 2 (переменная Х) возводим в степень 3 (переменная Y), то есть вычисляем следующую формулу:

Z = XY

Обратите внимание на подключенный модуль MATH.

Эта статья входит в раздел о подпрограммах модуля SYSTEM. И по идее описания функции Power здесь не должно быть. Но, так как в документации сказано, что функция Power объявлена в модуле SYSTEM, я решил включить данную статью именно в этот раздел (я же не виноват, что в документации косяк))).

Возведение в степень в Паскале

Возведение в степень в Паскале можно выполнить и без какой-то специальной функции, используя функцию вычисления натурального логарифма и функцию вычисления экспоненты. О том, как это сделать, я рассказал здесь.

Однако, если есть специальная функция для возведения числа в степень, то почему бы ей и не воспользоваться? С одной стороны. С другой стороны - эта функция совершенно неожиданно требует подключения модуля MATH.

В документации сказано, что по сути функция Power работает по формуле возведения в степень в Паскале:

Exp(Expon * Ln(Base))

Однако, если мы будем делать именно так, эта формула будет неправильно работать с отрицательными числами, потому что в документации сказано, что функция Ln работает только с положительными числами.

Так что функция Power в реальности несколько сложнее, чем приведённая выше формула.

Поэтому для разминки мы напишем свой аналог функции Power, который будет работать правильно. Но для начала вспомним как вычисляется степень числа:

Возведение в степень

Также напомню, что любое число в нулевой степени равно 1, а ноль в любой степени равен 0 (кроме нуля в нулевой - ноль в нулевой степени не определён, но мы будем возвращать в таких случаях ноль, хотя функция Power возвращает 1).

А теперь наш аналог функции Power:

function AVPower(Base: Double; Expon: Double) : Double;
var m     : byte;
    i     : integer;
    Res   : Double;
begin
  m := 0;
  if Expon < 0 then m := 1              //Отрицательная степень
  else if Expon = 0 then m := 2         //Нулевая степень
       else m := 3;                     //Положительная степень
  if Base < 0 then m := 10 + m          //Отрицательное число
  else if Base = 0 then m := 20 + m     //Число равно 0
       else m := 30 + m;                //Положительное число
  case m of
  11  :   //Отрицательное число, отрицательная степень
    begin //Если Expon - не целое число, то получаются комплексные числа
      Res := 1 / Exp(Abs(Expon) * Ln(Abs(Base)));
      i := Round(Expon);
      if Odd(i) then Res := -1 * Res;
    end;
  12, 32  :   //Нулевая степень
    Res := 1;
  13  :   //Отрицательное число, положительная степень
    begin //Если Expon - не целое число, то получаются комплексные числа
      Res := Exp(Expon * Ln(Abs(Base)));
      i := Round(Expon);
      if Odd(i) then Res := -1 * Res;
    end;
  21..23  :   //Число равно нулю
    Res := 0;
  31  :       //Положительное число, отрицательная степень
    Res := 1 / Exp(Abs(Expon) * Ln(Base));
  33  :       //Положительное число, положительная степень
    Res := Exp(Expon * Ln(Base));
  end;     

  AVPower := Res;
end;

Я сознательно немного всё усложнил, чтобы вас запутать )))

Пример использования функций Power и её аналога в программе:

x := 2;
y := 3;
z := Power(x, y);     //Z = X в степени Y
WriteLn(z:0:2); 

z := AVPower(x, y);   //Z = X в степени Y
WriteLn(z:0:2);

Здесь есть один подвох - если вы попытаетесь возвести отрицательное число в не целую степень, например, так:

-23,5

то стандартная функция Power вызовет ошибку во время выполнения программы. В своём аналоге я этого избежал, но надо понимать, что результат в этом случае будет неправильным (хотя с моей точки зрения это всё-равно лучше, чем аварийное завершение программы).

Это происходит потому, что при таком раскладе результатом являются комплексные числа, а операции с комплексными числами выполняются по другим правилам.

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

Ещё в моей функции используется функция Odd, о которой я ещё не рассказывал. Вкратце скажу, что она определяет, является ли число чётным. Более подробно о ней расскажу в отдельной статье.


Директивы компилятора Директивы компилятора
Как это ни странно, но даже многие опытные программисты не используют директивы компилятора, считая их чем-то ненужным и бесполезным. А между тем, директивы компилятора - это очень классная штука. Если их умело применять в своих программах, то можно существенно сократить время на разработку и уменьшить количество рутинных операций. Подробнее...
Инфо-МАСТЕР ®
Все права защищены ©
e-mail: mail@info-master.su

Яндекс.Метрика