2015-06-01 63 views
4

我想估計e^x使用冪級數在Haskell近似。我如何錯誤地計算e^x?

import Data.Function 

-- Take two integers and divide them and return a float as a result. 
-- So 1/2 would be 0.5 
fd :: Int -> Int -> Double 
fd = (/) `on` fromIntegral 

-- Helper function to compute factorial 
fact :: Int -> Int 
fact 1 = 1 
fact n = n * fact (n-1) 

-- Calculate e^x using the power series for e^x (n is the number of 
-- of terms used to approximate e^x 
computeHelper :: Double -> Int -> Double -> Double 
computeHelper x 0 res = res + 1 
computeHelper x n res = computeHelper x (n-1) (res + (x**n `fd` (fact n))) 

compute :: Double -> Int -> Double 
compute x n = computeHelper x n 0.0 

調用compute 1 56。這是不正確的。

fdfact都顯示工作正常。因此,我猜這個問題與computeHelper。然而,隨着在Python相同的邏輯:

from math import factorial 

def compute(x, n, res=0): 
    if n == 0: 
     return res + 1 
    return compute(x, n-1, res + (x**n*1.0/(factorial(n)))) 

print compute(1, 5) 

我得到2.71666666667這是不如預期,所以我很困惑,爲什麼Haskell的版本無法正常工作。

+1

在適當類型時不會泄漏空間的階乘單線程(與您的實現不同)是'fact n = product [1..n]'。然而,有更快的多行定義。 – dfeuer

+0

你也應該定義你的階乘爲0. 0!= 1。 –

回答

7

它是一個運算符優先級問題。 fd的優先級高於**。如果您添加額外的括號其清晰的,爲什麼你得到一個6:

(x**(n `fd` (fact n))) 

的方式來解決這一問題將是把括號圍繞冪再調整的事情了一點,所以他們進行類型檢查:

((x^n)/(fromIntegral (fact n)))