我正在使用DrRacket编写我的编程类。我认为使用简化的语法。
练习是以给定的精度计算给定数字的第n个根。
这个程序工作正常,但如果它尝试使用它与243的第5个根(即3),程序太慢,无法计算它。但是,如果叠加(improve 1 5 243)
函数,它就可以工作。但如果我将它堆叠的频率超过7次,那么程序执行时间会太长。
有什么问题?
这是程序:(它使用牛顿算法)
(check-within (nth-root 3 125 0.001) 5 0.001)
(check-within (nth-root 2 625 0.01) 25 0.01)
(check-within (nth-root 3 64 0.001) 4 0.001)
(: nth-root (natural natural real -> real))
(define nth-root
(lambda (n x eps) (root-iter 1 1 n x eps)))
(: root-iter (real real natural natural real -> real))
(define root-iter
(lambda (current last n x eps)
(if (good-enough? current n x eps)
current
(root-iter (improve last n x) current n x eps))))
(: improve (real natural natural -> real))
(define improve
(lambda (last n x)
(* (/ 1 n)
(+ (/ x
(expt last (- n 1)))
(* (- n 1)
last)))))
(: good-enough? (real natural natural real -> boolean))
(define good-enough?
(lambda (current n x eps)
(< (abs (- (expt current n) x)) eps)))
答案 0 :(得分:0)
几乎可以肯定你在这里使用精确算术。在这种特殊情况下,这将是昂贵的,因为你的数学将是有理数的;你的分子和分母将会变得巨大。进入不精确的算术,你应该看到一个重大的性能改进(以精度为代价,请注意)。
如果你正在处理确切的数字,那么球拍(和一般的方案)会给你精确的算术。事实证明,你从迭代到迭代改进猜测的方式都使用了确切的数字! :P
要确认此效果,请尝试:(nth-root 5 243.0 0.001)
。比较vs (nth-root 5 243 0.001)
,您应该看到计算答案所需的时间差异很大。
这就是为什么你会在Scheme中看到像exact->inexact
这样的函数。为什么你会在你的计算机中看到浮点(不精确)算术:你会遇到让柏拉图式答案非常昂贵的情况,对于许多应用程序,你可以容忍不精确的行为。
(虽然没有融资。当你处理钱财时,不要使用不准确的数字,否则你会让某人非常非常不开心。)