Delphi World - это проект, являющийся сборником статей и малодокументированных возможностей  по программированию в среде Delphi. Здесь вы найдёте работы по следующим категориям: delphi, delfi, borland, bds, дельфи, делфи, дэльфи, дэлфи, programming, example, программирование, исходные коды, code, исходники, source, sources, сорцы, сорсы, soft, programs, программы, and, how, delphiworld, базы данных, графика, игры, интернет, сети, компоненты, классы, мультимедиа, ос, железо, программа, интерфейс, рабочий стол, синтаксис, технологии, файловая система...
Возведение числа в степень

Алгебра у программистов. Преподаватель пишет на доске: sin X = 1.
- Ну, кто может найти X?
Выбегает программист и так радостно:
- Вот, вот X, - показывает на X.

Это может звучать тривиально, но как мне возвести число в степень? Например, 2^12 = 4095.

На самом деле вопрос далеко не тривиальный. Проблема в том, что сам алгоритм функции далеко не прост. Функцией Power(X, N) (т.е. X^N) должны четко отслеживаться несколько возможных ситуаций:

  1. X любое число, N = 0
  2. X = 1, N любое число
  3. X = 0 и N > 0
  4. X = 0 и N < 0
  5. X > 0
  6. X < 0 и N нечетное целое
  7. X < 0 и N целое
  8. X < 0 и N нецелое

Посмотрите на следующую, абсолютно правильно работающую функцию (тем не менее она может быть и не самой эффективной!):


interface

type
  EPowerException = class(Exception)
  end;

implementation

function Power(X, N: real): extended;
var
  t: longint;
  r: real;
  isInteger: boolean;
begin
  if N = 0 then
  begin
    result := 1.0;
    exit;
  end;

  if X = 1.0 then
  begin
    result := 1.0;
    exit;
  end;

  if X = 0.0 then
  begin
    if N > 0.0 then
    begin
      result := 0.0;
      exit;
    end
    else
      raise EPowerException.Create('Результат - бесконечность');
  end;

  if (X > 0) then
  try
    result := exp(N * ln(X));
    exit;
  except
    raise
      EPowerException.Create('Результат - переполнение или потеря значимости');
  end;

  { X - отрицательный, но мы все еще можем вычислить результат, если n целое. }
  { пытаемся получить целую часть n с использованием типа longint, вычисление }
  { четности n не займет много времени }

  try
    t := trunc(n);
    if (n - t) = 0 then
      isInteger := true
    else
      isInteger := False;
  except
    { Лишний бит может вызвать переполнение или потерю значимости }
    r := int(n);
    if (n - r) = 0 then
    begin
      isInteger := true;
      if frac(r / 2) = 0.5 then
        t := 1
      else
        t := 2;
    end
    else
      isInteger := False;
  end;

  if isInteger then
  begin
    {n целое}
    if odd(t) then
      {n нечетное}
    try
      result := -exp(N * ln(-X));
      exit;
    except
      raise
        EPowerException.Create('Результат - переполнение или потеря значимости');
    end
    else
      {n четное}
    try
      result := exp(N * ln(-X));
      exit;
    except
      raise
        EPowerException.Create('Результат - переполнение или потеря значимости');
    end;
  end
  else
    raise EPowerException.Create('Результат невычисляем');
end;

Проект Delphi World © Выпуск 2002 - 2004
Автор проекта: ___Nikolay