Bit operation of kotlin basic learning

What is bit operation?

All numbers in the program are stored in binary form in computer memory. Bit operation, to put it bluntly, is to directly operate on the binary bits of integers in memory. For example, the and operation is originally a logical operator, but the and operation can also be performed between integers. For example, the binary of 6 is 110 and the binary of 11 is 1011. Then the result of 6 and 11 is 2, which is the result of logical operation of binary corresponding bits (0 means false, 1 means true, and empty bits are processed as 0):

Because the bit operation directly operates on the memory data and does not need to be converted to decimal, the processing speed is very fast. Of course, some people will say, what's the use of this fast? Calculating 6 and 11 has no practical significance. This series of articles will tell you what bit operation can do, what classical applications there are, and how to optimize your program with bit operation.

introduction

This is really the foundation of the foundation. If you, like me, haven't studied the basic Java syntax before, it should be a bit silly for you. Not to mention the bottom layer, just from the perspective of Android programming, we still use bit operations frequently in encryption algorithms, network packet processing and other services, not to mention those various flags in intent. Therefore, it is very important to learn the basic knowledge in this regard

The examples in this series use kotlin's syntax, which is different from Java. Please refer to it

Unsigned and signed

In computers, types that can distinguish between positive and negative are called signed types, and those without positive and negative types are called unsigned types.

A byte is 8 bits. Starting from 0, its highest bit is bit 7. Similarly, the highest bit of 2 bytes is the 15th bit, and the highest bit of 4 bytes is the 31st bit. The types of different lengths have different highest bits, but they are all the leftmost ones.

In an unsigned number, all bits are used to directly represent the size of the value; The highest bit of a signed number is used to represent a positive or negative number, 0 is a positive number, and 1 is a negative number. Therefore, for the same byte, the maximum unsigned number is 255 and the maximum signed number is 127. The calculation of the maximum value of signed number is exactly the same as that of unsigned number, but the calculation method just now cannot be used in the range of negative number. In the computer, in addition to the highest bit of negative number being 1, it also adopts the form of complement, so the complement should be restored in the calculation

It is worth noting that there is no unsigned integer in the original type of Java. If you need to convert to an unsigned type, you can use ushr

Original code, complement code and inverse code

This is the knowledge taught in high school. I won't introduce it here

Remind me that negative numbers are calculated with complement, and the result is also complement. You need to subtract 1 to get the original code.

Bitwise Operators

Bit operation is mainly used when directly manipulating binary numbers, which can save memory and make your program run faster

Java defines bitwise operators, which can be applied to types such as integer (int), long, short, and byte. Bit operators act on all bits and operate on bits. Kotlin is slightly different from it. It does not provide special operators, only provides infix representation, and kotlin can only be used on int and long types. Remember this

Let's take an example

First look at the results, and then we analyze them one by one

As we know, int in Java is 4 bytes and 32 bits, so it should be necessary to convert A1, B1 and C1 into binary

Then there are the calculation rules of seven infix expressions

And if the corresponding bits are all 1, the result is 1, otherwise it is 0

Or if the corresponding bits are all 0, the result is 0, otherwise it is 1

XOR if the corresponding bit values are the same, the result is 0, otherwise it is 1

Inv flips each bit of the operand by bit, that is, 0 becomes 1 and 1 becomes 0

SHL shifts the specified number of bits to the left, which is equivalent to multiplying by 2 to the nth power. The omitted bits removed and the missing bits on the right are filled with 0

SHR shifts the specified number of bits to the right by bits, which is equivalent to dividing by 2 to the nth power. The removed bits are omitted. The missing bits on the left are supplemented by 0 if they are positive. If they are negative, they may be supplemented by 0 or 1, depending on the computer system used

Ushr shifts the specified number of bits to the right by bit, omits the removed bits, and complements the missing bits on the left with 0

So let's take a look at the result of bitwise calculation (omit the high-order repeated 0 or 1, and only look down eight bits)

Through the above rules, we can understand how the calculation results are obtained

There is a very interesting phenomenon. For a value of int type, whether you move left, right or unsigned right, as long as you move 32 bits, the effect is the same as that of no move. This is because in the shift operation in Java, because int occupies 32 bits, the number to be shifted is the modulus of 32. Therefore, when the value is shifted by 32 bits, it is equal to the value is shifted by 0 bits, which is equivalent to no shift. Similarly, for long type shifts, long occupies 8 bytes, that is, 64 bits, so the number of shifts is the modulus of 64

Application examples

There is a bit operation formula that you can remember:

To clear and reverse, use and, a certain position is available or

To reverse and exchange, use XOR easily

Judge whether int type variable a is odd or even

Get the k-th bit of int type variable (Note: K starts from 0, from right to left, the same below)

Clear the k-th bit of int type variable to 0

Set the k-th position of int type variable to 1

average value

Don't swap two integers with temp

Get absolute value

Get opposite number

Int to byte array

Complement zero extension and complement sign bit extension

Before we look at this problem, let's play a little game

Officer, please guess

Let me announce the answer

Can you explain why - 127 becomes 129? This involves complement zero extension and complement sign bit extension

As we know before, Java has no unsigned type. Byte is 8 bytes and int is 32 bytes. When byte is converted to int, 8 bits must be supplemented to 32 bits. The extension mode in Java is complement sign bit extension, so - 127 is still - 127 after complement sign bit extension, i.e. 11111111111111111111111111110000001. If zero filling extension is adopted, it is equivalent to 11111111 11111111 11111111 10000001 and 11111111. This value is 000000 000000 10000001, that is, 129

In order to deepen my memory, I'll leave another question for you to think about

These two expressions are also different when printed. Now you should be able to understand why they are different

To sum up

There are only signed numbers in Java. When byte is extended to short and int, because the sign bit is 0, the positive numbers are the same. In any case, it is zero complement extension; However, the results of negative zero complement extension and sign bit extension are completely different.

The complement sign bit is extended, and the original value remains unchanged. Zero complement extension is equivalent to treating signed numbers as unsigned numbers.

For signed numbers, sign bit extension is adopted by default. When expanding from small to large, you need to use and 0xff to ensure that it is expanded by filling zero; From large to small, the symbol bit is automatically invalid, so it does not need to be processed. If it is a char type, the zero padding extension is performed no matter what type it will be extended to

Reference articles

summary

The above is the whole content of this article. I hope the content of this article has a certain reference value for your study or work. If you have any questions, you can leave a message. Thank you for your support for programming tips.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>