Bitmap addition and subtraction multiplication and division

Posted by StirCrazy on Thu, 24 Feb 2022 17:43:38 +0100

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

Topics: Java Eclipse