以下是我在Haskell中实施的计算机程序结构和解释练习1-45的尝试解决方案:
fixedpoint :: (Double->Double) -> Double -> Double -> Double
fixedpoint f guess err
| err > abs next-guess = next
| otherwise = fixedpoint f next err
where next = f guess
avg :: Double -> Double -> Double
avg a b = (a+b)/2
avgdamp :: (Double -> Double) -> (Double -> Double)
avgdamp f = \ x -> avg x (f x)
log2 :: Double -> Double
log2 = (/ log 2) . log
repeated :: (a->a) -> Int -> (a->a)
repeated f n = \ x -> (iterate f x) !! n
nthroot :: Int -> Double -> Double -> Double
nthroot n x err = fixedpoint (repeated avgdamp numdampsneeded $ eqn) 1.0 err where
numdampsneeded = floor $ log2 $ fromIntegral n -- experimentally determined
eqn = \ y -> x/y^(n-1)
我逐一测试了帮助程序,看起来很好。我查看了3个博客,其中发布了哪些解决方案,我的似乎与它们相对应,有一些小的例外,如实现语言,我使用显式错误参数。
尽管如此,我从nthroot得到了可笑的结果,我没有线索。
> nthroot 2 16 0.000000001
5.1911764705882355
> nthroot 3 8 0.000001
2.447530864197531
> nthroot 3 27 0.001
7.0688775510204085
> nthroot 5 32 0.001
6.563864764681383
或者在这种情况下,我期望像八度音阶那样回归(近似)[0..16]
> [0:16].^(1/2).^2
ans =
0.00000 1.00000 2.00000 3.00000 4.00000 5.00000 6.00000 7.00000 8.00000 9.00000 10.00000 11.00000 12.00000 13.00000 14.00000 15.00000 16.00000
但
> map (^2) $ map (\x -> nthroot 2 x 0.000001) [0..16]
[0.25,1.0,2.006944444444444,3.0625,4.2025,5.4444444444444455,6.79719387755102,8.265625,9.852623456790123,11.559999999999999,13.388946280991735,15.340277777777777,17.41457100591716,19.612244897959187,21.933611111111112,24.37890625,26.94831314878893]
对这些糟糕结果背后可能出现的任何猜测都是值得欢迎的。
答案 0 :(得分:3)
函数应用程序比任何中缀运算符都更紧密。因此,
abs next - guess == (abs next) - guess
这不是你想要的。如果您解决了这个问题,那么您的算法运行正常。