Robinbb 发表于 2022-7-5 17:16:17

[帮助]ATOF函数遍历la

你好,卡迪亚斯,
 
我在网上找不到这个问题的解决方案。谈到AutoLISP,我基本上也是一个新手,因为我只是临时学习了该语言,以满足我的业务的某些需要。
 
我有一个lisp例程,它读取一个文本文件,每一行都有坐标深度和描述。我使用substr函数从每一行中获取每一项信息。到目前为止,一切正常。
 
然而,当我使用ATOF(在一些测试之后)时,它将值舍入到6位有效数字。例如,如果我在字符串“543334.243”上使用ATOF,它返回543334.0,“9543334.243”返回9.54333e+06,“43334.243”返回43334.2。
 
因此,当我使用此例程创建具有6个以上有效数字的点时,我遇到了舍入问题。我可以使用其他功能吗?我试过DISTOF,但它给了我同样的结果。这是一个设置还是我可以改变的?
 
我目前正在使用AutoCAD 2017,我使用VLIDE编写和编辑我使用的代码。这段特定的代码不久前最初是为AutoCAD R14编写的,现在仍然有效。
 
这是代码

;READ_MRG.LSP
;reads ASCII M-file <name.ext> created by MERGE_WS.BAS
;and inserts PT blocks 950 on each layer of the type _PTS#
;format of file must be:
;Name/1-7, East/9-19, North/21-31, Depth/33-41, Rmks/43-55,
;Seabed GPS El 57-65, Acc 67-68, Exact 70-71
;Exact shows whether interpolation was needed
;Read Hydro in ACAD File|ASC In/Out calls this program

;----------
(defun setcol()
(setq na1 1 na2 7 ea1 9 ea2 11 no1 21 no2 11 dp1 33 dp2 9
      rm1 43 rm2 13 el1 57 el2 9 acc1 67 acc2 2 xa1 70 xa2 2)
)
;----------
(defun C:READ_MRG ( / fname s f tx name east north depth elev rmks pt1)
(setvar "ATTDIA" 0)
(setvar "ATTREQ" 1)
;get existing file
(setq fname (getfiled "Select M... file: " "" "" 0))
(if f (close f))
(if (setq f (open fname "r"))
   (progn
;         (command "LAYER" "M" "_weak" "")
;         (command "LAYER" "M" "_bad" "")
      (princ "\nReading and inserting ...\n")
      (setcol)
      (setq tx (read-line f))
      (setq lyrnum 0)
      (setq ptnum 0)
      (while tx
         (if (= 0 ptnum)
            (progn
               (setq lyrnum (+ 1 lyrnum))
               (command "LAYER" "M" (strcat "_PTS" (rtos lyrnum 2 0)) "")
               (setq ptnum 0)
            )
         )
         (if (/= (substr tx 1 1) ";")    ;ignore remark and header lines
            (progn
               (putpt)
               (if (= ptnum 949)
                  (setq ptnum 0)
                  (setq ptnum (+ 1 ptnum))
               )
            )   
         )
         (setq tx (read-line f))
      );while tx
      (close f)
   )
);if f
(princ)
)
;----------
(defun putpt ()
(setq
   name (substr tx na1 na2)
   east (substr tx ea1 ea2)
   north (substr tx no1 no2)
   depth (substr tx dp1 dp2)
   rmks(substr tx rm1 rm2)
   elev(substr tx el1 el2)
   acc   (atoi (substr tx acc1 acc2))
   xact(substr tx xa1 xa2)
   name (rtos (atof name) 2 0)
   east (atof east)
   north (atof north)
   depth (atof depth)
   pt1 (list east2 north2)
)
(if
    (= depth2 -32767.0)
      (setq depth2 "")
      (setq depth2 (rtos depth 2 3))
)
(command "INSERT" "PT" pt1 1 1 0 depth2 name rmks)
;   (if
;   (> acc 3)
;       (command "CHPROP" "L" "" "LA" "_weak" "")
;   )
;   (if
;   (> acc 6)
;       (command "CHPROP" "L" "" "LA" "_bad" "")
;   )
)


 
任何帮助都将不胜感激。提前谢谢。
 
罗宾

Stefan BMR 发表于 2022-7-5 17:29:14

你不需要任何特殊功能。
仅为方便起见,截断了该值。
尝试将结果反转回字符串,您将看到所有的小数。
(atof "9543334.243") -> 9.54333e+006
(rtos (atof "9543334.243") 2 3) -> "9543334.243"

Robinbb 发表于 2022-7-5 17:43:42

感谢您的回复,我突出显示的红色代码是我尝试存储这些atof值的地方,但当我运行例程时,结果是这些值被截断,因此我的所有点都位于错误的位置。我用VLIDE“watch window”查看在使用atof an后传递的值是什么,它在窗口中显示了截断的值(watch window不应该显示实际值吗?)。
在研究过程中,我读到AutoCAD内部保留了该值,但显示了一个截断值,但是该例程不显示任何文本,它使用从文本文件创建的变量来绘制点,这些点是用截断值创建的,因此所有点都在一条直线上,因此代码中有一些不正确的地方,但我无法理解。

Roy_043 发表于 2022-7-5 17:54:36

你在哪里定义east2和north2?

lrm 发表于 2022-7-5 18:07:33

AutoCAD将坐标存储为双精度实数。这意味着数字大约有15到17个有效数字(参见https://en.wikipedia.org/wiki/Double-precision_floating-point_format了解更多信息)。
 
对于以下各项:
(setq x 123456789.123456789)
x将显示为:1.23457e+008
 
将x转换为字符串:
(setq xstring(rtos x))
收益率:“123456789.1234568”
 
将字符串转换为实数会产生以下显示值:
(setq xreal(atof xstring))
1.23457e+008
这意味着舍入为6位有效数字。
 
但是我们可以发现,从x的原始值中减去它,xreal具有更高的精度。
(setq dif(-x xreal))
-1.49012e-008
 
这表明x和xreal与16位有效数字相同(小数点前9位,小数点后7位)。xreal的精度高于其显示值。
 
小心不要将显示值与实际值混淆。

Robinbb 发表于 2022-7-5 18:21:01

从调试开始,我将east和north的第二个引用更改为east2和north2,看看这是否有帮助。我在创建线程之前把它改回来了,但我错过了这两个
页: [1]
查看完整版本: [帮助]ATOF函数遍历la