# TheSwamp

## Code Red => AutoLISP (Vanilla / Visual) => Topic started by: MeasureUp on April 29, 2013, 12:56:16 AM

Title: Rounding Real Numbers
Post by: MeasureUp 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?
Title: Re: Rounding Real Numbers
Post by: Kerry on April 29, 2013, 01:14:54 AM

You could start here:
http://www.theswamp.org/index.php?topic=18695.msg229257#msg229257
Title: Re: Rounding Real Numbers
Post by: MeasureUp on April 29, 2013, 02:03:16 AM
Thanks Kerry.
Title: Re: Rounding Real Numbers
Post by: Marc'Antonio Alessi 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?
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      )    )  ))`
Title: Re: Rounding Real Numbers
Post by: roy_043 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
Title: Re: Rounding Real Numbers
Post by: Lee Mac 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
Title: Re: Rounding Real Numbers
Post by: MeasureUp on April 29, 2013, 07:29:42 PM
Thanks to everyone's tips.
Cheers!
Title: Re: Rounding Real Numbers
Post by: Marc'Antonio Alessi 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:
Title: Re: Rounding Real Numbers
Post by: CAB on May 05, 2013, 09:03:56 PM
Looking back into the past.
http://www.theswamp.org/forum/index.php?topic=3076.0
http://www.theswamp.org/index.php?topic=8511.msg109002#msg109002

Title: Re: Rounding Real Numbers
Post by: irneb 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)))
Title: Re: Rounding Real Numbers
Post by: bruno_vdh 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`
Title: Re: Rounding Real Numbers
Post by: irneb 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
Title: Re: Rounding Real Numbers
Post by: chlh_jd on May 10, 2013, 04:43:28 AM
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)))`
Title: Re: Rounding Real Numbers
Post by: VovKa 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
Title: Re: Rounding Real Numbers
Post by: paradonk 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))
)
)
Title: Re: Rounding Real Numbers
Post by: roy_043 on July 04, 2017, 04:49:38 AM
`(round -1.9) => -1`What is your rounding rule?