Bitmap addition and subtraction multiplication and division
Let's briefly explain what our bitmap is
First of all, we can't avoid storing data in many cases during data processing. At this time, we will open up memory to create arrays to store our data
But let's take shaping as an example. int takes up 4 bytes of space,
Suppose I want to represent the data of 0-32. What you need to know is that one byte is 8 bits. Yes, we can represent our 32 bits through an integer. If the data we want to represent is between 0-31, we can do it with an integer
If we want to represent more data, we can create an array to store our data, which will save our space
If we want to express 0-1023 That's 1024 numbers 1024/32=32 If we prepare a 32 length array, we can represent 1024 numbers Then the elements in the first array can represent our 0-31 Is there any data between The function of bitmap is to make a collection 0-63 a%64===a&63 Because one of us num The data is actually%64 Is to get the last seven bits of their binary
Assuming that the range of data we want to represent is 0-1023, it is 1024
1024 / 32 = 32, then we can arrange an array with a length of 32
In this way, in fact, we have greatly reduced the complexity of our space by 32 times, which is almost 32 times
1. Create a bitmap
public BitMap(int max) { bits = new long[(max + 64) >> 6];//Here we determine how big we are and how big our data is }
2. Add a data
public void add(int num) { //How to put 170 into our array? //Num% 64 (this is the gain) = = = num & 63 //We try to put the position of the data to be placed as 1, which means that the data has entered //|=It is for our data to be set to 1 for processing bits[num >> 6] |= (1L << (num & 63));//This step is to set our data to 1, which means it has appeared //Because our binary position is that the last seven bits are our binary data, but in fact, our data is more than those. We only need to get our last seven bits
First of all, the first step is to find out where our 170 is located. First of all, we can locate where our data is located. There is no doubt. Then we need to turn the data of the specific location into 1, that is, which bit becomes 1
To be brief, Num & 63 = = = num% 64
Why? Because a data &63 will keep the last seven bits of the binary of that number intact, so we can get our remainder. The first bits will become 0, and only the last seven bits will be kept intact,
Then why do we take &63 instead of% 64? That's because the speed of bit operation is much faster than our normal% speed
Then the core of adding a data is to change the number of positions we determine from 0 to 1
So how to delete a data
First of all, we need to locate it at that position and turn it into 0
public void delete(int num) { //How to delete is to change the position we just changed to 1 to 0. I only care about this one. Just set it to 0 bits[num >> 6] &= (~(1L << (num & 63))); }
3. How to judge whether a data exists
//What we can determine first is where we want to deal with it, and then tell the truth public boolean contains(int num) { return (bits[num >> 6] & (1L << (num & 63))) == 0 ? false : true; }
This is also a process. Let's judge first. If the location is 0, it doesn't exist, otherwise it exists
addition
How to use bit operation to realize our addition
First of all, we need to know that an operation is a^b, which is the addition without carry
(A & B) < < 1 this is to get our carry information. Just add them together, but note that we can't add in the process of operation and processing, so we have to repeat the action just now until there is no carry
public static int add(int a, int b) { int sum = a; while (b != 0) {//When there is no carry sum = a ^ b;//This result is our non carry addition b = (a & b) << 1;//This is our carry data B - > b ' a = sum;//a->a' } return sum;//It's ok to return our sum value }
2. How to realize our subtraction??
Let's change b to - b
But you forgot we can't show the - number
So how to operate? First of all, we need to know a little common sense
The negative number of a number is equal to ~ a+1
Equal to this number, add 1 after bitwise negation
First, write a function to find the opposite number
public static int negNum(int n) { return add(~n, 1);//What is the negative number of a number equivalent to? Equivalent to our ~ n+1 }
Subtraction function debut
public static int sub(int a, int b) { return add(a, negNum(b)); }
multiplication
First, let's review that the direct multiplication of normal binary is
You may have been confused, but don't panic. Take your time and let's analyze it step by step
What does that mean? That is to say, we first observe the data of b. if it is 1, we will add a unopened, But when adding the second time, a wants to move to the left, because this is the law. Next time a continues to want to move to the left, b will move to the right, but it will move unsigned, because once it comes to moving to the right, if moving to the right is signed, our cycle will not end.
Code below
public static int mul(int a, int b) { int res = 0;//This represents our result while (b != 0) { if ((b & 1) != 0) { res = add(res, a);// } a <<= 1;//This is to move our a to the left b >>>= 1;//This is to move our b to the right to get its next bit. This is filled with 0 because > > > } return res; }
division
Here we can simply deal with division
public static int divide(int a, int b) { //But note that our system minimum cannot be converted into our positive number // We can only convert our data that is not the system minimum value. We can only convert the non system minimum value int x = isNegative(a) ? negNum(a) : a; int y = isNegative(b) ? negNum(b) : b; int res = 0; //Is x/y //011000 //000011 for (int i = 30; i >= 0; i = sub(i, 1)) {//This for loop also follows our subtraction principle if ((x >> i) >= y) {//If you directly shift 30 bits to the right, it can't be greater than our y, because the data will overflow directly res |= (1 << i);//This is to make our data become 1 x = sub(x, y << i);//Then our x moves the b data to the left } } return isNegative(a) ^ isNegative(b) ? negNum(res) : res;//If the judgment here is negative again //We will deal with negative numbers and implement our process. If not, we will deal with the opposite numbers }
Let's talk about our ideas
a/b=c
How do we get the value of c
a=1001
b=0010
c=?
Let's first move our a to the right to see when it will be greater than b
First, you can want to move 30 bits to the right and 29 bits......
We'll find two bits to the right
It is found that our data at this time is greater than
Then at this time, we can move the b image left by 2 bits for processing
This is just the opposite process
Then a becomes
0001 no matter how you move at this time, you won't succeed in subtracting
that
c=0100
Only the second place is 1
Then our operation process is over
The implementation idea of this is our first process, that is, how to improve our data and our process
Let's take a specific example to show our data flow
hypothesis
b=00110
c=01110
a/b=c
So our a=b × 21+b × 22+b × 2^3
We get the index above through the continuous movement of our data
So as to determine what location is our result data
0
Only the second place is 1
Then our operation process is over
The implementation idea of this is our first process, that is, how to improve our data and our process
Let's take a specific example to show our data flow
hypothesis
b=00110
c=01110
a/b=c
So our a=b × 21+b × 22+b × 2^3
We get the index above through the continuous movement of our data
So as to determine what location is our result data