12-bit arithmetic
The C language is designed for the description system, so it should have some functions that are done by assembly language. C language has the features of high-level language and low-level language. Therefore, it has a wide range of uses and strong vitality.
12.1-bit operators and bitwise operations
operator meaning
& Bitwise AND
| Bitwise OR
^ Bitwise XOR OR
~ Take counter
<< left Shift
>> Right Shift
Description
(1) The bitwise operator is a two-mesh operator except for ~, which requires an operand on each side.
(2) The operation can only be an integer or character data, and cannot be a real data type.
12.1.1 bitwise-AND Operator &
The two systems that participate in the operation are carried out and operated in binary order. If the two corresponding binary number is 1, the result of just this bit is 1 otherwise 0 is:
0 & 0 = 0;0 & 1 = 0;1 & 0 = 0;1& 1 = 1
For example: 3 & 8 is not equal to 8, should be bitwise AND
3 = 00000011
5 = 00000101 &
00000001
So 3 & 5 is worth 1, and if participation & is negative ( -3 &-5), it is represented as a binary number in complement form. The bitwise AND operation is then performed.
Press-Pull with some special uses:
(1) Clear zero. If you want to clear a cell, even if all of its binary is 0, just find a binary number, where each bit meets the following criteria: The number of bits in the original 1, the corresponding bit in the new number is 0. Then make the two & operations, that can achieve the goal of 0 clear.
(2) Take some of the points in a number to locate. If there is an integer a (2 bytes) you want the low byte. Just put a with (337). Bitwise AND CAN.
(3) to which one to keep, with a number of the & operation, this number in the bit 1, if there is a number 01010100, want to put the left of the 3,4,5,7,8 can be this operation:
01010100
00111011 &
00010000
12.1.2 Bitwise OR Operator |
As long as one of the two corresponding binaries is 1, the result of that bit is 1.
0|0=0; 0|1=1; 1|0=1; 1|1=1;
A bitwise OR operation is commonly used to set a value of 1 for a certain bit of data, such as A is an integer (16 bits) with an expression A & 0377, then the low 8 bits are all 1. The high 8 bits are left intact.
12.1.3 xor operator ^
The XOR operator ^ is also known as the. The rule is that if the two binary numbers of the operation are the same, the result is 0 and the XOR is 1. namely 0^0=0; 0^1=1; 1^0=1;1^1=0;
The following examples illustrate the application of the ^ operator.
(1) Turn specific bits upside down
Suppose there are 01111010, want to make it low 4-bit flip, that is, 1 to 0, 0 to 1, you can do it with 00001111 ^ operation, that is,
01111010
00001111 ^
01110101
The lower 4 bits of the resulting value are just the flip of the low 4 bits of the original number.
(2) with 0-phase ^ retain original value
such as 012 ^ 00 = 012
00001010
00000000 ^
00001010
Because 1 and 0 in the original number ^ operations have 1,0 and 1 arithmetic 0, so the original number is preserved.
(3) Exchange two values without temporary variables
If a = 3, B = 4. To swap the values of a and B, you can use the following assignment statements:
A = a ^ b;
B = b ^ A;
A = a ^ b;
A = 011
b =//a = a ^ b;
A = 111//A = 7
b =//b = b ^ A;
b = 011//B = 3
A = 111//a = a ^ b;
A = 100//4
12.1.4 Inverse operator ~
~ is a first-order operator that is used to reverse a binary bitwise, changing 0 to 0. For example, ~25 is a bitwise inverse of the octal number 25 (that is, 00010101).
00000000 00010101
11111111 11101010 ~
The ~ operator has a higher precedence than arithmetic operators, relational operators, logical operators, and other operators, for example: ~a & B, First ~a and then &.
12.1.5 left shift operator <<
Used to move a number of binary all to the left several bits. For example:
A = a << 2;
The binary number of a is shifted to the left 2 bits, to the right 0, if a = 15, that is, the binary number 00001111, left 2 bits to get 00111100, that is, the decimal number 60.
After the high-left shift overflow, discard does not work.
Move left one equivalent to the number multiplied by 2. However, the conclusions are only applicable when the number of left-shifted high-dropped highs does not contain 1.
The left shift is much faster than the multiplication, and some C compilers automatically implement the operation with the 2 by the left.
12.1.6 Right shift operator >>
A >> 2 means moving the binary of a to the right by 2 bits. Move to the right end of the low is discarded, the number of unsigned, high 0. When a = 017:
A = 00001111 >> 2
00000011
Shift right one is equivalent to dividing by 2, and the right shift n is equivalent to 2^n.
When you move right, you need to be aware of the sign bit problem. For unsigned numbers, move left high to 0 when moving right. For signed values, if the original symbol bit is 0 (the number is positive), then the left is also moved in 0, if the previous example indicates that if the symbol bit is originally 1 (the number is negative), then the left-hand side of the 0 or 1, depending on the computer system used. Move in 0 is called logical right SHIFT, that is, simple right shift. Moving in 1 is called arithmetic right shift.
12.1.7-bit Operation assignment operator
The bitwise operator and the assignment operator can form compound assignment operators.
such as: &=, |=, >>|, <<=, ^=
12.1.8 bit operations with different lengths of data
If two data lengths are different (for example, long and int) when bitwise operations are performed (such as A & B and A is long and b is int), the system aligns the two on the right side. If B is positive, the left 16 bits fill 0. If B is negative, the left should fill 1. If B is an unsigned integer type, the left side is filled with 0.
Example of a 12.2-bit operation
Take an integer a from the right end of the 4~7 bit
(1) First move A to the right 4 bits
A >> 4;
(2) set a low 4 bit is all 1, the rest is 0 of the number, can be implemented in the following ways:
~ (~0<<4)
~0 all binary is 1, left 4 bits, so that the right side is 4 bits low 0.
(3) Perform & operations on the above.
A >> 4 & ~ (~0<<4)
#include <stdio.h>
void Main ()
{
Unsigned A, B, C, D;
scanf ("%o", &a);
b = a >> 4;
c = ~ (~0<<4);
D = b & C;
}
Cyclic shift
#include <stdio.h>
void Main ()
{
Unsigned A, B, C;
int n;
scanf ("A=%o, n=%d", &a, &b);
b = a << (16-n);
c = a >> n;
c = C | b
printf ("%o\n%o", A, c);
}
12.3-bit segment
Previously introduced access to in-memory information, access is generally in bytes, in fact, sometimes storing a message does not have to use one or more bytes, for example, true or false with 0 or 1, only 1-bit, in the computer for process control, parameter detection or data communication field, Control information often takes one or more binaries in one byte, often putting a few bits of information in the byte.
The following two methods can be used to assign and change the value of one or more of the two in one byte:
(1) A few items can be set artificially in two bytes of data. For example A, B, C, and D are 2-bit, 6-bit, 4-bit, 4-bit respectively. If you want to change the value of C to 12 (set originally to 0)
A. Move the number 12 to the Left 4, so that 1100 to the right from the 4th ~ 7 bits.
B. Press data with << 4 to make the value of C change to 12.
(2) Bit segment
The C language allows you to specify the memory length of a member as a unit in a struct, which is called a bit-or-bit field, and the bits can be used to store data with fewer digits. For example:
struct Packed_data
{
unsigned a:2;
unsigned b:6;
unsigned c:4;
Undigned D:4;
int i;
}data;
Where A, B, C, D are 2-bit, 6-bit, 4-bit, 4-bit, and I-integer.
You can also make individual bit segments not exactly full of one byte. Such as:
struct Packed_data
{
unsigned a:2;
unsigned b:3;
unsigned c:4;
int i;
};
struct Packed_data data;
Where a, B, and C account for 9 bits, which account for 1 bytes and less than 2 bytes, it is followed by an int type. The 7-bit space after a, B, C is unused, and I store it from the start of a byte.
Note that in the storage unit, the spatial allocation direction of the bit segments, depending on the machine, in the computer used by the C system, usually from right to left allocation, but users can not ask this detail.
A method for referencing data in a bit segment. Such as:
DATA.A = 2;
DATA.B = 7;
DATA.C = 9;
Note the maximum allowable range of bit segments if written
DATA.A = 8;
Is wrong, because the DATA.A only occupies two bits, the maximum value is 3. In some cases, the low number of automatically assigned numbers. For example, 8 of the binary form is 1000, and data.a only 2 bits, take 1000 low 2 bits, so data.a value 0.
Description of the definition and reference of a bit segment:
(1) The type of the bit segment member must be specified as unsigned int type.
(2) If a segment is to be stored from another word. Can be defined in the following form
unsigned a:1;
unsigned b:2;
unsigned:0;
unsigned c:3;
Originally a, B, C should be kept in a storage unit, due to the length of 0 bits, its role is to make the next bit from the next storage unit to store, so now only a, b is stored in a storage, c and stored in the next unit.
(3) A bit segment must be stored in the same storage unit, cannot span two units, if the first cell space cannot accommodate the next bit segment, then the space is not used, and the next cell holds the bit segment.
(4) You can define a no-name field. Such as:
unsigned a:1;
Unsigned:2;
Unsigned b:3;//this two-bit space is not
unsigned c:4;
(5) The length of the bit segment cannot be greater than the length of the storage unit, nor can it define a bit segment array.
(6) Bit segments can be output in integer format. Such as:
printf ("%d,%d,%d", DATA.A, data.b, DATA.C);
Of course, can also use%u,%o,%x, and other formats output.
(7) A bit segment can be referenced in a data expression, which is automatically converted to an integer number by the system. Such as:
DATA.A + 5/data.b
is legal.
Bitwise operations (reproduced)