我在这里有一个简单的lisp程序,它计算在单位间隔上随机选择的两个点之间的平均长度的近似值。如果我运行这个程序,我会得到一个有理数16666671666667/50000000000000,但是当我(天真地)尝试将有理数格式化为20位时,一些精度就被丢弃了0.33333343000000000000。我认为,在幕后,SBCL在格式化有理数之前将其转换为浮点数,但我真的不确定如何判断。我只是在使用表达式(format t "~20$~%" (scale-all-line-contributions 10000000 1)。有没有办法将有理数转换为小数记数法,同时保持尽可能高的精度?我知道格式系统是强大和可扩展的,但我很难找到专门与有理数相关的文档。
为了完整起见,下面是代码,因为它不是很长。
(defun number-of-pairs (n i)
"get the number of pairs with distance x
for non-zero distances we have to consider two cases"
(cond
((= i 0) n)
((> i 0) (* 2 (- n i)))
((> i n) 0)))
(defun line-contribution (n i power)
"get the number of segments of length i in a line of n segments and their weight combined"
(let
((number-of-pairs (number-of-pairs n i))
(weight-of-pair (expt i power)))
(* number-of-pairs weight-of-pair)))
(defun all-line-contributions (n power)
"get the line contributions for reach [0 .. n]"
(loop for i from 1 upto (- n 1) summing (line-contribution n i power)))
(defun normalized-all-line-contributions (n power)
"normalize line contributions by number of pairs"
(let ((pair-count (expt n 2)))
(/ (all-line-contributions n power) pair-count)))
(defun scale-all-line-contributions (n power)
"scale the line contributions by the distance n
this will guarantee convergence"
(/ (normalized-all-line-contributions n power) (expt n power)))
(print (scale-all-line-contributions 10000000 1))
(format t "~20$~%" (scale-all-line-contributions 10000000 1))编辑:修复代码中的逻辑错误。新的有理数,浮点数对为33333333333333/100000000000000 0.33333334000000000000
https://stackoverflow.com/questions/38217904
复制相似问题