見出し画像

Retro-gaming and so on

ネイピア数


まず、用語の整理から。
高階関数と言うのは「関数を引数に取る関数」あるいは「関数を返り値とする関数」を指す。
長い間、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)

  • Xでシェアする
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

最近の「プログラミング」カテゴリーもっと見る

最近の記事
バックナンバー
人気記事