まず、用語の整理から。
高階関数と言うのは「関数を引数に取る関数」あるいは「関数を返り値とする関数」を指す。
長い間、Visual Basicは高階関数を扱えなかったが、どうやら最近は扱えるようになったらしい。・・・参照記事は2010年のモノなんで最近、って程でもねぇか(笑)。いずれにせよ、VB.netで、Higher_order_Functionっちゅうモジュールを導入すればいいのか。
まぁ、僕はLinux使ってるんで、VB使えないから確かめようがないんですけども。いずれにせよ、件の記事によると一応VBでも高階関数は扱えるらしい、と。
ここではisamさんが扱えるPythonで、ネイピア数の実装例を列挙しようと思う。
1つのお題でも複数の実装法をやってみる、ってのは割に良い練習になる筈だと思う。多分。
なお、例によって、階乗計算はPythonのmath.factorialに頼った(なんか今見たら、3.9から非推奨機能になってやがる・笑)。
また、せっかくあるんで、Pythonで分数を扱えるfractions.Fractionを用いてる。
従来のプログラミング言語では分数が扱えなかったので、浮動小数点数の「誤差」がルーピングに従って大きくなっていく問題があったが、分数を使えば不正確数に変換するのは返り値を返す際の「最後の一回」だけで済む。
そういう便利な機能は使わない道理はない。
from math import factorial
from functools import reduce
from fractions import Fraction
# for で書く
def napier1(n):
acc = 0
for i in range(n + 1):
acc += Fraction(1, factorial(i))
return float(acc)
print("-----napier1-----")
for i in range(1, 20):
print(napier1(i))
# while で書く
def napier2(n):
i = 0
acc = 0
while True:
if i > n:
return float(acc)
acc += Fraction(1, factorial(i))
i += 1
print("-----napier2-----")
for i in range(1, 20):
print(napier2(i))
# リスト内包表記で書く
def napier3(n):
return float(sum([Fraction(1, factorial(i)) for i in range(n+1)]))
print("-----napier3-----")
for i in range(1, 20):
print(napier3(i))
# 高階関数 map で書く
def napier4(n):
return float(sum(map(lambda x: Fraction(1, factorial(x)), range(n+1))))
print("-----napier4-----")
for i in range(1, 20):
print(napier4(i))
# 高階関数 reduce で書く
def napier5(n):
return float(reduce(lambda ini, x: ini + Fraction(1, factorial(x)), \
range(n+1), 0))
print("-----napier5-----")
for i in range(1, 20):
print(napier5(i))
# ジェネレータで書く
def napier6(i, n):
count = i
acc = i
while count < n:
acc += Fraction(1, factorial(count))
yield float(acc)
count += 1
print("-----napier6-----")
for i in napier6(1, 20):
print(i)
# イテレータで書く
class napier7:
def __init__(self, i, n):
self.count = i - 1
self.acc = i
self.n = n
def __iter__(self):
return self
def __next__(self):
self.count += 1
if self.count == self.n:
raise StopIteration
self.acc += Fraction(1, factorial(self.count))
return float(self.acc)
print("-----napier7-----")
for i in napier7(1, 20):
print(i)