Author Topic: Lee Mac Rounding function not returning correct result  (Read 2375 times)

0 Members and 1 Guest are viewing this topic.

jtoverka

  • Newt
  • Posts: 127
Lee Mac Rounding function not returning correct result
« on: October 10, 2019, 01:58:50 PM »
I am using Lee Mac's rounding function for an application. I have a function that rotates a point around another point with an angle. It's quite simple. There is a problem where the angle is correct, but the distance is not.

Code: [Select]
  (defun rotatePoint (origin point ang1 / x y r)
    (setq r (distance origin point))
    (setq ang2 (angle origin point))
    (setq x (LM:roundto (* r (cos (+ ang1 ang2))) 8))
    (setq y (LM:roundto (* r (sin (+ ang1 ang2))) 8))
    (mapcar '+ origin (list x y 0))
  )
  (defun LM:roundto ( n p )
      (LM:roundm n (expt 10.0 (- p)))
  )
  (defun LM:roundm ( n m )
      (* m (atoi (rtos (/ n (float m)) 2 0)))
  )

After debugging, I found it to be the rounding function. I notice the LM:roundto function has incorrect results after certain values. For example:
Code: [Select]
(lm:roundto 21 8) ; = 21.0
(lm:roundto 22 8) ; = 21.4748
anything above 21.4748 just yeilds 21.4748.

This error is a function of the decimal places used. for example:
Code: [Select]
(lm:roundto 22 7) ; = 22.0            correct
(lm:roundto 220 7) ; = 214.748     incorrect
(lm:roundto 220 6) ; = 220.0        correct
(lm:roundto 2200 6) ; = 2147.48   incorrect
(lm:roundto 2200 5) ; = 2200.0     correct
« Last Edit: October 10, 2019, 02:10:21 PM by jtoverka »

jtoverka

  • Newt
  • Posts: 127
Re: Lee Mac Rounding function not returning correct result
« Reply #1 on: October 10, 2019, 02:09:22 PM »
Looking into it, it appears to be an overflow error since the range of a 32 bit integer is 2147483647 to -2147483648. This error takes place at the point of atoi in the LM:roundm routine.
(atoi "2200000000") = 2147483647

I reduced the decimal bits from 8 to 6 in my application as it will be "okay."

tombu

  • Bull Frog
  • Posts: 288
  • ByLayer=>Not0
Re: Lee Mac Rounding function not returning correct result
« Reply #2 on: October 10, 2019, 03:00:00 PM »
Very old code  by Doug Broad:
Code: [Select]
;;; Written by Doug Broad
;;; If value given 'to' argument is a real, a real is returned.
;;; Rounds to nearest multiple of 'to' real or integer.

(defun round (value to)
  (setq to (abs to))
  (* to (fix (/ ((if (minusp value) - +) value (* to 0.5)) to)))
)

(defun roundup (value to / try)
  (setq to (abs to)
          try (+(* to (fix (/ ((if (minusp value) - +) value (* to 0.5)) to)))to)
  )
  (if(eq (+ 0.1 try) (+ 0.1 value to))(- try to) try)
)

; examples:
; (round 12232e-015 1)
; 0
; (round 12232e-015 1.0)
; 0.0
; (round 123.6 1.0)
; 124.0
; (round -123.6 1.0)
; -124.0
; (round 6.00000000008 4)
; 8
; 6.00000000008  rounded to the nearest multiple of 4 is 8

; Command: (roundup 30.01 5)
; 35
; Command: (roundup 30 5)
; 30
Try:
Code: [Select]
(round 22 0.00000001) to get 22.0 as
Code: [Select]
(round 22 8) rounds to the nearest multiple of 8 which is 24.
« Last Edit: October 24, 2019, 11:38:56 AM by tombu »
Tom Beauford P.S.M.
Leon County FL Public Works - Windows 7 64 bit AutoCAD Civil 3D

jtoverka

  • Newt
  • Posts: 127
Re: Lee Mac Rounding function not returning correct result
« Reply #3 on: October 10, 2019, 03:24:18 PM »
This is much better, however it still suffers some drawbacks.

(ROUND 170.123456 0.00001) = 170.123
(ROUND 170.123456 0.001) = 170.123

I would like a function that can round to a specified decimal place. This function must work at all boundary conditions. Now the work I do does not require that level of precision. However, a function should be capable of handling all possible scenarios.

I'll take a crack at it soon. Hopefully, it'll be as pretty as the other functions.

VovKa

  • Water Moccasin
  • Posts: 1626
  • Ukraine
Re: Lee Mac Rounding function not returning correct result
« Reply #4 on: October 10, 2019, 04:58:13 PM »
i ended up with
Code: [Select]
(atof (rtos r 2 p))

jtoverka

  • Newt
  • Posts: 127
Re: Lee Mac Rounding function not returning correct result
« Reply #5 on: November 27, 2019, 12:34:29 PM »
i ended up with
Code: [Select]
(atof (rtos r 2 p))

This is the KISS principle in action. Thank you very much!