自然数eを底とする指数関数。

指数関数は級数展開で求めることができる。x<0 である時は、級数展開の各項に正負が交互に現れるため桁落ちが生じる。そこで、指数関数の逆数を計算することによりx>0の計算に直す。 収束を早めるため、x=t+k*ln(x), -ln(x)/2<x<ln(x)/2 となるtとkを求め、Exp(x)=Exp(t)*2^kとする。

このほかに、連分数を使って求める方法もある。

ActiveBasicでは級数展開を用いたアルゴリズムでExp関数が用意されている。

#N88BASIC

Const LOG2 = 0.6931471805599453094172321214581765680755 'log_e(2)

Function lldexp(x As Double, k As Integer) As Double
Dim w As Double

If k >= 0 Then
w = 2
Else
w = 0.5
k = -k
End If
While k
If k And 1 Then x = x * w
w = w * w
k = k >> 1
Wend
lldexp = x
End Function

Function lexp1(x As Double) As Double ' 級数展開にて求める
Dim i As Integer, k As Integer, neg As Integer
Dim a As Double, e As Double, prev As Double

If x >= 0 Then
k = x / LOG2 + 0.5 ' またはFix(x / LOG2 + 0.5)
Else
k = x / LOG2 - 0.5 ' またはFix(x / LOG2 - 0.5)
End If
x = x - k * LOG2
' 級数展開
If x >= 0 Then
neg = 0
Else
neg = 1
x = -x
End If
e = 1 + x
a = x
i = 2
Do
prev = e
a = a * x / i
e = e + a
i = i + 1
Loop While e <> prev
If neg Then e = 1 / e
lexp1 = lldexp(e, k)
End Function

Const N = 22' 本文参照 (6, 10, 14, 18, 22, 26, ...)
Function lexp(x As Double) As Double ' 連分数展開にて求める
Dim i As Integer, k As Integer
Dim x2 As Double, w As Double

If x >= 0 Then
k = x / LOG2 + 0.5 ' またはFix(x / LOG2 + 0.5)
Else
k = x / LOG2 - 0.5 ' またはFix(x / LOG2 - 0.5)
End If
x = x - k * LOG2
'連分数展開
x2 = x * x
w = x2 / N
For i = N - 4 To 6 Step -4
w = x2 / (w + i)
Next i
lexp = lldexp((2 + w + x) / (2 + w - x), k)
End Function

'
Dim i As Integer
Dim x As Double

For i = -10 To 10
x = i / 4.0
Print "exp("; x; Ex"* log(2))\t"; lexp1(LOG2 * x); lexp(LOG2 * x), Exp(LOG2 * x)
Next i

タグ:

+ タグ編集
  • タグ:

このサイトはreCAPTCHAによって保護されており、Googleの プライバシーポリシー利用規約 が適用されます。

最終更新:2010年01月25日 19:15