乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 56|回复: 2

[编程交流] What's rounding down my v

[复制链接]

9

主题

43

帖子

35

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
50
发表于 2022-7-6 12:44:57 | 显示全部楼层 |阅读模式
Hi folks,
 
I have an odd issue with an old lisp routine. We’ve been using this routine from the year 0, and somehow an error snuck in so it doesn’t work as it should. I know for a fact it once used to work as it should, I never touched it or modified it, and now something goes wrong somewhere.
It’s a routine that sets a few parameters, and will then draw a spring with a particular diameter. The wire diameter should be 27mm (radius 13.5mm), but for some reason, the end result is a spring with a diameter 26mm. Something is causing that number to be rounded down to 26mm (=radius 13mm).
 
Now, where it gets really weird is this: say if I enter Diameter 29mm, it rounds down to 28mm. Ok, sounds like that can be expected. However, if I go in and say Diameter 27.0001mm, it will go and draw me a circle with a diameter 27.0001mm. No rounding up or down this time. I can cheat the system by telling it to draw a circle with diameter 27.00000000001mm, and it will give me exactly what I want.
 
Am I dealing with a bug here, or can someone tell from looking at the code that the problem is in there? I'd be curious if others can reproduce this same problem. I'm running Acad 2010, and unfortunately i cannot test it on a previous version myself, because I suspect it's not the code, but Acad 2010 causing it.

Thanks
 
  1. (defun C:D27 (/ d3 d2 n) (setq d3 162) (setq d2 27) (setq n 7) (spg))(defun SPG (/ a ang d1 h p pt p1 p2 p3 p4 p5 p6 p7 p8 p9) (setq osm (getvar "OSMODE")) (setvar "CMDECHO" 0) (setq oer *error**error* seterr ) (setq d1 (- d3 d2)) (setq pt (getpoint "\nSelect start point: ")h  (getdist pt "\nSpring height: ") )(setvar "OSMODE" 0) (setq ang (getangle pt "\nAt base angle : ")) (if (not ang)   (setq ang (/ pi 2))   (setq ang (+ ang (/ pi 2))) ) (setq   a (atan (/ d2 2)    (sqrt      (- (* (- (* 0.75 d1) (/ d2 2)) (- (* 0.75 d1) (/ d2 2)))  (* 0.25 d2 d2)      )    )     ) ) (setq p1 (polar pt (+ ang (/ pi 2)) (/ d1 4))p2 (polar pt (- ang (/ pi 2)) (/ d1 2))p3 (polar p2 (+ ang (/ pi 2)) (/ d2 2))p4 (polar p2 (- ang (/ pi 2)) (/ d2 2))p5 (polar p2 (+ ang a) (/ d2 2)) ) (command ".LINE" p1 p3 "") (setq p7 (ssadd (entlast))) (command ".LINE" p3 p4 "") (ssadd (entlast) p7) (command ".LINE" p5 p1 "") (ssadd (entlast) p7) (command ".ARC" p3 p5 p4) (ssadd (entlast) p7) (setq p  (/ (- (* 2 h) (* d2 2)) (- (* 2 n) 1))p9 (/ (+ p d2) 2)p1 (polar p2 ang p9)p2 (polar pt (+ ang (/ pi 2)) (/ d1 2))p2 (polar p2 ang (/ d2 2))a  (atan (- p9 (/ d2 2)) d1)p3 (polar p1 (+ ang pi a) (/ d2 2))p4 (polar p1 (+ ang a) (/ d2 2))p5 (polar p2 (+ ang pi a) (/ d2 2))p6 (polar p2 (+ ang a) (/ d2 2)) ) (command ".LINE" p5 p3 "") (ssadd (entlast) p7) (command ".LINE" p6 p4 "") (ssadd (entlast) p7) (command ".CIRCLE" p1 (/ d2 2)) (ssadd (entlast) p7) (command ".CIRCLE" p2 (/ d2 2)) (ssadd (entlast) p7) (command ".COPY"   p7   ""   pt   pt   ".MOVE"   p7   ""   pt   (polar pt ang h)   ".ROTATE"   p7   ""   (polar pt ang h)   "180" ) (if (> n 2)   (progn     (setq p1 (polar p1 ang p)    p2 (polar p2 ang p)    a  (atan (/ p 2) d1)    p3 (polar p1 (+ ang pi a) (/ d2 2))    p4 (polar p1 (+ ang a) (/ d2 2))    p5 (polar p2 (+ ang pi a) (/ d2 2))    p6 (polar p2 (+ ang a) (/ d2 2))     )     (command ".LINE" p5 p3 "")     (setq p7 (ssadd (entlast)))     (command ".LINE" p6 p4 "")     (ssadd (entlast) p7)     (command ".CIRCLE" p1 (/ d2 2))     (ssadd (entlast) p7)     (command ".CIRCLE" p2 (/ d2 2))     (ssadd (entlast) p7)   ) ) (if (> n 3)   (progn (setq p8 0)   (repeat (- n 3)     (setq p8 (+ 1 p8))     (command ".COPY" p7 "" pt (polar pt ang (* p8 p)))   )   ) ) (redraw) (setq *error* oer) (setvar "OSMODE" osm) (princ))
回复

使用道具 举报

15

主题

687

帖子

169

银币

中流砥柱

Rank: 25

铜币
582
发表于 2022-7-6 13:37:45 | 显示全部楼层
Hi,
 
I'ts not a bug, it's not due to 2010 behavior and I can't believe it worked fine one time.
This is due to the division (/) lISP operator implementation which never changed.
With LISP arithmetic operators (+,  -,  *,  /, rem, expt) if all arguments ar integers, the result will be an integer too. If almost one argument is a real number the result will be a real number.
 
For example:
(/ 27 2) returns 13
(/ 27.0  2) returns 13.5
 
So just replace integers by reals in the c:d27 routine so that the wire diameter will be 27.0 and the spring diameter 162.0 (instead of 160):
 
  1. (defun C:D27 (/ d3 d2 n) (setq d3 162.0) (setq d2 27.0) (setq n 7) (spg))
回复

使用道具 举报

9

主题

43

帖子

35

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
50
发表于 2022-7-6 14:10:21 | 显示全部楼层
You are right, someone must have changed it somewhere along the line then. It just took quite some time for someone here to notice! Luckily it's a little used feature, rather than a lot of incorrect springs generated in many drawings.
 
Thanks for your help gile, much appreciated  I never would have figured this out. I thought a number had to be defined as an integer for it to behave as one.
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2025-6-7 18:12 , Processed in 0.305973 second(s), 58 queries .

© 2020-2025 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表