adolfken
发表于 2011-11-2 11:18:52
只有仰望的份了
董堃
发表于 2011-11-2 16:42:04
仰望啊!唉!脖子都痛了!
cabinsummer
发表于 2011-11-3 00:44:54
本帖最后由 cabinsummer 于 2011-11-3 21:31 编辑
先分析一下。32位的电脑整形数范围为-2^31——(2^31-1),即-2147483648到2147483647。超过这个范围的数值计算,必须分段进行。同样精度数值的计算,分段越少,计算次数也越少,因此每段包含的位数要尽可能的多。
以麦钦公式为例,可以考虑八位一组的分段,因九位一组的分段在计算乘法时可能会超出最大整数范围,导致难以察觉的错误。99999999x16=1599999984<2147483647;而999999999x4=3999999996>2147483647。
同样的分析,上述各反正切计算法能达到的最大分段分别如下:
赫顿公式最大分段8位
麦钦公式最大分段8位
维加公式最大分段8位
欧拉-维加公式最大分段8位
克拉森公式最大分段8位
高斯两个公式最大分段分别是8和7位
卢瑟福公式最大分段8位
达泽公式最大分段8位
山克斯公式最大分段7位
斯特姆公式最大分段7位
肖鲁兹公式最大分段8位
布塞卡公式最大分段7位
艾斯克托公式最大分段7位
mmh1
发表于 2011-11-3 16:32:39
本帖最后由 mmh1 于 2011-11-3 16:33 编辑
(setq a 1 s 1 b 1)
(repeat 10
(setq a (+ a 2))
(setq b (* b -1))
(setq s (+ s (* (/ 1 a) b)))
)
(setq d (* 4 s))
输出结果为4,汗
重在参与
birdsky
发表于 2011-11-3 17:13:16
仰望中……
cabinsummer
发表于 2011-11-3 19:43:47
mmh1 发表于 2011-11-3 16:32 static/image/common/back.gif
(setq a 1 s 1 b 1)
(repeat 10
(setq a (+ a 2))
如果第一行改为(setq a 1.0 s 1.0 b 1.0)
输出结果为3.23232
如果再将重复次数改为100
输出结果为3.15149
如果再将重复次数改为1000
输出结果为3.14259
如果再将重复次数改为81000
输出结果为3.1416
效果出来了,但收敛速度太慢,而且精度也不高
鼓励继续
logoin
发表于 2011-11-3 20:13:10
数学太神奇了~~
cabinsummer
发表于 2011-11-3 21:05:26
本帖最后由 cabinsummer 于 2011-11-13 07:13 编辑
继续提供思路。
定义有d个数值且为0的表
(defun ZeroList(d / a)
(repeat d
(setq a (append a (list 0)))
)
a
)
两表相加
(defun AddList(xlist ylist / a b c)
(setq a (mapcar '+ xlist ylist))
(setq b (append (cdr (mapcar '(lambda(x)(/ x 1000000)) a))(list 0)))
(setq c (mapcar '(lambda(x)(rem x 1000000)) a))
(mapcar '+ b c)
)
两表相减
(defun MinusList(xlist ylist / n a tt tag)
(setq n (1- (length xlist)) a nil tag 0)
(repeat (length xlist)
(setq tt (- (nth n xlist)(nth n ylist) tag))
(if (< tt 0)
(progn
(setq tt (+ tt 1000000))
(setq tag 1)
)
(setq tag 0)
)
(setq a (cons tt a))
(setq n (1- n))
)
a
)
表乘以常数d并整理
(defun Multi(xlist d / a b c)
(setq a (mapcar '(lambda(x)(* d x)) xlist))
(setq b (append (cdr (mapcar '(lambda(x)(/ x 1000000)) a))(list 0)))
(setq c (mapcar '(lambda(x)(rem x 1000000)) a))
(mapcar '+ b c)
)
表除以常数d并整理
(defun Divide(xlist d / n v r g a)
(setq n 0 r 0 a nil)
(repeat (length xlist)
(setq v (+ (nth n xlist) (* r 1000000)))
(setq g (/ v d))
(setq r (rem v d))
(setq a (append a (list g)))
(setq n (1+ n))
)
a
)
精度d位u倒数并整理
(defun ReverseNumber(u d / n v r g a)
(setq xlist (zerolist d))
(setq n 0 r 1)
(repeat d
(setq v (+ (nth n xlist) (* r 1000000)))
(setq g (/ v u))
(setq r (rem v u))
(setq a (append a (list g)))
(setq n (1+ n))
)
a
)
表中数值输出为连接的长字符串,注意LISP只能处理4096个以下的字符,如果计算位数过长,必须改用其它输出方式。
(defun ToString(xlist / a b n fn)
(setq a "\npi=" n 0)
(setq fn (open "c:\\pi.txt" "w"))
(princ a fn)
(repeat (1- (length xlist))
(setq b (itoa (nth n xlist)))
(setq a (strcat (substr "00000" (strlen b)) b " ") n (1+ n))
(princ a fn)
)
(close fn)
(princ)
)
hhh454
发表于 2011-11-4 16:02:40
顶起来,学习的好材料,不过太难了,我先学点简单的吧!!
cabinsummer
发表于 2011-11-4 19:25:30
本帖最后由 cabinsummer 于 2011-11-4 19:26 编辑
继续提供思路
反正切函数的级数表达