nt8011 发表于 2018-10-16 19:56:24

求教:cal计算大整数时错误

调用cal函数计算时,碰到大整数时计算错误。 cal 的bug: 整数必须介于 -32768 和 32767 之间。
请问各位大侠,怎么解决?谢谢!

Bao_lai 发表于 2018-10-21 12:55:09

本帖最后由 Bao_lai 于 2018-10-21 13:13 编辑

(defun C:CALCU (/ ss ssl i e str el nstr p p1 ll l)
    ;(if (not (member "GEOMCAL.ARX" (MAPCAR ' strcase (arx)))) ;无用代码出错
    ;      (arxload "geomcal.arx")
    ;)
   
    (setq csd (getint "\n请指定计算结果小数位精度:<2>"))
    (if (= csd nil)
      (setq csd 2)
    )
    (if (and (setq ss (ssget '((0 . "TEXT,TCH_TEXT"))))
             (setq p (getpoint "\n请输入标注点位置: "))
      )
    (progn
      (setq ssl(sslength ss)
            i    -1
      )
      (command "cal")(command) ;先调用command函数,避免后面计算失败。
      (repeat ssl
            (setq el   (entget (ssname ss (setq i (1+ i))))
                  str(strcat "1.0*" (cdr (assoc 1 el))) ;调整型为实数,除Bug。
                  l    (caadr (textbox (list (assoc 1 el) (assoc 40 el))))
                  ll   (+ l (* 4. (/ l (strlen (cdr (assoc 1 el))))))
            ;nstr (rtos (c:cal str) 2 csd)
            )
            (setq nstr (rtos (c:cal str) 2 csd));把这个单独拿出来了
            (setq el (subst (cons 10 p) (assoc 10 el) el))
            (entmake el) ;写计算式
            (setq el (subst (cons 1 nstr) (assoc 1 el) el)
                  p1 (mapcar '+ (list ll 0. 0.) p)
                  el (subst (cons 10 p1) (assoc 10 el) el)
            )
            (entmake el);写结果
            (setq p (mapcar '+ p (list 0. (- (* 1.5 (cdr (assoc 40 el)))) 0.))) ;计算下一个插入点
      
      )
      )
    )
    (princ)
)

nt8011 发表于 2018-10-18 18:52:38

(defun CALCU (/ ss ssl i e str el nstr p p1 ll l)
   (if (not (member "GEOMCAL.ARX" (MAPCAR 'strcase (arx))))
    (arxload "geomcal.arx")
)
   (if (= csd nil)
       (setq csd 2))
   (if (and (setq ss (ssget '((0 . "TEXT,TCH_TEXT"))))
           (setq p (getpoint "\n请输入标注点位置: "))
      )
    (progn
      (setq ssl        (sslength ss)
          i        -1
      )
      (repeat ssl
        (setq el   (entget (ssname ss (setq i (1+ i))))
              str(cdr (assoc 1 el))
              l           (caadr (textbox (list (assoc 1 el) (assoc 40 el))))
              ll   (+ l (* 4. (/ l (strlen (cdr (assoc 1 el))))))
              nstr (rtos (c:cal str) 2 csd)
        )
        (setq el (subst (cons 10 p) (assoc 10 el) el))
        (entmake el)
        (setq el (subst (cons 1 nstr) (assoc 1 el) el)
              p1 (mapcar '+
                       (list ll 0. 0.)
                       p
               )
              el (subst (cons 10 p1) (assoc 10 el) el)
        )
        (entmake el)
        (setq
          p (mapcar '+ p (list 0. (- (* 1.5 (cdr (assoc 40 el)))) 0.))
        )
      )
    )
)
(princ)
)

Bao_lai 发表于 2018-10-17 23:06:20

(defun c:ca()
   (SETVAR "CMDECHO" 0)       
   (setq en1 (entsel "\n请选择表达式: \n"))
   (setq en1_data (entget (car en1)))
   (setq text1 (cdr (assoc 1 en1_data)))

       ;感觉调用都不会出错(*@ο@*) 哇~
   (princ (strcat "\n" text1 "="))
       ;(princ (strcat "\n" text1 "*1.0="))

   (command "cal" text1 )
   (SETVAR "CMDECHO" 1) (PRINC)
)

nt8011 发表于 2018-10-17 15:33:34

例如:53450+11850+9470 计算的结果为9234;
而直接用CAL命令计算的结果77470正确

lisperado 发表于 2018-10-17 16:28:25

本帖最后由 lisperado 于 2018-10-17 16:38 编辑

我也一样,整数限制正负16位元
(Cal "53450+11850+9470")
9234

实数就行
(Cal "53450.+11850.+9470.")
74770

干嘛不用Lisp函数 ‘+’?(+ 53450 11850 9470)
74770


nt8011 发表于 2018-10-17 16:41:18

lisperado 发表于 2018-10-17 16:28
我也一样,只限16位元整数
(Cal "53450+11850+9470")
9234


确实对于如计算式 “53450+11850+9470" 改为 “53450.0+11850+9470" 则计算正确。
是否有不改计算式,通过程序解决的办法?

lisperado 发表于 2018-10-17 17:02:04

nt8011 发表于 2018-10-17 16:41
确实对于如计算式 “53450+11850+9470" 改为 “53450.0+11850+9470" 则计算正确。
是否有不改计算式,通 ...

只是不解为何一定要用CAL呢?

nt8011 发表于 2018-10-17 17:16:03

CAL方便用于各种不同的计算式

960322 发表于 2018-10-17 22:14:48

我只有笨办法,将算式字符串拆分成计算数和运算符,对所有不带.的计算数字符串全部加.0,也就是把所有的计算数变成实数就可以了

Bao_lai 发表于 2018-10-17 23:07:57

Bao_lai 发表于 2018-10-17 23:06
(defun c:ca()
   (SETVAR "CMDECHO" 0)       
   (setq en1 (entsel "\n请选择表达式: \n"))


请试一试,如果出错就用底下这个吧。
(princ (strcat "\n" text1 "*1.0="))
页: [1] 2
查看完整版本: 求教:cal计算大整数时错误