Understanding the bitwise AND operator

Z

zirconx

I'm trying to understand how the bitwise AND can be used. I've read
about what it does but am having trouble applying it practically. I'm
working on a system that somebody else wrote and they make use of a
MODE flag that gets passed in. They then compare the mode flag against
a hard coded value using bitwise AND, and then show or don't show
certain features based on the mode. Example pseudocode:

if (mode & 1) do something

if (mode & 4) show this control

if (mode & 10) show this label

The values that mode is compared to include: 4, 8, 9, 10, 12, 14

I've been doing some testing and writing out the result of the bitwise
ANDs, and I'm not seeing a useful pattern. Sometimes it returns true
and sometimes false, I can't see how this is really being used.

Any tips appricated.
 
J

Jon Clements

I'm trying to understand how the bitwise AND can be used. I've read
about what it does but am having trouble applying it practically. I'm
working on a system that somebody else wrote and they make use of a
MODE flag that gets passed in. They then compare the mode flag against
a hard coded value using bitwise AND, and then show or don't show
certain features based on the mode. Example pseudocode:

if (mode & 1) do something

if (mode & 4) show this control

if (mode & 10) show this label

The values that mode is compared to include: 4, 8, 9, 10, 12, 14

I've been doing some testing and writing out the result of the bitwise
ANDs, and I'm not seeing a useful pattern. Sometimes it returns true
and sometimes false, I can't see how this is really being used.

Any tips appricated.

I take it you have stuff like:

const unsigned long can_read=1;
const unsigned long can_write=2;
const unsigned long can_delete=4;

(or perhaps even #define's to that effect - yuck)...


Jon..
 
D

Daniel T.

I'm trying to understand how the bitwise AND can be used. I've read
about what it does but am having trouble applying it practically. I'm
working on a system that somebody else wrote and they make use of a
MODE flag that gets passed in. They then compare the mode flag against
a hard coded value using bitwise AND, and then show or don't show
certain features based on the mode. Example pseudocode:

if (mode & 1) do something

if (mode & 4) show this control

if (mode & 10) show this label

The values that mode is compared to include: 4, 8, 9, 10, 12, 14

I've been doing some testing and writing out the result of the bitwise
ANDs, and I'm not seeing a useful pattern. Sometimes it returns true
and sometimes false, I can't see how this is really being used.

Any tips appricated.

0x0001 == 1
0x0100 == 4
0x1000 == 8
0x1001 == 9
0x1010 == 10
0x1100 == 12
0x1110 == 14

So you have 4 flags in the mode variable. "mode & 1 == true" means the
right most flag is set. "mode & 4 == true" means the second from the
leftmost flag is set. "mode & 10 == true" means the leftmost flag and
the second from the rightmost flag is set.

Well designed code that uses this idiom has some sort of define or
consts that give a name to each flag. For example:

enum { fail_bit = 1, eof_bit = 2, bad_bit = 4, good_bit = 8 };

if ( mode & fail_bit ) // you know the fail_bit was set
{ }

if ( mode & bad_bit ) // you know the bad_bit was set
{ }

if ( mode & ( good_bit | eof_bit ) ) // both the good_bit and eof_bit
{ } // were set, note the extra parens

The three ifs above match the three you posted.

Here is a nice web-site that explains the idiom:
<http://home.earthlink.net/~craie/122/notes/bit.flags.html>
 
M

Mark P

I'm trying to understand how the bitwise AND can be used. I've read
about what it does but am having trouble applying it practically. I'm
working on a system that somebody else wrote and they make use of a
MODE flag that gets passed in. They then compare the mode flag against
a hard coded value using bitwise AND, and then show or don't show
certain features based on the mode. Example pseudocode:

if (mode & 1) do something

if (mode & 4) show this control

if (mode & 10) show this label

The values that mode is compared to include: 4, 8, 9, 10, 12, 14

I've been doing some testing and writing out the result of the bitwise
ANDs, and I'm not seeing a useful pattern. Sometimes it returns true
and sometimes false, I can't see how this is really being used.

Any tips appricated.

It's just a way to make a bitset out of an integer. You have a bunch of
binary values which you pack together to form a single number and the
boolean ops let you read (and also write) those values. For example,
instead of:

bool flag1;
bool flag2;
bool flag3;
bool flag4;

I could have:

int flags;

And when before I would say:

if (flag3)...

now I say:

if (flags & 4) ...

because 4 = ...000100 in binary. Notably, the 1 is in the third
position (from the right) so it picks out flag3. To get flag4 I would
use 8 = ...0001000.

You can do "fancier" things too; for example, instead of:

if (flag1 && flag3 && flag4)

we can have:

if (flags & 13)

since 13 = ...0001101 with a '1' in positions 1, 3, and 4.

I think modern style would tend to prefer a more specialized container
for this purpose (perhaps a std::bitset) but this offers a fairly memory
efficient approach which may matter.
 
T

Thomas J. Gritzan

Daniel said:
0x0001 == 1
0x0100 == 4
0x1000 == 8
0x1001 == 9
0x1010 == 10
0x1100 == 12
0x1110 == 14

So you have 4 flags in the mode variable. "mode & 1 == true" means the
right most flag is set. "mode & 4 == true" means the second from the
leftmost flag is set. "mode & 10 == true" means the leftmost flag and
the second from the rightmost flag is set.

no, mode & 10 is true when one of the bits (or both) are set.
 
J

James Bannon

I'm trying to understand how the bitwise AND can be used. I've read
about what it does but am having trouble applying it practically. I'm
working on a system that somebody else wrote and they make use of a
MODE flag that gets passed in. They then compare the mode flag against
a hard coded value using bitwise AND, and then show or don't show
certain features based on the mode. Example pseudocode:

if (mode & 1) do something

if (mode & 4) show this control

if (mode & 10) show this label

The values that mode is compared to include: 4, 8, 9, 10, 12, 14

I've been doing some testing and writing out the result of the bitwise
ANDs, and I'm not seeing a useful pattern. Sometimes it returns true
and sometimes false, I can't see how this is really being used.

Any tips appricated.

Note: The following only applies for non-negative integers. When doing
bitwise operations you would be wise to restrict them to unsigned
integral types.

First, forget about thinking in decimal, it's much easier if you work in
binary (any decent desktop calculator will be able to do the conversion
- though it would be a considerable benefit for this kind of thing if
the language supported binary numbers directly).

Second, there is a simple way of writing out any integer in any valid
integer base using summation. For any n-digit binary number, N say, it's
decimal value can be computed as follows:

N = d(n-1) x 2^(n-1) + d(n-2) x 2^(n-2) + ..+ d(1) x 2^1 + d(0) x 2^0

(Damn plain text where you can't write subscripts properly). The
notation d(n - 1) is the digit (either 1 or 0 for the base 2) in bit
position n - 1. Counting from 0 (the least-significant bit position on
the right) this gives a total of n bits in the representation. E.g., 10
in decimal can be written as:

10 (decimal) = 1 x 2^3 + 0 x 2^2 + 1 x 2^1 + 0 x 2^0 = 1010 (base 2).

Now we can see what a bitwise and with the decimal value 10 will do
assuming we have, for simplicity, a total of 8 bits in the
representation this gives a binary value of 00001010. Applying the truth
table for the and operation, which looks like:

| 0 1
------------------
1 | 0 1
0 | 0 0

we can see that every 0 bit will reset the corresponding bit in the
argument to 0.

Thus 'if (mode & 10)' will be true (evaluate to non-zero) for any value
where either bit 1 or bit 3 in mode (counting from the left starting at
0) are 1. Some examples:

00001011 & 10100011 & 10100101 &
00001010 00001010 00001010
-------- -------- --------
00001010 00000010 00000000

Similar results apply with the remaining bitwise operators. Simply
convert the number to binary and then apply the truth table for the
operator.

I'll leave you to work out the rest.

Cheers
Jim.
 
J

James Bannon

James said:
Note: The following only applies for non-negative integers. When doing
bitwise operations you would be wise to restrict them to unsigned
integral types.

First, forget about thinking in decimal, it's much easier if you work in
binary (any decent desktop calculator will be able to do the conversion
- though it would be a considerable benefit for this kind of thing if
the language supported binary numbers directly).

Second, there is a simple way of writing out any integer in any valid
integer base using summation. For any n-digit binary number, N say, it's
decimal value can be computed as follows:

N = d(n-1) x 2^(n-1) + d(n-2) x 2^(n-2) + ..+ d(1) x 2^1 + d(0) x 2^0

(Damn plain text where you can't write subscripts properly). The
notation d(n - 1) is the digit (either 1 or 0 for the base 2) in bit
position n - 1. Counting from 0 (the least-significant bit position on
the right) this gives a total of n bits in the representation. E.g., 10
in decimal can be written as:

10 (decimal) = 1 x 2^3 + 0 x 2^2 + 1 x 2^1 + 0 x 2^0 = 1010 (base 2).

Now we can see what a bitwise and with the decimal value 10 will do
assuming we have, for simplicity, a total of 8 bits in the
representation this gives a binary value of 00001010. Applying the truth
table for the and operation, which looks like:

| 0 1
------------------
1 | 0 1
0 | 0 0

we can see that every 0 bit will reset the corresponding bit in the
argument to 0.

Thus 'if (mode & 10)' will be true (evaluate to non-zero) for any value
where either bit 1 or bit 3 in mode (counting from the left starting at
0) are 1. Some examples:

Correction: This should be counting from the right starting at 0.
 
M

Mark P

I said:
You can do "fancier" things too; for example, instead of:

if (flag1 && flag3 && flag4)

we can have:

if (flags & 13)

since 13 = ...0001101 with a '1' in positions 1, 3, and 4.

Noticing Thomas Gritzan's comment to Daniel T., I see I've made the same
mistake. The first conditional should be:

if (flag1 || flag3 || flag4)

to be equivalent to:

if (flags && 13)

-Mark
 
P

Pete Becker

Thomas said:
no, mode & 10 is true when one of the bits (or both) are set.

No, worse. mode & 10 will never equal true. The value true promotes to
the integer value 1. mode & 10 will be 2, 8, or 10. if(mode & 10) is not
the same as if((mode & 10) == true). mode & 10 is non-zero when either
of the bits is set.
 
D

Daniel T.

Mark P said:
Noticing Thomas Gritzan's comment to Daniel T., I see I've made the same
mistake. The first conditional should be:

if (flag1 || flag3 || flag4)

to be equivalent to:

if (flags && 13)

I guess it's pretty obvious that we don't use those kinds of constructs
very much. :)
 
J

James Bannon

Pete said:
No, worse. mode & 10 will never equal true. The value true promotes to
the integer value 1. mode & 10 will be 2, 8, or 10. if(mode & 10) is not
the same as if((mode & 10) == true). mode & 10 is non-zero when either
of the bits is set.

In Clause 4.12 paragraph 1 of the C++ standard we find:

"An rvalue of arithmetic, enumeration, pointer or pointer to member type
can be converted to an rvalue of type bool. A zero value, null pointer
or null member pointer value is converted to false: any other value is
converted to true."

and in Clause 6.3.1.2 paragraph 1 of the C Standard we find:

"When any scalar value is converted to _Bool, the result is 0 if the
value compares equal to 0; otherwise the result is 1."

mode & 10 is an integral rvalue and will be non-zero whenever either bit
1 or bit 3 (or both) in mode are 1. According to the both standards, as
I read them, ' if (mode & 10)' will evaluate to true (or 1) so long as
mode & 10 is non-zero or am I misreading them? If I am, how then do we
account for if (n) being true when n is non-zero (or non-null if a
pointer or pointer to member)?

Cheers
Jim.
 
T

Thomas Tutone

James said:
Pete Becker wrote:

In Clause 4.12 paragraph 1 of the C++ standard we find:

"An rvalue of arithmetic, enumeration, pointer or pointer to member type
can be converted to an rvalue of type bool. A zero value, null pointer
or null member pointer value is converted to false: any other value is
converted to true."

and in Clause 6.3.1.2 paragraph 1 of the C Standard we find:

"When any scalar value is converted to _Bool, the result is 0 if the
value compares equal to 0; otherwise the result is 1."

mode & 10 is an integral rvalue and will be non-zero whenever either bit
1 or bit 3 (or both) in mode are 1. According to the both standards, as
I read them, ' if (mode & 10)' will evaluate to true (or 1) so long as
mode & 10 is non-zero or am I misreading them? If I am, how then do we
account for if (n) being true when n is non-zero (or non-null if a
pointer or pointer to member)?

You're ignoring what Pete Becker actually said. He said: "if(mode &
10) is not the same as if((mode & 10) == true)." That is a true
statement, and in no way inconsistent with the clauses from the
standard that you quote. If you don't believe me (and I suspect you do
believe me, but simply didn't read Pete Becker's post carefully), then
consider the following program:

#include <iostream>
int main()
{
using namespace std;
unsigned char mode = 10;
if (mode & 10) cout << "true "; else cout << "false ";
if ((mode & 10)==true) cout << "true "; else cout << "false ";
cout << endl;
}

What do you think is displayed on standard output when you execute the
program?

Best regards.

Tom
 
O

Old Wolf

Daniel said:
0x0001 == 1
0x0100 == 4
0x1000 == 8
0x1001 == 9
0x1010 == 10
0x1100 == 12
0x1110 == 14

So you have 4 flags in the mode variable. "mode & 1 == true" means the
right most flag is set. "mode & 4 == true" means the second from the
leftmost flag is set. "mode & 10 == true" means the leftmost flag and
the second from the rightmost flag is set.

"mode & 4 == true" is not correct in C++, I think you mean to say
something like:

If (mode & 4) is nonzero the third from right flag is set.

In C++, == has higher precedence than &, so you end up with
mode & (4 == true), ie. mode & 0.

Further, even if you were to write:

(mode & 4) == true

it would fail: the bool is promoted to int, so it compares 4 == 1,
which is false.

Also you should talk about flags counting from the right; the OP
hasn't said how many bits are in 'mode' so we don't even know
where the left is!
 
P

Pete Becker

James said:
mode & 10 is an integral rvalue and will be non-zero whenever either bit
1 or bit 3 (or both) in mode are 1.

That's right.
According to the both standards, as
I read them, ' if (mode & 10)' will evaluate to true (or 1) so long as
mode & 10 is non-zero or am I misreading them?

That's essentially correct, but it slurs some details. My point was
about the literal constant 'true' as well as the semantics of if
statements. An if statement does not have a value. It selects a
statement based on the value of the controlling expression. if(mode&10)
selects the following statement if the value of mode&10 is not zero. Not
zero is not the same as the literal value 'true'. mode&10 will never
have the value 1, because the 1-bit will always be 0.
 
J

James Bannon

Thomas said:
You're ignoring what Pete Becker actually said. He said: "if(mode &
10) is not the same as if((mode & 10) == true)." That is a true
statement, and in no way inconsistent with the clauses from the
standard that you quote. If you don't believe me (and I suspect you do
believe me, but simply didn't read Pete Becker's post carefully), then
consider the following program:

#include <iostream>
int main()
{
using namespace std;
unsigned char mode = 10;
if (mode & 10) cout << "true "; else cout << "false ";
if ((mode & 10)==true) cout << "true "; else cout << "false ";
cout << endl;
}

What do you think is displayed on standard output when you execute the
program?

Best regards.

Tom
The output will be "true" and "false" respectively since the literal
'true' has the value 1 when converted from type bool (and I didn't need
to test it). I suppose the only excuse I have for missing the second
part is that it was late at night when I wrote it and that the first
part of the statement took me by surprise. Still it is confusing since,
in the context of its use here, (mode & 10) is true when converted to
type bool as it would be for any context where a control expression of
type bool is required as long as we're just considering the truth-value
of (mode & 10) and not its comparison with the literal true.

Jim.
 
H

Howard

Pete Becker said:
No, worse. mode & 10 will never equal true. The value true promotes to the
integer value 1. mode & 10 will be 2, 8, or 10. if(mode & 10) is not the
same as if((mode & 10) == true). mode & 10 is non-zero when either of the
bits is set.

I think he meant that (mode & 10) will evaluate as true in an if statement
when either bit is set, not that it would _equal_ true in a comparison. The
original snippets showed: "if (mode & 10) show this label", which will then
execute the "show this label" part whenever either of those bits is set.

-Howard
 
H

Howard

Howard said:
I think he meant that (mode & 10) will evaluate as true in an if statement
when either bit is set, not that it would _equal_ true in a comparison.
The original snippets showed: "if (mode & 10) show this label", which will
then execute the "show this label" part whenever either of those bits is
set.

D'oh! I didn't read far enough back, to see he was responding to someone who
_did_ use the == comparison with true. Never mind.

-Howard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top