TheSwamp
Code Red => AutoLISP (Vanilla / Visual) => Topic started by: daron on August 30, 2004, 11:06:08 AM
-
I've been doing a little experimentation today with the boole function. Trying to understand it beter. I decided to look into boole 8 (and's compliment). Here are my findings:
Set my osmode to 6175, I started off with 15359, as you see below.
Command: osmode
Enter new value for OSMODE <0>: 6175
Command: (setvar 'osmode (boole 8 (getvar 'osmode)15359))
Error: AutoCAD variable setting rejected: OSMODE -15360
Error: Function Cancelled.
I errored out above, noting that osmode can't take negative numbers. I also noted that the number was increased by 1 as well as being inversed. Solution below:
Command: (setvar 'osmode (boole 8 (getvar 'osmode) (- 15359)))
9184
Command: (setvar 'osmode (boole 8 (getvar 'osmode) (- 15359)))
6174
Command: (setvar 'osmode (boole 8 (getvar 'osmode) (- 15359)))
9184
Command: (setvar 'osmode (boole 8 (getvar 'osmode) (- 15359)))
6174
Something's not right here. 9184 is the complement to 6175, but when inverted again, the osmode number 6174 is placed. This removes endpoint. This seems very odd. I decided to see if I could increase the entire thing to see what would happen. Note below:
Command: (setvar 'osmode (1+ (boole 8 (getvar 'osmode) (- 15359))))
9185
Command: osnap
Command:
Command: (setvar 'osmode (1+ (boole 8 (getvar 'osmode) (- 15359))))
6175
Well, that works for 6175, but it also increases the inverse to 9185. That I would assume, but I had to see it first hand.
Next thought, increase 15359 to 15360, or in this case, decrease it, since it's a negative number. See below:
Command: (setvar 'osmode (boole 8 (getvar 'osmode) (- 15360)))
9184
Command: (setvar 'osmode (boole 8 (getvar 'osmode) (- 15360)))
6175
Command: (setvar 'osmode (boole 8 (getvar 'osmode) (- 15360)))
9184
Problem solved. Now, since 15359 is the addition of all osmode flags, why does it need to be increased to 15360 to work? I've also noticed that flag 1024 is missing from osnaps. Is this flag what used to be tracking? Does anybody remember?
-
1024 is used for the Quick osnap. It has no meaning as a standalone but with other osnaps it makes quite a difference when used among many objects.
Boole 8 is the NOR operator. It is equal to (~ (LOGIOR a b)) and only returns 1 if both input bits are 0. Therefore it will always set the sign bit when given two positive integers.
-
Okay, I do understand. To prove it, here's what I looked up and learned.
First, bitwise not (~)
(~ 5) = -6 Why?
Here's the answer I've discovered: 0 and -1 are the bitwise compliment. If you write out a graph:
-6 -5 -4 -3 -2 -1 0 1 2 3 4 5
-1 ~ 0
-2 ~ 1
...
-6 ~ 5
Okay, I understand that little function, now.
Next, logior. Stange name.
If I type in (logior 1 5 7), the answer is 7. Why?
Binary?
128 64 32 16 8 4 2 1
0 0 0 0 0 0 0 0 = 0
0 0 0 0 0 0 0 1 = 1
0 0 0 0 0 1 0 1 = 5
0 0 0 0 0 1 1 1 = 7
----------------------------
0 0 0 0 0 1 1 1 = 7
Next, bitwise not + logior
(~ (logior 1 5 7)) = -8
Reason? logior returns 7 and ~ returns its bitwise compliment: -8
WooHoo! Thanks Stig, for those little bits of knowledge. I really didn't think you'd answered the real question, until I looked into the bitwise not function. That opened it all up.
-
Excellent! :)
Because AutoLISP deals with integers and not single bits, bitwise NOT will always flip all 32 bits including the sign bit.
-
Here's a little ditty posted by Dietmar Rudolf back in the Compuserve days. I use it to this day when I need to delve back into the bitwise stuff. -David
;|Don,
logior and logand assume that the integer you pass as an argument is in fact
a list of bits. Here's a routine from my book on LISP programming, which
prints an integer as a list of bits:
|;
(defun print-bits (Bits / Bit-list Max-bit)
(if (minusp Bits)
(setq Max-bit 1
Bits (- Bits 2147483648))
(setq Max-bit 0)
)
(repeat 31
(setq Bit-list (cons (rem Bits 2) Bit-list)
Bits (/ Bits 2))
)
(cons Max-bit Bit-list)
)
Here are some examples of the functions working on bit-coded integers:
Command: (print-bits 53)
(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 1)
Command: (print-bits (~ 53)) ; Bit-wise complement
(1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 1 0)
Command: (print-bits (lsh 53 4)) ; left shift by four bits
(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 1 0 0 0 0)
Command: (print-bits 24)
(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0)
Command: (print-bits (logand 53 24)) ; bit-wise and
(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0)
Command: (print-bits (logior 53 24)) ; bit-wise or
(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1)
Command: (print-bits (boole 6 53 24)) ; bit-wise xor
(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1)
;Dietmar
-
Thanks David. Enlightening stuff.
-
I'm curious. In the above code posted by David there is line;
Bits (- Bits 2147483648)) where does the number 2147483648 come from?
-
where does the number 2147483648 come from?
(expt 2 31)
(rtos (expt 2 31) 2)
The starting point for Dietmar used.
Notice that it returns -2147483648
-David
-
So....... we are working on a 32 bit system?
-
Even more enlightening. I was trying to figure that out. I figured it had to do something with the number of the 32nd bit.
-
http://www.crlf.de/Dokumente/Logical%20LISP.html
I can't see that it explains why he uses that number. The max. integer is (2^31)-1 but in order not to have the routine deal with negative values I would just have used zero instead of 2^31
-
Here's another bit-printing function from http://www.autolisp-tutorial.mapcar.net/bits1.html (can't find the author's name .. maybe you can). It accepts both positive and negative numbers.
(defun prinbin (zahl / i str)
(setq i 0
str ""
)
(repeat 32
(setq str (strcat str
(itoa (logand 1 (lsh zahl (- i 31))))))
(setq i (1+ i))
(if (zerop (rem i 8))
(setq str (strcat str " "))
)
)
(strcat str ": " (itoa zahl))
)
-
Try this.
(print-bits (expt 2 31))
It still displays correctly even though ACAD returns a negative. -David