AfraLisp Blog

The AutoLisp/Visual Lisp/VBA Resource Website

AfraLisp Blog

Home Newsletter Utter Rubbish Coding Tips AutoCAD Tips Contact Downloads WAUN

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 :-)

 
The AutoLisp/Visual Lisp/VBA Resource Website

Copyright © 1999-Perpetuity by AfraLisp

All rights reserved.
Information in this document is subject to change without notice.
Site created and maintained by Kenny Ramage

The AutoLisp/Visual Lisp/VBA Resource Website