AutoCAD
and Binaries - Page II
And now to something completely similar: BOOLE
BOOLE is AutoLISP's general function for logical bitwise operations. It
can handle 16 Boolean operations for which only a few I will live to tell
about, but it is fairly easy to set up truth tables if you want to explore
all the functions. Otherwise it will be necessary to refer to more
specialized literature.
All functions in BOOLE are input as an integer argument. If you don't have
the AutoLISP Reference at hand the syntax for BOOLE is as follows:
(boole operator int1 [int2 ... ])
; my apologies to the late George Boole for not using capital B
The 4 most common logical operators AND, XOR, OR or NOR
has the following integer representations. Please refer to the text and
the truth tables above for an explanation of these operators.
AND 1
XOR 6
OR 7
NOR 8
(boole 1 ...) and (boole 7 ...) performs the same operations as LOGAND and
LOGIOR. As mentioned before, beware that for example NOR does a one's
complement on a 16 bit integer and the truth table when printed out with
BOOLE is not the same as making a truth table on a single bit. We can
illustrate this is if doing a NOR operation on a byte - and by the way, A
NOR B is the same as NOT(A OR B):
A 00000001 NOR decimal: 1
B 00000000 => 0
A 00000001 OR 1
B 00000000 = 0
00000001 NOT 1
= 11111110 -1
Remember, binary representation of a negative integer is (in popular
terms) defined by setting the leftmost bit to 1, so AutoLISP will regard
the result of this equation as being two's complement of 1 = -1.
To try and make a truth table lisp showing all different values of the
different BOOLE operators, you could make a defun like the following. If
you would explore this matter even further it is possible to write a
decimal-to-binary conversion routine and really check out the binary
values bit for bit (hint: use (expt 2 n) to run through all bits).
(defun nothingButTheTruth (/ a)
(defun princline (b n m / x)
(setq x (boole b n m))
(cond ((= x -1)(setq x 1))
((= x -2)(setq x 0)))
(princ (strcat "\n" (itoa n) " " (itoa m) " " (itoa x)))
)
(setq a 0)
(repeat 16
(princ (strcat "\nOperator: " (itoa a)))
(princline a 0 0)
(princline a 0 1)
(princline a 1 0)
(princline a 1 1)
(terpri)
(setq a (1+ a))
)
(princ)
)
It will produce an output like this:
Operator: 0
0 0 0
0 1 0
1 0 0
1 1 0
Operator: 1
0 0 0
0 1 0
1 0 0
1 1 1
Operator: 2
0 0 0
0 1 0
1 0 1
1 1 0
...etc...
Operator: 8
0 0 1
0 1 0
1 0 0
1 1 0
...etc...
... and so on. A full list of the operators can be found at the end of
this article.
Whether you use BOOLE operators 1 and 7 or you use LOGAND and LOGIOR is
indifferent. Of course, in some specific code where it is needed to offer
the operator as a variable only BOOLE will do the job.
Clearing bits in a number can be done in a number of ways. For example,
clearing the 4th bit with AND in the number 48 could be done like this:
(logand 48 -17)
32
Why exactly use -17 as the masking value?, Well, looking at it bit-wise
this is what takes place:
00110000 AND decimal: 48 AND
11101111 -17 = (have in mind that integers are 32 bit and not 8 bit long)
00100000 32
We
simply
take advantage of the fact that AND clears all
bits if they aren’t both 1’s. Of course, this can be done in a more
obvious and especially a much more useful way when using logical NOT to
inverse the flag we want to mask with:
(logand (48 (~ 16)))
32
00010000 NOT decimal: 16 NOT
11101111 AND -17 AND (again, have in mind that integers are 32 bit and not 8 bit long)
00110000 = 48 =
00100000 32
Does this seem confusing? You betcha. Why not take advantage of the facts
that LOGAND returns 0 if the bit value we're searching for is not present
in the integer, and it returns the bit value itself if it is present in
the integer? This means we can simply subtract LOGAND's return value from
the integer itself:
(- 48 (logand 48 16))
32
For bits that are not set in the
integer, LOGAND will return 0 which doesn't harm the output. For example,
the 4th bit in the integer 47 is not set (in 47 bits 0, 1, 2, 3 and 5 are
all set, but not bit 4), thus LOGAND will return 0 in this case:
(- 47 (logand 47 16))
47
So, clearing a bit with LOGAND is easily done by subtracting (logand
num bit) from num. If clearing more than 1 bit from an integer, we can
simply add together the bit values. For example, to clear the bits 0, 2
and 3 (i.e. the integer bitvalues 1, 4 and 8) from 47:
(- 47 (logand 47 (+ 1 4 8)))
34
Now we can define a simple function that clears a bit from an integer:
(defun clearBit (num flag)
(- num (logand num flag))
)
If we look at the truth tables returned by BOOLE in the function nothingButTheTruth
above, it becomes obvious that BOOLE’s operator number 2 also can do the
job for us. It returns true if and only if the first bit is 1 and the
second bit is 0:
(defun clearBit (num flag)
(boole 2 num flag)
)
This function will perform exactly the way as the previous clearBit
function with LOGAND. It returns num with the flag value or values cleared
indicated by argument flag. For instance:
(clearBit 48 16)
32
00110000 BOOLE 2 decimal: 48 BOOLE 2
00010000 16 =
00100000 32
and
(clearbit 47 (+ 1 4 8))
34
For both functions, it is important that the order of arguments be obeyed.
(clearBit 16 48) is not the same as (clearBit 48 16). This
may seem like a trivial point, but when dealing with LOGAND and LOGIOR
where order of arguments is as indifferent as in arithmetic addition, it
should be mentioned.
By the way, to clear all bits
you can use the maximum integer 2147483647, or as returned by the
expression
(~ (expt 2 31)). This is only superficial information, though,
because it is much easier just to set the value to 0!
BOOLE operators
Not that it comes up often when
programming in AutoLISP (far from it), but when wanting a particular
logical operation besides NOT (logical), LOGAND and LOGIOR it will
sometimes be necessary to use BOOLE. Either in one operation or as nested
operations. In any case it would be much desired if the various operators
could be documented in a more precise way than Autodesk has done it. So
here’s a list of all 16 operators!
Where the operation can be
expressed by logical formulas, these formulas are shown in LISP style
format but with standard operator names. These names are NOT to be
confused with AutoLISP functions. Where order is essential, the first
input bit is always called A and the second is called B as shown in the
truth tables.
Operator 0: NULL
A
|
B
|
Out
|
0
|
0
|
0
|
0
|
1
|
0
|
1
|
0
|
0
|
1
|
1
|
0
|
NULL operator. Also called CLEAR as
it clears all inputs no matter the input bits.
Operator 1: AND
A
|
B
|
Out
|
0
|
0
|
0
|
0
|
1
|
0
|
1
|
0
|
0
|
1
|
1
|
1
|
This
operator is the same as the AutoLISP function
LOGAND.
Operator 2: AND-2 (in Common LISP called BOOLE-ANDC2)
A
|
B
|
Out
|
0
|
0
|
0
|
0
|
1
|
0
|
1
|
0
|
1
|
1
|
1
|
0
|
(AND A (NOT B))
Operator 3: Only A (in Common LISP
called BOOLE-1)
A
|
B
|
Out
|
0
|
0
|
0
|
0
|
1
|
0
|
1
|
0
|
1
|
1
|
1
|
1
|
(OR (AND A B) (AND A (NOT B))) = A.
This operator returns only first input bit.
Operator 4: AND-1 (in Common LISP
called BOOLE-ANDC1)
A
|
B
|
Out
|
0
|
0
|
0
|
0
|
1
|
1
|
1
|
0
|
0
|
1
|
1
|
0
|
(AND (NOT A) B)
Operator 5: Only B (in Common LISP
called BOOLE-2)
A
|
B
|
Out
|
0
|
0
|
0
|
0
|
1
|
1
|
1
|
0
|
0
|
1
|
1
|
1
|
(OR (AND A B) (AND (NOT A) B)) = B.
This operator returns only second input bit.
Operator 6: XOR (also called
Exclusive OR)
A
|
B
|
Out
|
0
|
0
|
0
|
0
|
1
|
1
|
1
|
0
|
1
|
1
|
1
|
0
|
Exclusive OR can be constructed
with this equation: (OR (AND A (NOT B))(AND (NOT A) B))
Operator 7: OR (also called
Inclusive OR)
A
|
B
|
Out
|
0
|
0
|
0
|
0
|
1
|
1
|
1
|
0
|
1
|
1
|
1
|
1
|
(OR A B). This operator is the same
as the AutoLISP function LOGIOR.
Operator 8: NOR (also sometimes
referred to as NOT-OR)
A
|
B
|
Out
|
0
|
0
|
1
|
0
|
1
|
0
|
1
|
0
|
0
|
1
|
1
|
0
|
(NOT (OR A B))
Operator 9: XNOR (also called
Exclusive NOR)
A
|
B
|
Out
|
0
|
0
|
1
|
0
|
1
|
0
|
1
|
0
|
0
|
1
|
1
|
1
|
(OR (AND A B) (AND (NOT A)(NOT B)))
Operator 10: NOT B (also known as
Inverting buffer for second bit)
A
|
B
|
Out
|
0
|
0
|
1
|
0
|
1
|
0
|
1
|
0
|
1
|
1
|
1
|
0
|
(NOT B). This operator discards
first input put and only returns the inverted second input bit. In Common
LISP it is called BOOLE-C2.
Operator 11: ? (in Common LISP
called BOOLE-ORC2)
A
|
B
|
Out
|
0
|
0
|
1
|
0
|
1
|
0
|
1
|
0
|
1
|
1
|
1
|
1
|
(OR A (NOT B))
Operator 12: NOT A (also
known as Inverting buffer for first bit)
A
|
B
|
Out
|
0
|
0
|
1
|
0
|
1
|
1
|
1
|
0
|
0
|
1
|
1
|
0
|
(NOT A). This operator discards
second input put and only returns the inverted first input bit. In Common
LISP it is called BOOLE-C1.
Operator 13: ? (in Common LISP
called BOOLE-ORC1)
A
|
B
|
Out
|
0
|
0
|
1
|
0
|
1
|
0
|
1
|
0
|
1
|
1
|
1
|
1
|
(OR (NOT A) B)
Operator 14: NAND (sometimes
referred to as NOT-AND)
A
|
B
|
Out
|
0
|
0
|
1
|
0
|
1
|
1
|
1
|
0
|
1
|
1
|
1
|
0
|
(NOT (AND A B))
Operator 15: SET (also known as
Identity)
A
|
B
|
Out
|
0
|
0
|
1
|
0
|
1
|
1
|
1
|
0
|
1
|
1
|
1
|
1
|
This operator has no formula
derived from other logical operations – it merely disregards any input
bits and returns a set bit.
To wrap it up...
With this document it's my hope that the use of bit coded values in
AutoCAD and to investigate, extract and alter them with AutoLISP is
somewhat covered and, more importantly, explained adequately to make use
of the topics in a practical way.
If you still want to explore and manipulate for example group code 70
values but you absolutely refuse to use logical operators then you could
begin to explore the ActiveX functionality, either in VLISP or VBA. Using
ActiveX, the properties of an entity are given by named constants, but
that is the only thing said on that matter in this document.
AutoCAD &
Binaries MS Word format.
AutoCAD & Binaries
PDF format.
To reserve the right to use
this document as it is in later context such as publications or otherwise,
it is hereby copyrighted by© 2001 Stig B. Madsen
Feel absolutely free to use any part of or all of the techniques and code
described in this document, unaltered or altered to suit any need. The
programmatic solutions and descriptions are by no means copyrighted by the
author - only use of the textual document as a singularity is a right
hereby reserved solely by the author.
If you should happen to claim any copyright to material in this document,
then by all means claim it by letting me know. But please have in mind
that the AutoLISP functions described here are as close to bare-boned
AutoLISP as possible, that the number of solutions given to each of the
above discussions are limited and that they probably already are declared
copyrighted by hundreds of authors who included them in similar routines
worldwide :-)
|