マクローリン展開によるsin関数
30分プログラム、その622。http://gauc.no-ip.org/awk-users-jp/blis.cgi/DoukakuAWK_188にインスパイアされて、sin関数を書いてみます。
『マクローリン展開をそのまま実装すればいいんだろ、簡単簡単』と思ってら、わりと時間がかかってしまった。IntじゃなくてIntegerを使うべきなのに気がつくのに時間がかかったからなぁ。
使い方
*Main> mySin 0 0.0 *Main> mySin (pi/2) 0.9999999999939768
ソースコード
import Data.List fact :: Integer -> Integer f :: Floating a => Integer -> a -> a fact n = product [1..n] f n x = (numer / denom) * x' where float n = fromInteger $ toInteger n numer = (-1) ** (float n) denom = float $ fact $ 2 * n + 1 x' = x ** (float $ 2 * n + 1) sinStream x = scanl1 (+) [f n x | n <- [0..]] mySin x = let xs = sinStream x in case find (\(current,prev)-> abs (current - prev) < 1e-8) $ zip (tail xs) xs of Nothing -> error "must not happen" Just (x,_) -> x