Suppose there is a monthly check-in activity now, and you want to record the monthly check-in data of users. If it was you, how would you design this feature?
In Java, a variable of type int
occupies 4 bytes of space, and a byte has 8 bits (bit).
In other words, a variable of type int will take up 32b(it) of space. The value range of int: -231 ~ 231-1 (-2147483648~2147483647)
The maximum number of months in each month is 31 days. In February, basically [1]28 days in normal years and 29 days in leap years. They are all less than 32 (the 32 bits mentioned above).
Getting Started
Think about it, is it possible to use each bit of an int to store the check-in status of a certain day?
As shown in the figure below, assuming that there is a number 0 below, after converting it into binary, there are 32 0s, from the lowest digit to the highest digit, each number represents the check-in situation of a certain day:
E.g:
There is such an int number: 13030250, which is converted to binary as follows:
13030250(decimal)= 00000000 00110010 01101010 01101010(binary)
First of all, let’s set the rules, binary numbers, if a digit is 0, it means that it has not checked in, and if it is 1, it means that it has already checked in.
Combined with the converted binary numbers above (the signed-in data has been bolded). It can be seen that the 2nd, 4th, 6th, 7th, 10th, 12th, 14th, 15th, 18th, 21st, and 22nd days have already signed in (because the numbers in these digits are all 1), and the remaining days have not signed in .
When signing in, just change the number in the corresponding position to 1
. To put it in layman’s terms, if you sign in on the first day, change the number in the first position to 1, and if you sign in on the nth day, change the number in the nth position to 1.
After the above demonstration, it can be seen that this design is completely feasible.
Coding
Sign-in process
Before you start writing, you need to know the basic logic of bit operations. This is not complicated, so let’s not talk about it. Let’s talk about what is used in the project.
Let’s run the logic manually:
Suppose there is a variable value of 3351, ie: int value = 3351;
Convert it to binary: 3351(decimal) = 00000000 00000000 00000111 00010111(binary)
Then let’s take a look. The data of 00000000 00000000 00000111 00010111 indicates that the 1st, 2nd, 3rd, 5th, 9th, 10th, 11th day
of this month has signed in. The rest of the day was unsigned.
Then again, we want to make [2] sign-in on the fourth day, which is equivalent to a supplementary sign. How should we change it?
First of all, we already know the requirements, that is, the fourth day to sign in, so that is, to operate the fourth bit of this binary data, see the following example: in order to facilitate the demonstration, the high bits of 0 are discarded
Four kinds of operations are used above, and the operation rules are explained below:
- Shift left: Shift a few bits to the left, just add a few 0s at the end of the number
- Shift right: shift a few bits to the right and discard the lowest bits
- XOR operation: same as 0, different as 1
- Logical OR: As long as one is 1, it is 1
Convert above process to code:
Check sign-in
The sign-in has been mentioned above. Now let’s talk about how to check whether there is a sign-in on a certain day.
In fact, the check-in process is very similar to the check-in process, but the latter step is different.
In a nutshell, the sign-in process is:
And the check-in process is
Let’s walk through the process in detail: Let’s take the results calculated above as an example. The above calculation is: 11100011111. Now to judge whether there is a check-in on the third day, then:
Two kinds of operations are used above, and the operation rules are explained below (repetitions will not be explained):
- Logical AND: The result is 1 only if both numbers are 1
Let’s take another example to determine whether there is a check-in on the 7th day:
Let’s convert the above process into code: