Недавно добавленные исходники

•  TDictionary Custom Sort  514

•  Fast Watermark Sources  878

•  3D Designer  1 809

•  Sik Screen Capture  1 458

•  Patch Maker  1 466

•  Айболит (remote control)  1 390

•  ListBox Drag & Drop  1 164

•  Доска для игры Реверси  21 337

•  Графические эффекты  1 339

•  Рисование по маске  1 278

•  Перетаскивание изображений  1 091

•  Canvas Drawing  965

•  Рисование Луны  803

•  Поворот изображения  758

•  Рисование стержней  804

•  Paint on Shape  489

•  Генератор кроссвордов  750

•  Головоломка Paletto  661

•  Теорема Монжа об окружностях  842

•  Пазл Numbrix  609

•  Заборы и коммивояжеры  835

•  Игра HIP  551

•  Игра Go (Го)  523

•  Симулятор лифта  544

•  Программа укладки плитки  505

•  Генератор лабиринта  561

•  Проверка числового ввода  521

•  HEX View  596

•  Физический маятник  522

•  Задача коммивояжера  556

 
скрыть


Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



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



Алгебра у программистов. Преподаватель пишет на доске: 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;








Copyright © 2004-2022 "Delphi Sources" by BrokenByte Software. Delphi World FAQ

Группа ВКонтакте   Facebook   Ссылка на Twitter   Ссылка на Telegram