>> "With that understood, looking at the above makes it very easy to understand..."
sorry, you may have to look at it in HTML or a non-proportional font, so the digits line up.
--
http://www.caddzone.com
AcadXTabs: MDI Document Tabs for AutoCAD 2008
Supporting AutoCAD 2000 through 2008
http://www.acadxtabs.com
"Tony Tanzillo" wrote in message news:5882965@discussion.autodesk.com...
With all due respect, your layman's explaination is as clear as mud 🙂
The concept is very easily understood when the explaination uses base-2 or binary notation along side base-10 notation:
Decimal Binary
1 00000001
2 00000010
3 00000011
4 00000100
7 00000111
12 00001100
And then, to illustrate binary math:
12 00001100
AND 5 00000101
--------------------------
4 00000100
12 00001100
OR 5 00000101
--------------------------
13 00001101
In this context, each digit in a binary number is called a 'bit'.
With that understood, looking at the above makes it very easy to understand that "AND" means that each bit in the output is 1, if the corresponding bits in both inputs are 1, and that "OR" means that each bit in the output is 1, if either (or both) cooresponding bits in each of the two inputs is 1.
In other words, you illustrate the basic concept in the same way you would do simple math with two numbers on paper, one digit at a time.
Never mind the exponential, or 'power of 2' gibberish, and the '+' operator, as that only makes the whole matter even more confusing to a beginner, who doesn't think about numbers in terms of exponents.
BTW, there is plenty of stuff on this out there on the .NET. Searching on 'Boolean' and 'bitwise' will turn up a lot of useful hits.
--
http://www.caddzone.com
AcadXTabs: MDI Document Tabs for AutoCAD 2008
Supporting AutoCAD 2000 through 2008
http://www.acadxtabs.com
"Kent Cooper" wrote in message news:5882774@discussion.autodesk.com...
I had a really hard time coming to understand what the AutoLisp bit-related (logand), (logior) and
(boole) functions actually DO, despite a lot of trying. I wanted something in English to get around
my lack of experience with programming outside AutoCAD. Help didn't do it for me (nor for a lot of
other people who've wondered about these on Newsgroup threads), or I wouldn't be posting this. I
searched the Newsgroup, and found some links to what ought to have been helpful website articles,
but they all seem to be obsolete. I looked at AfraLisp, Googled, and I was still at a loss, until I
messed with them enough to figure them out (sort of -- see below). But having figured at least most
of it out, I'm putting these Laymen's Explanations on record for the sake of others who, I hope,
will be able to find this a useful route into being able to USE these functions. They can be very
useful in the right situations, but I never used them until recently, because I didn't "get" how
they worked.
Preface:
All integers can be expressed as a unique sum of powers of 2, expressed here in the form
2-to-the-X-power = 2^X. For example,
7 = 1 + 2 + 4 [or 2^0 + 2^1 + 2^2]
42 = 2 + 8 + 32 [or 2^1 + 2^3 + 2^5]
64 = 64 [only, because it *is* a power of 2, namely 2^6]
etc.
This system is used to store things like AutoCAD System Variables that can be made of various
combinations of values, such as OSMODE, *because* of the fact that every value represents a unique
combination -- each Osnap mode is assigned a value that is a power of 2, and any possible
combination of Osnap modes is represented by its own unique sum.
Consider integers in terms of the collection of power-of-2 components, otherwise known as bits, that
make them up. [I will use the power-of-2 values themselves, because one finds them referred to with
different "bit numbers" in some sources, e.g. 8 seems to be called "bit 3" in some places, because
it's 2^3, and "bit 4" in other places, because it's represented by a 1 in the 4th position from the
right in a binary number.]
The "log" in (logand) and (logior) stands for "logical bitwise," meaning basically "when considered
in terms of the component bit values that make up the integers in question." "Boole" is the name of
a mathematician who's memorialized in a system of logical operations.
Laymen's explanation of (logand):
The "and" stands for the logical or Boolean "and" function, which [in AutoLisp-type terms] returns
True only if *every* thing being looked at has the characteristic being tested for -- this *and*
that *and* the other thing are *all* True, so the "and" combination is, too. If any of them are
*not* True, then neither is the combination.
The (logand) function, when applied to a set of integers is asking the question: "What power-of-2
component bits are a part of the makeup of *all* of these integers?" It returns an integer that is
the *sum* of all of those bits shared by *all* of the numbers being looked at.
So, to use Help's examples:
(logand 7 15 3) returns 3, because *all* of those numbers [1+2+4, 1+2+4+8, 1+2] are made up of
combinations that include a 1 and a 2 [which together constitute the 3 that is returned], and those
are the only bits that are contained in all of those numbers.
(logand 2 3 15) returns 2, because those numbers all have the 2 bit in them, and no others in
common.
(logand 8 3 4) return 0, because those numbers [8, 1+2, 4] share no common bits.
This can be used, for example, to determine whether a particular Object Snap mode is set. For
example, Intersection is represented by 32, so if the value of OSMODE is the sum of a combination of
bits that includes 32, then Intersection mode is set. The question is: "Do the number 32 and the
value of OSMODE share any bits?" [Since 32 is itself a power of 2, it's the only one they can
possibly share.] Or, in AutoLisp terms:
(logand 32 (getvar 'osmode))
That will return 32 if they do, that is, if Intersection mode is set, because 32 is the sum of all
the bits the two number share.
You can also look at combinations. For example, Endpoint is 1 and Midpoint is 2; you can ask
whether the sum of those [3] and OSMODE share any bits, the same way:
(logand 3 (getvar 'osmode))
If that returns 1, then Endpoint is set, but not Midpoint; if it returns 2, it's the other way
around; and if it returns 3, both are set.
Laymen's explanation of (logior):
The "ior" part stands for the Boolean "inclusive or" [sometimes just called "or"] function, which
returns True if *any* thing being looked at has the characteristic being tested for -- this *or*
that *or* the other thing is True, so the "or" combination is, too. It's only if *none* of them are
True that the combination therefore is not, either. It's "inclusive" because it includes the
possibility that *more than one* thing may be True, as opposed to the "exclusive or" function which
is True only if *just one* of the things being looked at is True, but *not* more than one of them.
The (logior) function, when applied to a set of integers is asking the question: "What power-of-2
component bits are a part of the makeup of *any* of these integers?" It returns an integer that is
the sum of all of those bits included in *any* the numbers being looked at.
So, to use Help's examples:
(logior 1 2 4) returns 7, because 1, 2, and 4 [which add up to 7] are all contained in at least one
of those numbers [and happen, in this case, to *be* the numbers themselves, which share no common
bits].
(logior 9 3) returns 11, because 9 = 1+8 and 3=1+2, so together they involve 1 [which happens to be
part of both of them, but doesn't get counted twice], 2, and 8, and those three bits add up to 11.
Laymen's explanation of (boole) [for two-integer comparisons]:
The operator bits in Help's "truth table," which are added together to make the 'operator' argument
in the function, are asking:
1 -- "For each bit value, is that bit a part of both of the integers being looked at?" The returned
integer includes that bit value if it's included in both.
2 -- "For each bit value, is that bit a part of the first number but not of the second?" The
returned integer includes that bit value if that's the case.
4 -- "For each bit value, is that bit a part of the second number but not of the first?" The
returned integer includes that bit value if that's the case.
8 -- "For each bit value, is that bit a part of *neither* number?" The returned integer includes
that bit value if it's not in either.
So, to use Help's examples:
(Boole 1 12 5) returns 4. The 1 operator is asking for bit values that are part of both 12 and 5.
They both include a 4, but have no other common bits, so 4 is returned.
(Boole 6 6 5) returns 3. The 6 operator = 2+4. The 2 component of that is looking for bits that
are part of the 6 but not part of the 5, and bit value 2 fits that description. The 4 component is
looking for bits that are part of the 5 but not of the 6, and bit value 1 fits that description.
[The 4 that is part of both numbers satisfies neither test.] The returned 3 is the sum of the 2 and
the 1 that those two components of the operator found.
(Boole 4 3 14) returns 12. The 4 operator is looking for bits that are part of the 14 but not of
the 3, and finds bit values 4 and 8. The 14 includes a 2, but since that's also part of 3, it isn't
included in the returned sum of 12.
The specific operator 6, as in (boole 6 x y), can be used to toggle bit values on and off in things
like System Variables, because if it finds a shared bit value, it doesn't include that in its
returned integer, but if it finds a value that's only in one number, it does include that. For
example, if you want to toggle Intersection mode [represented by 32] on or off within OSMODE, you
can do this [an approach found in many Newsgroup threads]:
(setvar 'osmode (boole 6 32 (getvar 'osmode)))
What it's doing is looking [with the 2 component of the 6 operator] for bit values that are in 32
but are not in OSMODE, and [with the 4 component] for bit values that are in OSMODE but are not in
32. [Combined, that's the "exclusive or" function -- looking for things that are in either one, but
not both.] If Intersection is set, the first check will *not* be satisfied, because 32 will be part
of *both* numbers. So the return will *not* include a 32, and Intersection will be removed from the
OSMODE combination. But the second check will find all the bit values that are in OSMODE but not in
32, which will include all other modes that are set, so the return will still include all of those.
If, on the other hand, Intersection is *not* set, the first check *will* be satisfed, because 32 is
part of only the first number checked. So the return will include a 32 [along with, again, all the
other values found by the second check], and Intersection will be *added* into the OSMODE
combination.
Questions arise about (boole) for more than two integers:
Help for (boole) implies at the beginning that you can look at *more than two* integers, but none of
its examples do, its truth table doesn't seem to allow for it, and no examples I found anywhere else
do. I have my suspicions about how that works, but welcome any better information:
(boole 1 a b c d) seems to find bits that are common to all the integers listed, but it's not really
"needed" because it's the equivalent of (logand a b c d):
(boole 1 1 3 5 7 9) returns 1, because that's the one bit value shared by all the numbers; some
other bits are shared by some, but not all, numbers;
(boole 1 3 5 12) returns 0, because while all the numbers share a bit with one of the others, no bit
is common to all.
(boole 2 a b c d) seems to find, as expected, bit values that are in the first integer, but in
*none* of the rest:
(boole 2 6 10 18) returns 4, which is in 6 and not in the others, but the 2 part of the 6 is in both
the others;
(boole 2 6 10 37) returns 0, because the 2 that's part of the 6 is also part of the 10, and the 4 in
it is part of the 37, so both bit values that make up the first number are disqualified. And since
the 37 is the third number, I infer that it is indeed looking at all numbers, not just the first two
as the truth table seems to imply.
(boole 4 a b c d) however, seems *not* to do what I expected, namely look for bits that are in the
last number but none of the others:
(boole 4 9 24 33 6) returns 6 as I expected, because none of the other numbers has the 2 or 4 bit
that make up that 6. That suggests that it is indeed the *last* number it's comparing the others to
[rather than the second, as in two-number comparisons], simply because none of the others can
contribute to that result. But:
(boole 4 15 24 33 6) also returns 6, despite the fact that the 15 contains both the 4 and 2 bit
values. However,
(boole 4 24 33 15 6) returns 0, suggesting that it compares the last number *only to the
next-to-last number,* and ignores the rest. Why this isn't analagous to the way the 2 operator
works, in reverse, I can't guess.
I was hoping that (boole 6 a b c) would function as a more-than-two-number "exclusive or" function,
finding bit values that are part of only one of the integers compared, however many there are. And
sometimes that seems to work, for example:
(boole 6 2 5 12) returns 11 -- 1 is part of only the 5, 2 is part of only the 2, [4 doesn't count
because it's part of both the 5 and the 12,] and 8 is part of only the 12; the result is 1+2+8 = 11.
Also, using (a b c) values involving one 1 and two 0's, in any combination, returns 1 [if any one of
the three includes 1, but not more than one of them, then 1 is part of the returned value], and one
0 and two 1's in any combination returns 0 [not 1, because 1 is part of more than one of the
integers]. But:
(boole 6 2 5 12 37 40) returns 6, which should mean that 2 and 4 are in only one number each. 1 is
in two of them, 2 is part of only the 2 [that's good], 8 is in two of them, 16 isn't in any of them,
and 32 is in two of them. But 4 is a part of the 5 and the 12 and the 37, so it "shouldn't" be part
of the returned value. If anyone knows anything about the "thought process" here, I'd appreciate
hearing about it.
An interesting thing happens with (boole 8), which Help does not use in any examples. If it's
looking for bit values that are not part of either integer (or any of them, if more than two are
compared), in theory it *could* accept all bit values higher than the highest integer, off to
infinity! But it doesn't do that. In two-number comparisons, it seems to find bits that are not
part of either number, and add them up [so far so good], then *subtract* the next bit-value beyond
the highest integer, and not look any further:
(boole 8 5 9) returns -14; 1, 4 and 8 are disqualified because they're part of at least one of the
integers, but 2 isn't, so it qualifies; 16 is the next bit value above 9; 2-16 = -14.
I haven't been able to find any pattern to suggest how it reaches a result from comparing more than
two numbers this way. But all the ones I've tried are positive, rather than negative as in
two-integer comparisons. Any ideas?
--
Kent Cooper