Author Topic: Rounding Real Numbers  (Read 10099 times)

0 Members and 1 Guest are viewing this topic.

MeasureUp

  • Bull Frog
  • Posts: 461
Rounding Real Numbers
« on: April 29, 2013, 12:56:16 AM »
The "fix" function converts a real number to the nearest smaller number.
How to round a real number to the nearest larger number?
Thanks in advance.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Rounding Real Numbers
« Reply #1 on: April 29, 2013, 01:14:54 AM »
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

MeasureUp

  • Bull Frog
  • Posts: 461
Re: Rounding Real Numbers
« Reply #2 on: April 29, 2013, 02:03:16 AM »
Thanks Kerry.
The thread is great.

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1451
  • Marco
Re: Rounding Real Numbers
« Reply #3 on: April 29, 2013, 05:54:45 AM »
The "fix" function converts a real number to the nearest smaller number.
How to round a real number to the nearest larger number?
Thanks in advance.
Code: [Select]
; Rounding function - Doug Broad - 02/19/2003
; Additional credits: Joe Burke, Peter Toby
; Original name: (defun Round (value to) ...)
;
; Examples:
; (ALE_Number_Round 1.11111          1) => 1
; (ALE_Number_Round 1.11111        0.1) => 1.1
; (ALE_Number_Round 1.11111       0.01) => 1.11
; (ALE_Number_Round 1.11111      0.001) => 1.111
; (ALE_Number_Round 1.11111     0.0001) => 1.1111
; (ALE_Number_Round 1.11111  0.0000001) => 1.11111
;
; (ALE_Number_Round 1.565656        10) => 0
; (ALE_Number_Round 1.565656         1) => 2
; (ALE_Number_Round 1.565656       0.1) => 1.6
; (ALE_Number_Round 1.565656      0.01) => 1.57
; (ALE_Number_Round 1.565656     0.001) => 1.566
; (ALE_Number_Round 1.565656    0.0001) => 1.5657
; (ALE_Number_Round 1.565656   0.00001) => 1.56566
; (ALE_Number_Round 1.565656 0.0000001) => 1.56566
;
(defun ALE_Number_Round (ImpVal To_Val)
  (setq To_Val (abs To_Val))
  (*
    To_Val
    (fix
      (/
        (
          (if (minusp ImpVal)
            -
            +
          )
          ImpVal
          (* To_Val 0.5)
        )
        To_Val
      )
    )
  )
)

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Rounding Real Numbers
« Reply #4 on: April 29, 2013, 08:22:38 AM »
@Marc'Antonio Alessi
To be exact: :police:
Your function rounds to infinity and not to the nearest largest number.
(ALE_NUMBER_ROUND -1.5 1) => -2

Lee Mac

  • Seagull
  • Posts: 12905
  • London, England
Re: Rounding Real Numbers
« Reply #5 on: April 29, 2013, 08:28:35 AM »
Here are my functions for rounding up & down:

Code - Auto/Visual Lisp: [Select]
  1. ;; Round Up  -  Lee Mac
  2. ;; Rounds 'n' up to the nearest 'm'
  3.  
  4. (defun LM:roundup ( n m )
  5.     (cond
  6.         ((equal 0.0 (rem n m) 1e-8) n)
  7.         ((< n 0) (- n (rem n m)))
  8.         ((+ n (- m (rem n m))))
  9.     )
  10. )
  11.  
  12. ;; Round Down  -  Lee Mac
  13. ;; Rounds 'n' down to the nearest 'm'
  14.  
  15. (defun LM:rounddown ( n m )
  16.     (cond
  17.         ((equal 0.0 (rem n m) 1e-8) n)
  18.         ((< n 0) (- n (rem n m) m))
  19.         ((- n (rem n m)))
  20.     )
  21. )

Code - Auto/Visual Lisp: [Select]
  1. _$ (LM:roundup 3.2 2)
  2. 4.0
  3. _$ (LM:rounddown 3.2 2)
  4. 2.0

MeasureUp

  • Bull Frog
  • Posts: 461
Re: Rounding Real Numbers
« Reply #6 on: April 29, 2013, 07:29:42 PM »
Thanks to everyone's tips.
Cheers!

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1451
  • Marco
Re: Rounding Real Numbers
« Reply #7 on: April 30, 2013, 04:23:05 AM »
@Marc'Antonio Alessi
To be exact: :police:
Your function rounds to infinity and not to the nearest largest number.
(ALE_NUMBER_ROUND -1.5 1) => -2
Thanks for pointing that.  :'(
 :kewl:

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Rounding Real Numbers
« Reply #9 on: May 07, 2013, 08:08:41 AM »
An optimized version I've taken from here: http://blog.frama-c.com/index.php?post/2013/05/02/nearbyintf1

Seeing as AutoLisp reals are always doubles, you could use the add (0.5 - one double increment less = 0.49999999999999994) idea.
Code - Auto/Visual Lisp: [Select]
  1. (defun round (val)
  2.   (fix (+ val 0.49999999999999994)))
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

bruno_vdh

  • Guest
Re: Rounding Real Numbers
« Reply #10 on: May 07, 2013, 08:28:16 AM »
Hello,

Good idea, but be careful with the type of the return value.
Code: [Select]
$ (type (round 2.49))
INT

I think this is preferable
Code: [Select]
$ (defun round (val)  (float (fix (+ val 0.49999999999999994))))
ROUND
_$ (type (round 2.49))
REAL

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: Rounding Real Numbers
« Reply #11 on: May 08, 2013, 01:38:37 AM »
It depends on what you want. If you always do want a real, then add the float conversion as per your code. However, Lisp usually does not care between int & real, performing mathimatical calcs would convert to whatever is needed automatically. E.g. see the return on a very large real value from my code - if it's larger than the signed 32bit int max/min then the return stays a real.
Code: [Select]
_$ (round 1234567890)
1234567890
_$ (round 12345678901)
1.23457e+010

There are some functions which do care about the type though (the rtos and itoa e.g.). IMO this is an inconsistency - I'd have much more use for a num-to-str function, but I get why the 2 are there (ability to format decimals/fractions for reals but not ints). One of the reasons for the format function in this thread: http://www.theswamp.org/index.php?topic=39158.45
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

chlh_jd

  • Guest
Re: Rounding Real Numbers
« Reply #12 on: May 10, 2013, 04:43:28 AM »
Add the precision option :
Code: [Select]
(defun round (num pre / b)
  ;; Enhanced rounding
  ;; num -- a number
  ;; pre -- precision , type in an interg like -1 0 2 ...
  ;; (round 1.23456789 3) --> 1.235
  ;; (round 1.23456789 0) --> 1.0
  ;; (round 123456789 -3) --> 1.23457e+008
  ;; (round -98764567 -5) --> -9.88e+007
  (setq b (expt 10.0 pre))
  (/ (fix (+ (* num b) (* 0.5 (sign num)))) b)
    )
(defun sign (x) (cond ((minusp x)-1.)(1.0)))

VovKa

  • Water Moccasin
  • Posts: 1626
  • Ukraine
Re: Rounding Real Numbers
« Reply #13 on: May 11, 2013, 04:14:20 AM »
in case anyone would need another rounding rule
http://www.theswamp.org/index.php?topic=23142.msg278394#msg278394

paradonk

  • Guest
Re: Rounding Real Numbers
« Reply #14 on: July 03, 2017, 11:23:26 PM »
(defun round (number)
  (if (>= (rem number 2 1) 0.5)
    (1+ (- number (rem number 2 1)))
    (float (fix number))
  )
)