[Java Basics] 14. bitwise operations-bitwise AND (&) operations-(fast modulo algorithm) and java Basics 14 Operations
The redis dictionary structure is learned. The hash Value & sizemask operation is used when the hash is used to find the index value of the slot,
The subsequent scan operations involve the scanning sequence logic. The slots in the same model are scanned according to certain rules!
It involves the relationship between bitwise operations and % operations! Therefore, sort out the learning materials as follows:
From: http://blog.sina.com.cn/s/blog_7b7cad23010163vy.html
Bitwise operations directly perform operations on memory data and do not need to be converted to decimal. Therefore, the processing speed is very fast.
Bitwise AND, the operator number is &
Result of a & B operation: if the corresponding bits in a and B are both 1, the corresponding result bits are also 1,
For example:
10010001101000101011001111000
& 111111100000000
---------------------------------------------
101011000000000
For 10101100000000Right Shift 8Bit returns 101011In this way, a is obtained.8 ~ 15Bit mask.
Based on this revelation, determine whether an integer is between 0-65535 (2 ^ 16) (commonly used cross-border judgment ):
Generally (a> = 0) & (a <= 65535) may take two judgments.
Only one bitwise operation is required:
A &~ (1 <16)-1)
123456 |
Ex: 1 0000 0000 0000 0000 //1 << 16 = 65536 0 1111 1111 1111 1111 //(1 << 16) -1 = 65535 1111 11... 0000 0000 0000 0000 // Previous result ~ Operation. If the value is set to 1 at a high position, the value is 0 at a position smaller than 65536, a & 1111 .. 0000 0000 0000 0000 // True, indicating that there is a high value, greater than 65535 |
The following constants are good at compilation. In fact, you only need to calculate the logic and the line.
Common tips:
1. used to judge the parity of Integers
An integer a, a & 1 can be used to determine the parity of. The last bit of binary is 0, indicating an even number. The last bit of binary is 1, indicating an odd number. Use a % 2 to determine that parity is the same as a & 1, but a & 1 is much faster.
2. Determine whether n is a positive integer of 2.
(! (N & (n-1) & n
For example:
If n = 16 = 10000, n-1 = 1111
So:
10000
& 1111
----------
0
For another example, if n = 256 = 100000000, n-1 = 11111111
So:
100000000
& 11111111
--------------
0
Good! After reading the two small examples above, I believe everyone has a perceptual knowledge. Theoretically, if a number a is a positive integer power of 2, the binary form of a must be 1000 ..... (There are 0 or more 0 at the end), then the conclusion is obvious.
3. count the number of 1 in n
The simple statistical method is: first judge the parity of n, increase the counter by 1 when it is an odd number, then shift n to the right, repeat the above steps until the shift is complete.
The simple statistical method is relatively simple, so let's look at the more advanced method.
For example, consider the two-digit binary number n = 11, there are two 1 inside, first extract the even number 10 inside, odd number 01, shift the even number one to the right, then add the odd digits. Because the sum of the odd and even bits of each pair does not exceed "two", the number of 1 in n is saved in the result; if n is a four-digit integer n = 0111, extract the odd and even bits in the unit of "One bits", and then add the even displacement bits (shifted one bit right; perform parity extraction in the unit of "two", and shift the even number of locations (two places need to be removed at this time). The sum is added because the sum of the non-parity bits does not exceed the "four bits ", therefore, the number of 1 in n is saved in the result, and more n algorithms can be obtained by analogy. The whole idea is similar to divide and conquer.
Here is the commonly used binary number:
0 xAAAAAAAA = 10101010101010101010101010101010
0x55555555 = 1010101010101010101010101010101 (the odd digit is 1, and the parity is extracted in 1 bits)
0 xCCCCCCCC = 11001100110011001100110011001100
0x33333333 = 110011001100110011001100110011 (the parity is extracted in the unit of "2 bits)
0xF0F0F0F0 = 11110000111100001111000011110000
0x0F0F0F0F = 1111000011110000111100001111 (the parity is extracted in 8 bits)
0xFFFF0000 = 11111111111111110000000000000000
0x0000FFFF = 1111111111111111 (the parity is extracted in 16 bits)
For example, the number of 1 of the 32-bit unsigned number can be as follows:
Int count_one (unsigned long n)
{
// 0 xAAAAAAAA, 0x55555555, respectively, the parity is extracted in the unit of "1 bit"
N = (n & 0 xAAAAAAAA)> 1) + (n & 0x55555555 );
// 0 xCCCCCCCC and 0x33333333 respectively extract the parity bits in the unit of "2 bits"
N = (n & 0 xCCCCCCCC)> 2) + (n & 0x33333333 );
// 0xF0F0F0F0 and 0x0F0F0F0F respectively extract parity bits in units of "4 bits"
N = (n & 0xf0f0f0)> 4) + (n & 0x0f0f0f );
// 0xFF00FF00 and 0x00FF00FF are respectively used to extract parity bits based on "8 bits"
N = (n & 0xFF00FF00)> 8) + (n & 0x00FF00FF );
// 0xFFFF0000 and 0x0000FFFF are used to extract parity bits in 16 bits.
N = (n & 0xFFFF0000)> 16) + (n & 0x0000FFFF );
Return n;
} For example, if my birthday is lunar calendar month February 11, use 211 to convert it to binary:
N = 11010011
Calculate n = (n & 0 xAAAAAAAA)> 1) + (n & 0x55555555 );
Obtain n = 10010010
Calculate n = (n & 0 xCCCCCCCC)> 2) + (n & 0x33333333 );
Obtain n = 00110010
Calculate n = (n & 0xf0f0f0)> 4) + (n & 0x0f0f0f );
If n = 00000101 ------------------- à cannot be further divided, then 5 is the answer.
4. modulo operation of positive integers (note that negative numbers cannot be calculated in this way)
The following is a simple example:
Multiplication and division consume a lot of time. As long as the logarithm is shifted to the left by 2 and the right by 2, the bitwise operation efficiency is increased by 60%.
Take 2 ^ k as we all know: n <k. So in the future, will you be silly enough to knock 2566*4 and the result is 10264? It can be done directly at 2566 <4, which is fast and accurate.
Except 2 ^ k, we all know that n> k.
What about mod 2 ^ k? (Modulo the multiples of 2)
N & (1 <k)-1)
To describe it in plain words, just perform bitwise AND operation on the multiples of 2 as long as the multiples of number and 2-1.
Good! For ease of understanding, let's take an example.
Think: if the result is a modulo of 2 ^ k, do we really need to perform the modulo every time?
It is easy to think of the Rapid power modulo method.
Fast modulo Algorithm
I often encounter the case that I want to calculate a ^ B mod c when I do the question. At this time, I am not careful about it. How can this problem be solved? Bits help you.
First, let's introduce the qinjiu algorithm: (numerical analysis is clear)
Take an n times polynomial f (x) = a [n] x ^ n + a [n-1] x ^ (n-1) + ...... + a [1] x + a [0] is rewritten as follows:
F (x) = a [n] x ^ n + a [n-1] x ^ (n-1) + ...... + a [1] x + a [0]
= (A [n] x ^ (n-1) + a [n-1] x ^ (n-2) +... + a [1]) x + a [0]
= (A [n] x ^ (n-2) + a [n-1] x ^ (n-3) + ...... + a [2]) x + a [1]) x + a [0]
= ......
= (...... (A [n] x + a [n-1]) x + a [N-2]) x + ...... + a [1]) x + a [0].
When calculating the polynomial value, calculate the value of a polynomial in the inner bracket, that is
V [1] = a [n] x + a [n-1]
Calculate the value of a polynomial layer by layer from the inside and out, that is
V [2] = v [1] x + a [N-2]
V [3] = v [2] x + a [n-3]
......
V [n] = v [n-1] x + a [0]
In this way, the value of the n polynomial f (x) is converted to the value of the n polynomial.
Good! With the basic knowledge above, let's start solving the problem.
By (a × B) mod c = (a mod c) × B) mod c.
We can first describe B's achievements:
B = a [t] × 2 ^ t + a [T-1] × 2 ^ (t-1) + ...... + A [0] × 2 ^ 0. (a [I] = [0, 1]).
In this way, we use a ^ B mod c = (a ^ (a [t] × 2 ^ t + a [T-1] × 2 ^ (t-1) +... A [0] × 2 ^ 0) mod c.
However, we can find a ^ (2 ^ (I + 1) mod c = (a ^ (2 ^ I) mod c) ^ 2 mod c.
The specific implementation is as follows:
Using the idea of the Qin JIU Algorithm for Fast Power modulo algorithm, simple and elegant
// Quickly calculate the value of (a ^ p) % m
_ Int64 FastM (_ int64 a, _ int64 p, _ int64 m)
{
If (p = 0) return 1;
_ Int64 r = a % m;
_ Int64 k = 1;
While (p> 1)
{
If (p & 1 )! = 0)
{
K = (k * r) % m;
}
R = (r * r) % m;
P> = 1;
}
Return (r * k) % m;
}
Http://acm.pku.edu.cn/JudgeOnline/problem? Id = 3070
5. Computing mask
For example, a mask with a minimum of six bits: 0 × 3F
This is represented by bitwise operations: (1 <6)-1
This is also a good way to read the mask, because the number of digits of the mask is directly reflected in the expression.
Bitwise OR is simple. As long as the corresponding bits in a and B appear 1, the result of a | B is also 1. I will not go into detail.
6. subset
Enumerate a subset of a set. If the original set is set to mask, the following code can list all its subsets:
For (I = mask; I = (I-1) & mask );