All the numbers in the program are stored in binary form in the computer's memory. Bitwise operations operate directly on the bits of integers in memory. Because bit arithmetic operates directly on memory data, it does not need to be converted to decimal, so processing is very fast.
(1), and (&) operations
The & operation is typically used for binary take operations, such as the result of a number & 1, which is the last digit of the binary. This can be used to determine the parity of an integer, the last digit of the binary is 0 to indicate that the number is even, and the lowest of 1 indicates that the number is odd.
(2), or (|) operation
| Operations are typically used for unconditional assignment on binary positioning, such as a number | The result of 1 is to force the last binary into 1. If you need to turn binary last to 0, on this number | After 1 minus 1, the practical meaning is to force this number into the nearest even.
(3), XOR (^) operation
The "^" operation is typically used to reverse a particular one of the binary, because XOR can be defined as: 0 and 1 xor or 0 are unchanged, and XOR 1 is reversed.
The inverse of the "^" operation is itself, that is to say, two times or the same number the final result is unchanged, i.e. (a^b) ^b = A. The "^" operation can be used for simple encryption, such as you want to say to a friend 1314520, but afraid of others know, so the two sides agreed to take birthday 19800205 as the key, 1314520 ^ 19800205 = 20590165, so 20590165 told the friend. Your friend calculates the value of 20590165^19800205 again and gets 1314520, so it understands your intentions.
Addition and subtraction are mutually inverse, and addition satisfies the commutative law. Can write a swap function that does not require a temporary variable
void swap (int a, int b)
{
A = a + B;
b = a A;
A = a-B;
}
Since ^ 's inverse is itself, there is a very special swap process:
void swap (int a, int b)
{
A = a ^ b;
b = a ^ b;
A = a ^ b;
}
(4), take the inverse (~) operation
The definition of the "~" operation is to reverse all 0 and 1 in memory. Use the "~" operation with extreme caution and be aware that the integer type has no symbols. If the "~" object is an unsigned integer (which cannot represent a negative number), then the resulting value is the difference between it and the upper bound of the type. Because the number of unsigned types is represented by 00 to $FFFF. The following program returns 65435.
#include <stdio.h>
int main ()
{
unsigned short a = 100;
A = ~a;
printf ("%d\n", a);
return 0;
}
If the "~" Object is a signed integer, the situation is different and will be mentioned later.
(5), left shift (<<) operation
A << B means to shift A to binary and left B bit (add B 0 later). such as 100 of the binary is 1100100, and 110010000 turns to decimal is 400. It can be seen that the value of a<< B is actually a multiplied by 2 B, because adding a 0 after the binary number is the equivalent of multiplying the number by 2.
It is generally thought that a <<1 is faster than a * 2, because the former is a lower level operation, so multiply the 2 action in the program by using the left one instead.
Defining some constants may use the << operation. can be conveniently used (1 << 16)-one to represent 65535. Many algorithms and data structures require that the scale of the dataset must be a power of 2, which can be used to define constants such as Max_n in <<.
(6), right Shift (>>) operation
Similar to <<, a >> B represents the binary right shift B-bit (minus the last B-bit), which is equivalent to the B-squared (rounding) of a divided by 2. In addition, >> is often used instead of dividing by 2, such as binary lookup, heap insertion, and so on. Try to use >> instead of division operation, can make the program efficiency greatly improved. The greatest common divisor binary algorithm uses the 2 operation instead of the MoD operation, and the efficiency can be increased by 60%.
Common BITS transformation operations
Function |
Example |
Bit arithmetic |
Remove the last one |
(101101--->10110) |
X >> 1 |
Add a 0 at the end |
(101101--->1011010) |
X << 1 |
Add a 1 at the end |
(101101--->1011011) |
(x << 1) + 1 |
Turn the last one into 1. |
(101100--->101101) |
x | 1 |
Turn the last one into 0. |
(101101--->101100) |
(x|1)-1 |
The last one takes the reverse |
(101101--->101100) |
x ^ 1 |
Turn the right number k position into 1 |
(101001--->101101, k = 3) |
x | (1 << (k-1)) |
Turn the right number K position into 0 |
(101101--->101001,k = 3) |
X & ~ (1 << (k-1)) |
The right-number-K-position takes the inverse |
(101001--->101101,k= 3) |
x ^ (1 << (k-1)) |
Take the lowest three digits |
(1101101--->101) |
X & 7 |
Take the last K-bit |
(1101101--->1101,k = 5) |
X & ((1 << k)-1) |
Take the right number K-bit |
(1101101--->1, k = 4) |
x >> (k-1) &1 |
Turn the last K bit into 1 |
(101001--->101111, k = 4) |
x | ((1 << k)-1) |
End K-position inversion |
(101001--->100110, k = 4) |
x ^ ((1<<k)-1) |
Remove the rightmost 1 from the integer |
(100101111--->10010110) |
X & (X-1) |
Turn the right 1 into 0. |
(100101111--->100100000) |
X & (x + 1) |
Turn the first 0 of the right up into 1. |
(100101111--->100111111) |
x | (x + 1) |
Turn the right 0 into 1. |
(11011000--->11011111) |
x | (x-1) |
Remove the left of the first 1 from the right |
(100101000--->1000) |
X & (x ^ (x-1)) |
Take the right 1 consecutive |
(100101111--->1111) |
(x ^ (x+1)) >> 1 |
In the actual programming process, the different bits of an integer are often used to represent different data information. When the integer is accessed, a bitwise operation is required to obtain or change a certain number of digits of the integer. For example, create data structures to use when creating in Windows:
struct{
Pio_security_context SecurityContext;
ULONG Options;
USHORT pointer_alignment fileattributes;
USHORT shareaccess;
ULONG pointer_alignment ealength;
PVOID Eabuffer;
Large_integer Allocationsize;
}create;
The options are usually quoted as follows:
Data->iopb->parameters.create.options
ULONG Options is an unsigned long integer during the creation of a Windows file, indicating different options when creating and opening a file. Where the high 8 bits indicate the createdisposition parameter (such as File_open, file_create), the low 24 bits indicate the createoptions parameter (such as File_delete_on_close).
To get the value of the createdisposition, take the following bit action:
(Data->iopb->parameters.create.options >>) & 0x000000ff;
The value of createdisposition is obtained by moving the integer right 24 bits, and then with 0xFF.
(2) Place the nth position or clear zero.
#define BITN (1 << N)
Position: a |= bitn;
Qing 0: a &= ~bitn;
(3) Clear the rightmost 1 of the integer a
Method: A & (A-1)
Question: How to tell how many 1 are in the binary of an integer x?
int func (x)
{
int countx = 0;
while (x)
{
Countx + +;
x = x & (x-1);
}
return countx;
}
(4) align an integer to n:
A = (A + n-1) & ~ (n-1)
C Getting Started---bit arithmetic