Возведение числа в степень
|
На самом деле вопрос далеко не тривиальный. Проблема в том, что сам алгоритм функции далеко не прост. Функцией Power(X, N) (т.е. X^N) должны четко отслеживаться несколько возможных ситуаций: - X любое число, N = 0
- X = 1, N любое число
- X = 0 и N > 0
- X = 0 и N < 0
- X > 0
- X < 0 и N нечетное целое
- X < 0 и N целое
- 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; |