?
Solved

How to use '&' in C++

Posted on 2003-02-19
4
Medium Priority
?
311 Views
Last Modified: 2012-08-14
I saw some very neat usage of '&' like:

int k;
int result=(k&2);

another example is:

int k;
int result=(k&1);

Can anyone explain to me how '&' works?

I tried to use cout<< to figure it out. For (k&2), result=0 when k=0, or k=1. If k>=2, it returns 2.

For (k&1), seems like when k is an odd number, it returns 1, otherwise, it returns 0.

Is that about right? Would you please give me more examples, so I can learn this trick.

Thank you

hfl
0
Comment
Question by:hfl
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
4 Comments
 
LVL 6

Expert Comment

by:gj62
ID: 7982415
Assuming that the operator is not overloaded, the following applies:

The bitwise-AND operator (&) compares each bit of its first operand to the corresponding bit of its second operand. If both bits are 1, the corresponding result bit is set to 1. Otherwise, the corresponding result bit is set to 0.

In the following example, the bitwise-AND operator (&) compares the bits of two integers, nNumA and nNumB:

// Example of the bitwise-AND operator
int nNumA=1, nNumB=3, nNumC; // 00000001, 00000011

nNumC = nNumA & nNumB;       // nNumC is now 00000001
0
 
LVL 6

Expert Comment

by:gj62
ID: 7982443
So, in your original post, k&2 will take the value of k and apply the bitwise-AND with 00000010 = 2.

Therefor, it will return 0 for any number that does not have the 2-bit set, but will return 2 for any number that has the 2-bit set.  For example:

Dec  Binary
1 = 00000001 - will return 0
2 = 00000010 - will return 2
3 = 00000011 - will return 2
4 = 00000100 - will return 0
5 = 00000101 - will return 0
6 = 00000110 - will return 2
etc...
0
 
LVL 12

Accepted Solution

by:
Salte earned 80 total points
ID: 7982481
The usage of & that you refer to there is the bit-wise and operation.

& comes in two flavors:

prefix operator &

   & var;

means the 'address of' var. If var is of type T then '& var' is the address of var and is of type 'T *'.

int x;

int * y = & x;

*y = 5; // set x to 5.

The other way to use & as operator is to use it as a binary operator. The binary & operator is predefined for integer data types and will do a bit-wise and of the operands.

k & 2 will return 0 if the bit 000000010 of the integer is 0 and will return 2 if the bit is set to 1.

if (k & 1) is a fast way to test if k is odd.
if ((k & 1) == 0) is a fast way to test if k is even.

It is often used if the integer k is used to hold flags, say bit 0 has one meaning and bit 1 another meaning and bit 2 and 3 together form a field with 4 possible values, then you can define the following:

enum {
   one_meaning = 0x01,  // 0001
   other_bit = 0x02,   // 0010
   field_mask = 0x0c,   // 1100
   field_val0 = 0x00,   // 0000
   field_val1 = 0x04,   // 0100
   field_val2 = 0x08,   // 1000
   field_val3 = 0x0c,   // 1100
};

Now if you have a char variable, that variable can hold those bits:

char flags;

flags = 0; // flags set to (00,0,0).
flags = one_meaning | field_val2; // flags = (10,0,1)
flags |= other_bit; // set bit 0010
flags &= ~one_meaning; // clear bit 0001
flags &= ~field_mask; // clear the bit mask field 00xx
flags |= field_val1; // set bit mask field to 1 (01,x,x)
flags ^= one_meaning; // toggle bit 0001
if (flags & other_bit) { // test if other_bit is set.

if (!(flags & other_bit)) { // test if other bit is cleared

switch (flags & field_mask) { // switch on field.
case field_val1: // field has 01xx
case field_val3: // field has 11xx
  break;
}

etc etc etc.

Bit manipulation is very easy using these operators:

a & b   - bitwise AND of a and b.
a | b   - bitwise OR of a and b.
a ^ b   - bitwise XOR of a and b.
~a      - invert bits of a.

~a will invert the bits so that all 1s becomes 0 and all 0s will become 1s:

~3 is a fast way to set all bits except the two lowest bits.

Example: Ensure that k is divisible by 4. I.e. add by a value 0-3 so that the result is divisible by 4:

k = (k + 3) & ~3;

if k was 8 the result is 8, if k was 9, 10 or 11 the result is 12, if k is 12 the result is also 12 but if k is 13, 14, 15 or 16 the result is 16 etc.

Bitwise manipulation is also often done in connection with shift:

a >> b   - will shift a right b times. I.e. it will move the bits down b places. The b topmost bits will be equal to the sign bit if a is a signed integer type and equal to 0 if a is an unsigned integer type.

a << b - will shift a left b times, i.e. it will move bits up b places, the lower b bits will be all 0 after the shift.

Unfortunately, C and C++ doesn't have an operator for rotate, however many implementations provide a _rotl() and _rotr() function for that and if you don't have it you can always do:

((k << 27) | (k >> 5)) // rotate left by 5 bits.

Rotate left by 5 is the same as rotate right by 27 for a 32 bit data type. Of course, if the integer type is 64 or 16 bits the shift counts must be different:

((k << 11) | (k >> 5)) // rotate 16 bit data left by 5 bits.


Hope this is of help for you.

Alf
0
 

Author Comment

by:hfl
ID: 7985160
Alf:

This is exactly what I am looking for. Thank you so much!

hfl
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question