计算哈斯克尔的窦

Paj*_*kec 1 c++ haskell

这是我的问题:我需要一个计算某些数字的窦的函数......

在C++中我写了这个:

double msin(double number, int counter = 0, double sum = 0)
{
    // sin(x) = x - (x'3 / 3!) + (x'5 / 5!) - (x'7 / 7!) + (x'9 / 9!)
    if (counter <= 20)
    {
        if (counter % 2 == 0)
            sum += mpow(number, counter * 2 + 1) / mfak(counter * 2 + 1) ;
        else
            sum -= mpow(number, counter * 2 + 1) / mfak(counter * 2 + 1) ;

        counter++;
        sum =  msin(number, counter, sum);

        return sum;
    }

    return (sum* 180.0 / _PI);
}
Run Code Online (Sandbox Code Playgroud)

现在我正在尝试在Haskell中做到这一点,我不知道如何...现在我正在尝试这样的事情(它确实没有用,但正在进行中;)):

这有效:

mfak number = if number < 2
                    then 1
                    else number *( mfak (number -1 )) 


mpow number potenca = if potenca == 0
                        then 0
                        else if potenca == 1
                        then 1
                        else (number * (mpow number (potenca-1)))
Run Code Online (Sandbox Code Playgroud)

这不起作用:

msin :: Double -> Int -> Double -> Double                           
msin number counter sum = if counter <= 20
                                    then if counter `mod` 2==0
                                            then let sum = sum + (msin 1 (let counter = counter+1 in counter) sum) in sum 
                                            else let sum = sum + (msin 1 (let counter = counter+1 in counter) sum) in sum                                   
                                    else sum* 180.0 / 3.14
Run Code Online (Sandbox Code Playgroud)

更新....不编译:/"无法匹配预期类型Double' with actual typeInt'"

msin :: Double -> Int -> Double -> Double                           
msin number counter sum = if counter <= 20
                                    then if counter `mod` 2==0
                                            then let sum' = sum + ((mpow number (counter*2+1))/(mfak counter*2+1)) in msin number (counter+1) sum'
                                            else let sum' = sum - ((mpow number (counter*2+1))/(mfak counter*2+1)) in msin number (counter+1) sum'                              
                                    else sum* 180.0 / 3.14
Run Code Online (Sandbox Code Playgroud)

你可以看到最大的问题是如何添加"sum",增加"counter"并再次使用这个新值进行递归...

PS我是Haskell的新手,所以尽可能多地尝试解决你的解决方案.我正在阅读一些教程,但是我找不到如何将某些表达式的结果保存到一个值中然后继续使用其他代码...它只是在每次我尝试这样做时返回我的值,而我不要那样......

所以tnxx提前提供任何帮助!

Tom*_*lis 5

问题是表达式let stevec = stevec+1 in stevec.Haskell不是一种命令式语言.这不会添加一个stevec.相反,它定义stevec为比自身多一个的数字.没有这样的数字,因此你会得到一个无限循环,或者,如果你幸运的话,你会崩溃.

代替

stevec++;
vsota =  msin(stevilo, stevec, vsota);
Run Code Online (Sandbox Code Playgroud)

你应该使用类似的东西

let stevec' = stevec + 1
in  msin stevilo stevec' vsota
Run Code Online (Sandbox Code Playgroud)

要不就

msin stevilo (stevec + 1) vsota
Run Code Online (Sandbox Code Playgroud)

(这里还有一些我不明白的东西.你需要mpowmfak.他们在哪里?)


chi*_*chi 5

我会稍微修改一下算法。首先我们可以定义阶乘逆的列表:

factorialInv :: [Double]
factorialInv = scanl (/) 1 [1..]  -- 1/0! , 1/1! , 1/2! , 1/3! , ...
Run Code Online (Sandbox Code Playgroud)

然后,我们遵循正弦系数:

sineCoefficients :: [Double]
sineCoefficients = 0 : 1 : 0 : -1 : sineCoefficients
Run Code Online (Sandbox Code Playgroud)

然后,给定x,我们将上述两个列表与 的幂相乘x,逐点:

powerSeries :: [Double]   -- ^ Coefficients
            -> Double     -- ^ Point x on which to compute the series
            -> [Double]   -- ^ Series terms
powerSeries cs x = zipWith3 (\a b c -> a * b * c) cs powers factorialInv
   where powers = iterate (*x) 1   -- 1 , x , x^2 , x^3 , ...
Run Code Online (Sandbox Code Playgroud)

最后,我们取前 20 项并总结它们。

sine :: Double -> Double                   
sine = sum . take 20 . powerSeries sineCoefficients
 -- i.e., sine x = sum (take 20 (powerSeries sineCoefficients x))
Run Code Online (Sandbox Code Playgroud)