飞诗(fsxm) 发表于 2007-7-23 22:02:00

本帖最后由 作者 于 2007-7-23 22:04:58 编辑 <br /><br /> <p>呵呵~我只是写了一个处理有优化级的函数一个例子~</p><p>sin之类的没有优化级别更好处理~</p><p>只要提前将sin(XXX)用字符处理成(sin XX)就行了~用不到表处理`!</p><p>字符替代 "sin(" -&gt; "(sin"</p>

狂刀无痕 发表于 2007-7-24 15:07:00

本帖最后由 作者 于 2007-7-24 20:20:14 编辑 <br /><br /> <p>;| xcal = 计算字符串表达式------- by lxx.2007.7.22<br/>格式: (xcal 运算过程式 返回值表达式)<br/>返回: 实数 (可用rtos提取)<br/>命令: xxcal<br/>实例:<br/>(xcal "" "1e+2*5^3*exp(5.31)" )<br/>-&gt; 2.52938e+006<br/>(xcal "a=1e+2*5^3*exp(5.31):" "a" )<br/>-&gt;2.52938e+006<br/>(rtos (xcal "a=1e+2*5^3*exp(5.31):" "a" ) 2 10)<br/>-&gt; "2529377.854851844"<br/>(xcal "a=3 : for i = 1 to 100000 : a=a+i+5^3*exp(5.31) : b=a^2*sin(a) : c=sqr(a)*b : next :" "c" )<br/>-&gt; 1.59322e+021&nbsp; ;;返回 c值,10万次计算,1~2秒<br/>版本:<br/>v1.0 2007.7.22<br/>|;</p><p>&nbsp;命令行方式演示,重复运算100万次, &lt;1秒得结果.</p><p></p><p>其实计算不是lisp的强项。用c系列语言,甚至vb都快得多。上面的方法是在lisp中调用vb计算。C我不懂,肯定能更快。大家继续。。。</p><p>&nbsp;</p>

飞诗(fsxm) 发表于 2007-7-24 20:46:00

本帖最后由 作者 于 2007-7-24 20:46:58 编辑 <br /><br /> <p></p><p>;;;分离出变量与函数<br/>(defun format1 (str / char funs lastfun lst tmp lastchar)<br/>&nbsp; (setq funs '("+" "-" "*" "/" "^" "%" "(" ")" " "))<br/>&nbsp; (setq tmp "")<br/>&nbsp; (while (/= str "")<br/>&nbsp;&nbsp;&nbsp; (setq char (substr str 1 1))<br/>&nbsp;&nbsp;&nbsp; (setq str (substr str 2))<br/>&nbsp;&nbsp;&nbsp; (if&nbsp;(and (member char funs)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;;负号特别处理<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (not (and lastfun (/= lastfun ")") (= char "-")))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;;"e"科学计数法特别处理<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (not (and lastchar (or (= char "-") (= char "+"))))<br/>&nbsp;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setq lst&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (vl-list* char tmp lst)<br/>&nbsp;&nbsp;&nbsp;&nbsp; tmp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ""<br/>&nbsp;&nbsp;&nbsp;&nbsp; lastfun&nbsp; char<br/>&nbsp;&nbsp;&nbsp;&nbsp; lastchar nil<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setq tmp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (strcat tmp char)<br/>&nbsp;&nbsp;&nbsp;&nbsp; lastfun&nbsp; nil<br/>&nbsp;&nbsp;&nbsp;&nbsp; lastchar (if (= (strcase char) "E") t)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/>&nbsp;&nbsp;&nbsp; )<br/>&nbsp; )<br/>&nbsp; (vl-remove "" (vl-remove " " (reverse (cons tmp lst))))<br/>)<br/>;;;处理简单无优先级别函数运算<br/>(defun format1_1 (lst funs / fun lasta nlst tmp)<br/>&nbsp; (foreach a lst<br/>&nbsp;&nbsp;&nbsp; (cond<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((setq tmp (assoc (strcase a) funs))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setq fun (cadr tmp))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((and (= a "(") fun)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setq nlst (vl-list* fun "(" nlst))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setq fun nil)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((and (= a "(")<br/>&nbsp;&nbsp;&nbsp;&nbsp; (not (member lasta '(nil "+" "-" "*" "/" "^" "%" "(" ")")))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setq nlst (vl-list* lasta "(" (cdr nlst)))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (t (setq nlst (cons a nlst)))<br/>&nbsp;&nbsp;&nbsp; )<br/>&nbsp;&nbsp;&nbsp; (setq lasta a)<br/>&nbsp; )<br/>&nbsp; (reverse nlst)<br/>)<br/>;;;带return的apply<br/>(defun Fsxm-Apply ($Sym $Lst / $$ return $rt)<br/>&nbsp; (defun Return (var) (setq Return nil) (setq $$ var) (exit))<br/>&nbsp; (setq $rt (vl-catch-all-apply $Sym $Lst))<br/>&nbsp; (if Return $rt $$)<br/>)<br/>;;递归处理括号<br/>(defun format2 (lst / a i lst2 nlst tmp var)<br/>&nbsp; (setq i 0)<br/>&nbsp; (while lst<br/>&nbsp;&nbsp;&nbsp; (setq a (car lst))<br/>&nbsp;&nbsp;&nbsp; (setq lst (cdr lst))<br/>&nbsp;&nbsp;&nbsp; (setq i (1+ i))<br/>&nbsp;&nbsp;&nbsp; (cond ((= a "(")<br/>&nbsp;&nbsp;&nbsp; (setq var (fsxm-apply 'format2 (list lst)))<br/>&nbsp;&nbsp;&nbsp; (repeat (car var) (setq lst (cdr lst)))<br/>&nbsp;&nbsp;&nbsp; (setq i (+ i (car var)))<br/>&nbsp;&nbsp;&nbsp; (setq nlst (cons (cadr var) nlst))<br/>&nbsp;&nbsp;&nbsp; (setq tmp (cons (cadr var) tmp))<br/>&nbsp;&nbsp; )<br/>&nbsp;&nbsp; ((= a ")")<br/>&nbsp;&nbsp;&nbsp; (return (list i (reverse tmp)))<br/>&nbsp;&nbsp; )<br/>&nbsp;&nbsp; (t<br/>&nbsp;&nbsp;&nbsp; (setq tmp (cons a tmp))<br/>&nbsp;&nbsp;&nbsp; (setq nlst (cons a nlst))<br/>&nbsp;&nbsp; )<br/>&nbsp;&nbsp;&nbsp; )<br/>&nbsp; )<br/>&nbsp; (reverse nlst)<br/>)<br/>;;递归转化计算式格式<br/>(defun format3 (lst funs / lasta nlst tmp fun)<br/>&nbsp; (foreach a lst<br/>&nbsp;&nbsp;&nbsp; (cond ((setq fun (assoc a funs))<br/>&nbsp;&nbsp;&nbsp; (setq tmp (list lasta (cadr fun)))<br/>&nbsp;&nbsp; )<br/>&nbsp;&nbsp; (t<br/>&nbsp;&nbsp;&nbsp; (if (listp a)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setq a (format3 a funs))<br/>&nbsp;&nbsp;&nbsp; )<br/>&nbsp;&nbsp;&nbsp; (if tmp<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setq lasta (reverse (cons a tmp))<br/>&nbsp;&nbsp;&nbsp;&nbsp; nlst&nbsp; (cons lasta (cdr nlst))<br/>&nbsp;&nbsp;&nbsp;&nbsp; tmp&nbsp; nil<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (setq lasta a<br/>&nbsp;&nbsp;&nbsp;&nbsp; nlst&nbsp; (cons lasta nlst)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/>&nbsp;&nbsp;&nbsp; )<br/>&nbsp;&nbsp; )<br/>&nbsp;&nbsp;&nbsp; )<br/>&nbsp; )<br/>&nbsp; (reverse nlst)<br/>)<br/>;;递归处理掉多余的括号,<br/>;;常量str-&gt;浮点数real 变量str-&gt;符号sym<br/>(defun format4 (lst)<br/>&nbsp; (mapcar '(lambda (a / x)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (cond ((listp a)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (if&nbsp;(listp (car a))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (format4 (car a))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (format4 a)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/>&nbsp;&nbsp;&nbsp;&nbsp; )<br/>&nbsp;&nbsp;&nbsp;&nbsp; ((= (type a) 'str)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (or&nbsp;(setq x (distof a))<br/>&nbsp;&nbsp;&nbsp;(setq x (read a))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x<br/>&nbsp;&nbsp;&nbsp;&nbsp; )<br/>&nbsp;&nbsp;&nbsp;&nbsp; (t a)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<br/>&nbsp;&nbsp;&nbsp; )<br/>&nbsp;&nbsp; lst<br/>&nbsp; )<br/>)<br/>(defun trans_format (str / lst)<br/>&nbsp; ;;预处理 去空字符&amp;转括号<br/>&nbsp; (setq str (vl-string-translate "{[]}\t\n," "(())&nbsp;&nbsp; " str))<br/>&nbsp; ;;分离出变量与函数<br/>&nbsp; (setq lst (format1 str))<br/>&nbsp; ;;处理无优先级别函数运算<br/>&nbsp; (setq lst (format1_1 lst '(("COS" cos2) ("SIN" sin2) ("TAN" tan2))))<br/>&nbsp; ;;递归处理括号<br/>&nbsp; (setq lst (format2 lst))<br/>&nbsp; ;;优先计算&nbsp; 开方<br/>&nbsp; (setq lst (format3 lst '(("^" expt))))<br/>&nbsp; ;;再次计算&nbsp; 乘 除 取模<br/>&nbsp; (setq lst (format3 lst '(("*" *) ("/" /) ("%" rem))))<br/>&nbsp; ;;最后计算 加减<br/>&nbsp; (setq lst (format3 lst '(("+" +) ("-" -))))<br/>&nbsp; ;;后处理<br/>&nbsp; (car (format4 lst))<br/>)</p><p>(defun sin2 (d)<br/>&nbsp; (sin (* d (/ pi 180)))<br/>)<br/>(defun cos2 (d)<br/>&nbsp; (cos (* d (/ pi 180)))<br/>)<br/>(defun tan2 (d)<br/>&nbsp; (setq d (* d (/ pi 180)))<br/>&nbsp; (/ (sin d) (cos d))<br/>)<br/>;;====================功能测试1:====================<br/>(setq str1 (strcat "(1/(cos(-2)*-3)+"<br/>&nbsp;&nbsp;&nbsp; "min(22,abs(-5),0.5,8)"<br/>&nbsp;&nbsp;&nbsp; "*(2-5))/3^(sin(pi/5)+2)-1e+2*5"<br/>&nbsp;&nbsp; )<br/>)<br/>(eval (trans_format str1))&nbsp;&nbsp;;-&gt; -500.201<br/>(eval (trans_format "min(22 , abs(-5) , 0.5 , 8)")) ;-&gt; 0.5<br/>;;因min(22,abs(-5),0.5,8) -&gt; 0.5 现在用cal验证结果<br/>(setq str2 "(1/(cos(-2)*-3)+0.5*(2-5))/3^(sin(pi/5)+2)-1e+2*5")<br/>(c:cal str2)&nbsp;&nbsp;&nbsp;&nbsp;;-&gt; -500.201</p><p>;;功能测试通过</p><p><br/>;;====================效率测试====================<br/>;;计时子函数<br/>(defun time0 () (setq t0 (getvar "TDUSRTIMER")))<br/>(defun time1 ()<br/>&nbsp; (princ "用时:")<br/>&nbsp; (princ (* (- (getvar "TDUSRTIMER") t0) 86400))<br/>&nbsp; (princ "(S)")<br/>&nbsp; (princ)<br/>)<br/>(setq str "(1/(cos(-2)*-3)+0.5*(2-5))/3^(sin(pi/5)+2)-1e+2*5")<br/>(defun c:t1 (/ t0)&nbsp;&nbsp;&nbsp;;用CAL对比<br/>&nbsp; (time0)<br/>&nbsp; (repeat 5000 (cal str))<br/>&nbsp; (time1)<br/>)<br/>(defun c:t2 (/ t0)&nbsp;&nbsp;&nbsp;;多次eval+多次trans_format(比cal慢)<br/>&nbsp; (time0)<br/>&nbsp; (repeat 5000 (eval (trans_format str)))<br/>&nbsp; (time1)<br/>)<br/>(defun c:t3 (/ t0)&nbsp;&nbsp;&nbsp;;多次eval+1次trans_format(与cal差不多)<br/>&nbsp; (time0)<br/>&nbsp; (setq trans_lst (trans_format str))<br/>&nbsp; (repeat 5000 (eval trans_lst))<br/>&nbsp; (time1)<br/>)<br/>(defun c:t4 (/ t0 test)&nbsp;&nbsp;&nbsp;;1次eval+1次trans_format(比cal快)<br/>&nbsp; (time0)<br/>&nbsp; (eval (list 'defun 'test nil (trans_format str)))<br/>&nbsp; (repeat 5000 (test))<br/>&nbsp; (time1)<br/>)</p><p>后语:<br/>事实上基于字符解释与表处理的trans_format<br/><font color="#3809f7">它的单次运算效率是不如cal的,约比cal慢20倍</font><br/>但是因为它的最终解释结果为lisp表达式,<br/><font color="#0909f7">在很多次运算"解释结果"时,运算效率将比cal快10倍以上</font><br/><font color="#ff0033">它开放式的程式构架,赋予了很多cal函数所没有功能.比如:<br/>trans_format可以运算"自定义函数"也可以运算"变量",还可以自定义"运算子"的优先级别</font><br/>-----fsxm2007.07.23~2007.07.24</p><p>希望以上程序代码能对各位有点帮助!</p>

highflybir 发表于 2007-7-25 09:33:00

本帖最后由 作者 于 2007-7-25 10:51:34 编辑

看来飞诗已经研究出来了,佩服佩服!
先下载下来学习学习。
建议,函数不应局限于lisp中的有限几个,可以扩展一些。
感觉速度上应该还可以提高。
关于为什么要转换,请大家看下面的例子:就是平方运算:

;;;平方表达式的lisp运算和cal运算。
(defun C:test(/ cal-express lisp-express)
(arxload "Geomcal.arx")
(setq cal-express "x^2")
;;假设我已经准确地翻译"X^2"成如下函数
(setq lisp-express (read "(* x x)"))
;;则
(eval
    (list 'defun 'lisp-sqr (list 'x)
      lisp-express
    )
)
(defun cal-sqr (x)
    (cal cal-express)
)
;;lisp
(time0)
(setq i 0)
(repeat 10000
    (lisp-sqr i)
    (setq i (1+ i))
)
(time1)
;;cal
(time0)
(setq i 0)
(repeat 10000
    (cal-sqr i)
    (setq i (1+ i))
)
(time1)
)

实际结果发现对于是一个变量的表达式子,如果经lisp翻译后(假设这种翻译是完全准确而且不冗余的)的运算速度可能要比cal快100倍以上。这还是没有经过编译的。

;;计时子函数
(defun time0 () (setq t0 (getvar "TDUSRTIMER")))
(defun time1 ()
(princ "用时:")
(princ (* (- (getvar "TDUSRTIMER") t0) 86400))
(princ "秒")
(princ)
)

狂刀无痕 发表于 2007-7-25 14:41:00

本帖最后由 作者 于 2007-7-25 15:09:20 编辑

要说表处理和cad更容易结合,我没话说.但是说比cal快那我得说点不同意见.
cal也是arx(c系列语言)编写的.怎么可能慢.
上面的测试本来就是个错误.为什么这么说.单就计算本身(比如1次运算),cal快是没画说.但是为什么多次运算又慢了呢?根本不是计算的效率问题.而是程序的结构问题.是lisp把它拖慢的.因为没计算一次,数据传给计算函数计算,结果传回lisp,慢就慢在传出传入上.是错误的应用方法.发挥不了优势. 要慢也不是因为cal慢.
就是说,如果用cal或其它用vb,vc等编写的函数或模块来进行大量运算,应该把要计算的条件一次传入,计算(包括多次循环)完了,再一次性把结果传回lisp.
因此,对简单的计算.用lisp或其它都无所谓,时间感觉不出来.
要进行大量运算.就放手让外部计算程序计算.一次出结果.不要把时间花在lisp的数据转换上面.;;;平方表达式的lisp运算和cal运算。
(defun C:test (/ cal-express lisp-express)
(arxload "Geomcal.arx")
(setq cal-express "x^2")
(setq lisp-express (read "(* x x)"))
(defun cal-sqr (x)
    (cal cal-express)
)
(eval (list 'defun'lisp-sqr(list 'x)lisp-express ))
(time0)
(setq i 0)
(repeat 10000
    (setq end (cal-sqr i))
    (setq i (1+ i))
)
(time1)
(print (rtos end 2 8))
(princ)
)
;;; 对比测试:
(defun c:xx ()
(setq n(getdist "\n 输入运算次数:"))
(time0)
(setq end
(xcal (strcat "a=0 : for i = 1 to "
      (itoa (fix n))
      " : a=i^2 : next :") "a" ));; 可在12楼下载本函数
(time1)
(print (rtos end 2 8))
(princ)
)

测试结果:命令: test
用时:11.984秒
"99980001.00000002"
命令:
命令: xx
输入运算次数:10000
用时:0.016秒
"100000000.0000000"
命令:
命令: xx
输入运算次数:1000000
用时:1.656秒
"1000000000000.000"
命令:
命令:
XX
输入运算次数:8000000
用时:11.609秒
"64000000000000.00"


也就是说,用xcal函数(调用了vba) 800万次运算和用lisp1万次运算用时相当.而且越到后面每次运算时间需要更多, 因为是 (* x x)
如果都是1万次运算.11.984秒 秒和0.016秒有多大差别,不用说了吧....
另外,test的测试结果有误差(几次测试都是),可能是浮点运算造成,楼上可再检查一下

highflybir 发表于 2007-7-25 17:05:00

回楼上的,我觉得应该这样做比较:
(注意是:lisp-sqr,而不是cal-sqr)

;;;平方表达式的lisp运算和cal运算。
(defun C:test (/ i lisp-express)
(setq n(getreal "\n 输入运算次数:"))
(setq lisp-express (read "(* x x)"))
(eval
    (list 'defun
   'lisp-sqr
   (list 'x)
   lisp-express
    )
)
(time0)
(setq i 0.0)
(repeat (fix n)
    (setq end1 (lisp-sqr i))
    (setq i (1+ i))
)
(time1)
(print (rtos end1 2 8))
(princ)
)
;;; 对比测试:(
(defun c:xx ()
(setq n(getreal "\n 输入运算次数:"))
(time0)
(setq end1
(xcal (strcat "a=0 : for i = 1 to "
         (itoa (fix n))
         " : a=i^2 : next :"
      )
      "a"
)
)
;; 可在12楼下载本函数
(time1)
(print (rtos end1 2 8))
(princ)
)
;;计时子函数
(defun time0 () (setq t0 (getvar "TDUSRTIMER")))
(defun time1 ()
(princ "\n用时:")
(princ (* (- (getvar "TDUSRTIMER") t0) 86400))
(princ "秒")
(princ)
)

把这个程序编译成vlx后发现两者在1000000次以内基本打平。不信大家去测试.


highflybir 发表于 2007-7-25 17:20:00

<p>下面是一个一亿次的运算测试:</p><p>命令:<br/>命令: test<br/>&nbsp;输入运算次数:100000000</p><p>用时:86.203秒<br/>"9999999800000001"</p><p>命令:<br/>命令: xx<br/>&nbsp;输入运算次数:100000000</p><p>用时:59.093秒<br/>"1.00000000E+16"</p><p>可见在亿次上才可能看见差别。然而这个差别不大,不是数量级的差别。</p><p>至于为什么后面返回的结果不同,也许大家能猜得到。<br/></p>

狂刀无痕 发表于 2007-7-25 20:27:00

本帖最后由 作者 于 2007-7-25 20:32:35 编辑 <br /><br /> <p>不得不说,编译我vlx后lisp的速度确优化了不少.因为vlx被编译为一种介lisp和机器码之间的编码,所以速度提高.</p><p>虽然不是数量级的差别,但是也不会基本打平拉 (我的电脑cpu是 amd3200 内存512兆),另外,连10次运算,在100内都有19的的误差,不知道哪个敢用.</p><p>TEST<br/>&nbsp;输入运算次数:10</p><p>用时:0.0秒<br/>"81.00000000"</p><p>命令:<br/>命令: xx</p><p>&nbsp;输入运算次数:10</p><p>用时:0.0秒<br/>"100.00000000"</p><p>命令: test<br/>&nbsp;输入运算次数:1e4<br/>用时:0.031秒<br/>"99980001.00000000"<br/>命令: xx<br/>&nbsp;输入运算次数:1e4<br/>用时:0.016秒<br/>"100000000.0000000"<br/>命令:<br/>命令: test<br/>&nbsp;输入运算次数:1e6<br/>用时:3.563秒<br/>"999998000001.0001"<br/>命令:<br/>命令: xx<br/>&nbsp;输入运算次数:1e6<br/>用时:1.297秒<br/>"1000000000000.000"<br/>命令:<br/>命令: test<br/>&nbsp;输入运算次数:1e6<br/>用时:3.672秒<br/>"999998000001.0001"<br/>命令:<br/>命令: xx<br/>&nbsp;输入运算次数:1e6<br/>用时:1.578秒<br/>"1000000000000.000"<br/>命令:<br/>命令: test<br/>&nbsp;输入运算次数:1e7<br/>用时:36.5秒<br/>"99999980000001.00"<br/>命令:<br/>命令: xx<br/>&nbsp;输入运算次数:1e7<br/>用时:13.984秒<br/>"100000000000000.0"</p><p>命令: test</p><p>&nbsp;输入运算次数:1e8</p><p>用时:433.89秒<br/>"9999999800000001"</p><p>命令:<br/>XX<br/>&nbsp;输入运算次数:1e8</p><p>用时:160.031秒<br/>"1.00000000E+16"</p>

飞诗(fsxm) 发表于 2007-7-25 21:11:00

本帖最后由 作者 于 2007-7-25 22:07:54 编辑 <br /><br /> <p>我们不要只是简单的说运行的快慢~</p><p>效率是在实际应用上体现出来的! 如果没有用的"快"远不如有用的"慢"</p><p>现在给一个应用例子:</p><p>y = x^3+x*x+5x+cos(x+pi/5)+0.5</p><p>现在用CAD画这个方程线: 取值0&lt;=X&lt;=100 步进为1e-4</p><p>用trans_format运算一次 转化为lisp表达式计算,</p><p>只要给出不同的x就可以算出对应的y,</p><p>cal/vbs呵呵你总不可以"a=* : for i = 1 to 10000...."来计算吧!</p><p>就是一个变量就足以说明与实际应用结合之后的效率问题,</p><p><font color="#ff0033">不管你有多快~如果不能用"变量"快了也没用! 用了"变量"后,这下看你还快不快!!</font></p><p>如果没有一个"变量"计算多次的结果还是一样的,去计算N次也就没有意义了哦!</p><p></p><p><font face="宋体" size="3"><strong><font face="Verdana" color="#da2549">highflybir:</font></strong></font><font face="宋体" size="3">建议,函数不应局限于lisp中的有限几个,可以扩展一些。</font></p><p><font face="宋体" size="3">回: 谢谢提议,不过现在程序就是可以运算自定义函数的啊!</font></p><p><font face="宋体" size="3"></font></p><p><font face="宋体" size="3">来个简明的:</font></p><p><font face="宋体" size="3">(defun test (a b)<br/>&nbsp; (+ (* a b) (/ a b))<br/>)</font></p><p><font face="宋体" size="3">_$ (eval (trans_format "test(5,6)"))<br/>30.8333</font></p><p><font face="宋体" size="3"></font></p>

highflybir 发表于 2007-7-26 09:47:00

狂刀无痕发表于2007-7-25 20:27:00static/image/common/back.gif不得不说,编译我vlx后lisp的速度确优化了不少.因为vlx被编译为一种介lisp和机器码之间的编码,所以速度提高.虽然不是数量级的差别,但是也不会基本打平拉 (我的电脑cpu是 amd3200 内存512兆),另外

<p></p><p>对于1百万次的运算才相差一秒,我认为这个结果是可以接受的。而且用lisp语言就能完成这个功能,而不用其他语言,所以我认为fxsm的程序是有效的。</p><p>至于你说的误差,我想也许你可能没弄清楚lisp的递增加法和vb的不同之处。-这并不是lisp的计算出现失误,相反我认为是正确的,你得出的最后结果反而是错误的。</p><p>因为我们知道:计算机计数是从0开始,假设要重复运算10次,那么实际上第10次平方应该是9X9=81,而不是10X10=100,</p><p>这就是为什么在10次以内存在19的差距。lisp是先求值后计数器加1。(当然你也可以改变这流程)</p><p>在我的电脑上是持平的,也许电脑可能有差别,我的电脑是1G内存,3.0G intel pentium D。不同的cpu对浮点运算是有区别的。</p>
页: 1 [2] 3
查看完整版本: 求各路高手帮小弟学一个计算式程序