在不使用求幂运算符的情况下在 Extended Pascal 中实现 x^(e)

Implement x^(e) in Extended Pascal, without using exponentiation operators

我正在构建的 Pascal ISO 10206 程序的一部分,要求我实现一个函数来将实数 (x) 取幂为欧拉数 (e),而不使用 Pascal 中已经包含的任何取幂函数(**, pow,exp...).

几个小时以来我一直在尝试不同的算法,但我无法弄清楚如何在不使用已经包含的求幂函数的情况下做到这一点。

如有任何帮助,我们将不胜感激。任何某种数学算法等...在此先感谢。

正如其他人所说,使用 Exp() 或基于它的函数没有意义 而不是 。但是如果你真的必须使用其他东西,并且不想得到太多technical/mathematical,那么下面应该可以工作(真正的算法要复杂得多,需要更多数学知识)。

该程序将泰勒级数的前 N ​​项用于 X 的小数部分和二进制求幂 X 的整数部分的组合。它可能不是很快,但相当准确,即使对于较大的指数也是如此。为了比较,我还显示了Exp(X)。如果您的 Pascal 有 DoubleExtended 类型,请使用它们代替 Real.

program SimplePower;

{ Required for Delphi, you can omit it in other Pascals: }
{$APPTYPE CONSOLE}

{ Returns approximate value of e^X using sum of first N terms of Taylor series.
  Works fine with X values between 0 and 1.0 and N ~ 30. }
function Exponential(N: Integer; X: Real): Real;
var
  I: Integer;
begin
  Result := 1.0;
  for I := N - 1 downto 1 do
    Result := 1.0 + X * Result / I;
end;

{ Binary exponentiation of Base by integer Exponent. }
function IntegerExp(Base: Real; Exponent: Integer): Real;
begin
  Result := 1.0;
  while Exponent > 0 do
  begin
    if Odd(Exponent) then
      Result := Result * Base;
    Base := Base * Base;
    Exponent := Exponent shr 1;
  end;
end;

{ Combines IntegerExp function for integral part with 
  Exponential function for fractional part. }
function MyExp(N: Integer; X: Real): Real;
const
  E = 2.7182818284590452353602874713527; { from Google: "e euler" }
var
  Factor: Real;
  Fraction: Real;
begin
  Fraction := Exponential(N, Frac(X));
  Factor := IntegerExp(E, Trunc(X));
  Result := Factor * Fraction;
end;

{ Simple demo: }
const
  N = 30;
  X = 73.4567890242421234;

begin
  Writeln('MyExp(', N, ', ', X:22:18, ') = ', MyExp(N, X):22:18);
  Writeln('Exp(', X:22:18, ')       = ', Exp(X):22:18);
end.

参考:

我没有为负指数做任何事情,但只知道Exp(-x) = 1/Exp(x)。您可以根据这些知识修改 MyExp

我在其他 post 中使用了@RudyVelthuis 指出的解决方案,但对其进行了一些修改。它基于 x^0.5 = sqrt(x),我们可以利用它来发挥我们的优势。我会留下我使用的 Pascal ISO 10206 代码。谢谢大家的帮助,特别是 Rudy。

function MyPow(base,power,precision:real):real;
begin
    if (power<0) then MyPow:=1/MyPow(base,-power,precision)
    else   if (power>=10) then MyPow:=sqr(MyPow(base,power/2,precision/2))
    else   if (power>=1) then MyPow:=base*MyPow(base,power-1,precision)
    else   if (precision>=1) then MyPow:=sqrt(base)
    else MyPow:=sqrt(MyPow(base,power*2,precision*2));
end;