Jump to content

round up number in autolisp


Qonfire

Recommended Posts

Hello people a beginner question

lets say i do some calculations i want than round up the result of calcul to the next whole number

Link to comment
Share on other sites

  • Replies 24
  • Created
  • Last Reply

Top Posters In This Topic

  • Lee Mac

    5

  • Qonfire

    5

  • irneb

    4

  • ckwilliam

    2

depending on what you want to do

look at the fix function

fix 3.75 will return 3 and if you want to round up use the 1+ function

(1+(fix 3.75)) will return 4

Link to comment
Share on other sites

If you need to round numbers to closest real-value increments, then you could use mine over here:

;;; -------------------------------------------------------------------------------------
;;; Round a number to the closest matching factor
;;; -------------------------------------------------------------------------------------
;;; num : real/integer value to be rounded
;;; fact : real/integer value as factor to be rounded to
;;; Result: real/integer value rounded to the closest matching to fact
;;; -------------------------------------------------------------------------------------
(defun Round (num fact / n1 n2 d1 d2)
 (setq fact (abs fact)
       n1   (RoundDown num fact)
       n2   (+ n1 fact)
       d1   (abs (- num n1))
       d2   (abs (- num n2))
 )
 (if (< d1 d2)
   n1
   n2
 )
)

;;; -------------------------------------------------------------------------------------
;;; Round a number down to the closest matching factor below the value
;;; -------------------------------------------------------------------------------------
;;; num : real/integer value to be rounded
;;; fact : real/integer value as factor to be rounded to
;;; Result: real/integer value rounded to the closest matching to fact
;;; -------------------------------------------------------------------------------------
(defun RoundDown (num fact /)
 (setq num (- num (rem num fact)))
 (if (and (= (type fact) 'INT) (= (type num) 'REAL))
   (fix num)
   num
 )
)

;;; -------------------------------------------------------------------------------------
;;; Round a number up to the closest matching factor above the value
;;; -------------------------------------------------------------------------------------
;;; num : real/integer value to be rounded
;;; fact : real/integer value as factor to be rounded to
;;; Result: real/integer value rounded to the closest matching to fact
;;; -------------------------------------------------------------------------------------
(defun RoundUp (num fact /)
 (+ (RoundDown num fact) (abs fact))
)

Works file for any form of number, and you can get the result to be either a real or an integer. E.g.:

_$ (roundup 34.5678 1)
35
_$ (roundup 34.5678 1.0)
35.0
_$ (roundup 34.3678 0.5)
34.5

Link to comment
Share on other sites

(defun LM:Round ( n ) (fix (+ n (if (minusp n) -0.5 0.5)))) here Lee considers what if number negativ if - than make it positive number and than i dont get it ....the last part make that number integer......could u please break it down.....why In Lee version in stead of 1+ there is just plus

 

(1+(fix 3.75) in JohnM version number becomes integer than u add 1 so 3.45 become 3 plus 1...understand

 

thank you all Its amazing I can get an answer links and help to all my questions in a short period of time from experts on this cool site

Link to comment
Share on other sites

Lee's LM:Round function does a round to nearest integer (it produces similar results to my Round defun if you use a factor of 1 in mine).

 

To explain what happens in Lee's though:

(fix ;Fix the result to an integer value
 (+ ;Add the following numbers together
   n ;The original number
   (if (minusp n) ;If the original number is negative
     -0.5 ;Subtract a half from it
     0.5 ;Else add a half to it
   )
 )
)

Say you send the value 3.75 to that defun. It sees that it's not negative so adds 0.5 to it = 4.25, then uses fix on that = 4.

 

If it was negative (e.g. -3.35) then it subtracts 0.5 from that and you get -3.85. The fix then adjusts it to become -3.

 

Unfortunately Lee's method doesn't work well if you want to round-up always. For the round-down the fix function's the easiest, and the round-up becomes a simple increment of that. Just as a warning though, don't reuse the rounded result from fix too much. There was a thread about it causing rounding errors: http://www.cadtutor.net/forum/showthread.php?60050-Help-What-wrong-in-Fix-defun

Link to comment
Share on other sites

To understand the method I use, consider that for numbers n such that the fractional part is greater than 0.5, i.e.

(< 0.5 (rem n 1))

Adding 0.5 to such numbers will make them greater than the next integer, and so the fix function will then remove the fractional part and return the whole integer as required. Whereas, for those numbers whose fractional part is less than 0.5, these will remain below the next integer after the addition of 0.5, and so the fix function will return the integer below, hence rounding down. The reverse logic can be applied for negative numbers.

 

The functions I have provided on my site are for rounding to the nearest integer, however, I notice you wish to round up to the next integer, whatever the fractional part of the provided number - for this I would recommend the following function:

 

(defun RoundUp ( n )
 (if (or (minusp n) (zerop (rem n 1)))
   (fix n)
   (fix (1+ n))
 )
)

_$ (RoundUp 2.4)
3
_$ (RoundUp -2.4)
-2
_$ (RoundUp -2.0)
-2
_$ (RoundUp 2.0)
2

Link to comment
Share on other sites

Irne,

 

I like this construct:

 

(setq num (- num (rem num fact)))

Since, for large numbers/precisions my 'Roundto' function will run out of integers when the fix function is called, as the original number is exponentiated by 10^p before peforming the rounding operation:

 

(defun LM:Roundto ( n p ) (/ (fix (+ (* n (setq p (expt 10. p))) (if (minusp n) -0.5 0.5))) p))

I might now be inclined to rewrite my Roundto function as:

 

(defun LM:Roundto ( n p / f )
 (setq n (- n (setq f (rem n (setq p (expt 10. (- p)))))))
 (if (< 0.5 (/ (abs f) p))
   ((if (minusp n) - +) n p)
   n
 )
)

Link to comment
Share on other sites

Irne try this code is from MSDN


public static double Round(double value, short digits) 
{
           double 
factor = Math.Pow(10, 
digits);
           
return Math.Round(value * factor) / 
factor;
        }

Not so easy to convert to lisp I think

Link to comment
Share on other sites

Yep, I tried to steer clear of the usual fix method of rounding in my functions. As that other thread points out, it doesn't always play well with mixing reals & integers - especially when you get very close to the integer value, but not EXACTLY on it. (What you're basically trying to avoid with that (zerop (rem n 1))).

 

I might even need to perform an check to see if the real value num (in my RoundDown) is "extremely" close to the integer factor of fact. To get around any possibility of a rounding error like ktexu got in that other thread. But I'm in 2 minds as to whether that's a good idea: what if the number was "supposed" to be very close, but just beneath the next integer factor?

Link to comment
Share on other sites

Fixo: that's using a math library built into C++/C#. It's a bit difficult calling it from lisp, unless you go and write a DotNet wrapper which opens a lisp function to it (but then you always need to NetLoad that thing!)

 

Edit: It would have made AutoLisp a lot easier if we could have the usual Common Lisp stuff: http://jtra.cz/stuff/lisp/sclr/round.html

 

In which case the OP's request could have been (car (ceiling num))

Link to comment
Share on other sites

  • 2 years later...

Hi, I'm new to autolisp. Found the roundup number lisp in this post. Have using it to roundup the column load to nearest 50kN.

 

It seem that the column load text have different justify setting. How to set the justify of the new text as the previous replace text?

 


;;; -------------------------------------------------------------------------------------
;;; Round a number to the closest matching factor
;;; -------------------------------------------------------------------------------------
;;; num : real/integer value to be rounded
;;; fact : real/integer value as factor to be rounded to
;;; Result: real/integer value rounded to the closest matching to fact
;;; -------------------------------------------------------------------------------------
(defun Round (num fact / n1 n2 d1 d2)
 (setq fact (abs fact)
       n1   (RoundDown num fact)
       n2   (+ n1 fact)
       d1   (abs (- num n1))
       d2   (abs (- num n2))
 )
 (if (< d1 d2)
   n1
   n2
 )
)

;;; -------------------------------------------------------------------------------------
;;; Round a number down to the closest matching factor below the value
;;; -------------------------------------------------------------------------------------
;;; num : real/integer value to be rounded
;;; fact : real/integer value as factor to be rounded to
;;; Result: real/integer value rounded to the closest matching to fact
;;; -------------------------------------------------------------------------------------
(defun RoundDown (num fact /)
 (setq num (- num (rem num fact)))
 (if (and (= (type fact) 'INT) (= (type num) 'REAL))
   (fix num)
   num
 )
)

;;; -------------------------------------------------------------------------------------
;;; Round a number up to the closest matching factor above the value
;;; -------------------------------------------------------------------------------------
;;; num : real/integer value to be rounded
;;; fact : real/integer value as factor to be rounded to
;;; Result: real/integer value rounded to the closest matching to fact
;;; -------------------------------------------------------------------------------------
(defun RoundUp (num fact /)
 (+ (RoundDown num fact) (abs fact))
)



(defun c:ru ( )



(setq entdata (entget (car(entsel "\nSelect The Column Load: "))))
(setq txt (cdr (assoc 1 entdata)))
          (setq pt1 (cdr (assoc 10 entdata)))
(setq txh (cdr (assoc 40 entdata)))
(setq txtn (atof txt))
(setq txtnup (RoundUp txtn 50))
(setq txtr (rtos txtnup 2 0))
(setq txtrkn (strcat txtr "kN"))

(setq oldlayer (getvar "CLAYER")) ; get current layer
(setvar "CLAYER" "COLUMNLOAD")

(command "-mtext" pt1 "h" txh "j" "bl" "w" "0" txtrkn "")
(setq aa (cdr (assoc -1 entdata)))
(SETVAR "CLAYER" oldlayer)
(entdel aa)








)

Edited by ckwilliam
Link to comment
Share on other sites

Welcome to CADTutor ckwilliam :)

 

When posting code, you can preserve the code indentation by enclosing the code in code tags, e.g.:

 

[highlight][noparse]

[/noparse][/highlight]Your code here[highlight][noparse]

[/noparse][/highlight]

 

You can edit your post to correct this.

 

For more information about posting code, please read the Code Posting Guidlines.

Link to comment
Share on other sites

  • 3 years later...

look at previous codes and add check for odd & even ie (/ (- num (fix num)) 2.0) this should be so close to zero if a even number ans/2 say = 7.000000001, 12.7/2=6.35 so 0.35 add 1 to the round up from code above which would be 13.0 result is 14.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...