can someone tell me why this is, and/or another way to do it. given a real with one decimal place, say 1.2, I would like the decimal portion as an integer (just the 2). so like this: (setq a1 1.2) 1.2 (setq a1 (- a1 (fix a1)) 0.2 (setq a1 (* a1 10)) 2.0 (setq a1 (fix a1)) 1 WTF? any thoughts? or a better way to solve for this? --J
It just the way real numbers are stored in a 'puter. (setq a1 (atoi (rtos a1 2 14))) Allows you to control the accuracy. -David
Yes,that is another way to do it, but why doesn't this work? (setq a1 (fix (* (- a1 (fix a1)) 10))) if the value of a1 is 1.2, mathematically, this equasion looks like: (1.2 - 1.0)*10 this equates to 2, so why doesn't autocad come up with the same number? In autocad, using a value of 1.3, the above lisp tidbit returns '3' but if you enter 1.4, it returns '3'.... This makes little sense.
This seems to work. ;; return the decimal value of a real number as an integer (defun DV (num / str) (if (= (type num) 'REAL) (progn (setq str (rtos num 2)) (atoi (vl-string-right-trim "0" (substr str (+ 2 (vl-string-search "." str))))) ) ) ) Command: (dv -3.10250) 1025 Joe Burke
Casey, I think fix should be avoided with something like this. Though the number appears to be 1.4, it may be stored internally as 1.39999999... Fix simply discards the decimal value. So your function might return 3. See my string based solution below. Joe Burke
(defun ALE_NumberLeftPtTrim (NumVal / CurDZn OutVal PtnPos) (if (= 8 (setq CurDZn (getvar "DIMZIN"))) (setq CurDZn nil) (setvar "DIMZIN" 8) ) (setq OutVal (rtos NumVal 2)) (and CurDZn (setvar "DIMZIN" CurDZn)) (if (setq PtnPos (vl-string-position (ascii ".") OutVal)) (atoi (substr OutVal (+ 2 PtnPos))) 0 ) ) Comando: (ALE_NumberLeftPtTrim 1) 0 Comando: (ALE_NumberLeftPtTrim 1.2) 2 Comando: (ALE_NumberLeftPtTrim 1.23) 23 Comando: (ALE_NumberLeftPtTrim 1.234) 234 Comando: (ALE_NumberLeftPtTrim 1.23400) 234 Comando: (ALE_NumberLeftPtTrim 0) 0 Comando: (ALE_NumberLeftPtTrim 0.0) 0 Comando: (ALE_NumberLeftPtTrim 0.0000) 0 Comando: (ALE_NumberLeftPtTrim 0.1) 1 Comando: (ALE_NumberLeftPtTrim 0.1234000) 1234 -- Marc'Antonio Alessi http://xoomer.virgilio.it/alessi (strcat "NOT a " (substr (ver) 8 4) " guru.") --
Hi, Marco. I guess we both forgot the rtos precision argument. Command: (ale_numberleftpttrim 1.23456789) 2346 A question for you and others. I was fairly certain the function should return nil when passed an integer. Obviously you thought otherwise, and you might be right. My thinking was returning zero seems to indicate there was a decimal value, when there was none. ;; revised 9/29/2004 ;; return the decimal value of a number as an integer (defun DV (num / str) (if (= (type num) 'REAL) (progn (setq str (rtos num 2 14)) ;added precision (atoi (vl-string-right-trim "0" (substr str (+ 2 (vl-string-search "." str))))) ) ) ) Regards Joe Burke
Casey, Acad has the computer store integers as they are inputed. 0 to 32,767 X 2 ( + and - ) 4 bytes per integer ( 16 x 16 x 16 x 16 ) 65,536 Real numbers ( ie 1.2 ) are stored in scientific notation with 15 significant places. 8 bytes per real. It is not always totally accurate and therefore can lead to some erroneous results Most of this comes from the days when PC storage space and memory were at a premium. Today there are long integers. I don't know if reals have been updated. So things like (fix), division of integers (/ 3 2), can still be a problem. HTH -David
I know of no other operating system or programming language that returns this erroneous result. It sounds to me like an Acad floating point bug. --Jeremiah
Thanks, may be this is better: (defun ALE_NumberLeftPtTrim (NumVal / CurDZn OutVal PtnPos) (if (= 8 (setq CurDZn (getvar "DIMZIN"))) (setq CurDZn nil) (setvar "DIMZIN" 8) ) (setq OutVal (rtos NumVal 2 14)) (and CurDZn (setvar "DIMZIN" CurDZn)) (if (setq PtnPos (vl-string-position (ascii ".") OutVal)) (atoi (substr OutVal (+ 2 PtnPos))) ) ) Yours has better performance: DV > 10000 iterations: 0.36 secs. ALE_NUMBERLEFTPTTRIM > 10000 iterations: 0.38 secs. setting DIMZIN outside the function: ALE_NUMBERLEFTPTTRIM > 10000 iterations: 0.32 secs Cheers. -- Marc'Antonio Alessi http://xoomer.virgilio.it/alessi (strcat "NOT a " (substr (ver) 8 4) " guru.") --