[The principle of computer composition] The role of hexadecimal & 0xff

1. Why use hexadecimal

Computer hardware is 0101 binary, and hexadecimal is just a multiple of 2, which makes it easier to express a command or data.
The earliest ASCII character set is 8bit (later expanded, but the basic unit is still 8bit), 8bit can be expressed directly with 2 hexadecimals, no matter whatIt is more convenient to read and store than other bases

The CPU operation in the computer also follows the ASCII character set, and develops in such a way as 16, 32, and 64, so hexadecimal is better when data is exchanged.
In order to unify the specification, we see that the CPU, memory, and hard disk are all calculated in hexadecimal.

2. Some uses of the current hexadecimal system

In network programming, bytes need to be parsed during data exchange, which is a byte - by- byte process, and 1 byte can be expressed by two hexadecimals of 0xFF .
Data storage, stored in the hardware is the 0101 method, and the expression method stored in the system is the byte method.

The definition of some common values, such as the color expression in html that we often use, is the hexadecimal method used, and 4 hexadecimal digits can express millions of colors.

3. The role of &0xFF

First of all, we must know that it &means bitwise AND. Only when two bits are 1 at the same time can we get 1, which 0xrepresents a hexadecimal number, and the represented number occupies one byte 0xffin binary . 1111 1111And &the number that operates on it, the lowest 8 bits, will not change.

3.1 Get the lower eight bits

Usually used with the == shift operator >>==.

For example, in the length-based framing method in java socket communication, if the length of the sent information is less than 65535 bytes, the bytes of the length information are defined as two bytes in length. At this time, the two-byte length information is written to the memory in a Big-Endian manner

out.write((message.length>>8)&0xff);//右移8位,取高八位写入地址
out.write(message.length&0xff);//取低八位写入高地址中

For example, there is a number0x1234, if you only want to write the lower 8 bits to memory:0x1234&0xff

  • 0x1234represented as binary0001 0010 0011 0100
  • 0xffrepresented as binary1111 1111

The operation of two numbers will obviously be 0xffsupplemented to 16 bits, that is, the high bits will be supplemented with 0. At this time 0xffis 0000 0000 1111 1111.

AND operation 1&0 =0, 1&1 =1so that 0x1234only the lower eight digits can be reserved, 0000 0000 0011 0100that is0x34

3.2 Guarantee the consistency of complement code

We only care about the binary machine number and not the decimal value, so it byte &0xffis only a copy of its lowest 8 bits, which is usually used in conjunction with logic 或 |to achieve byte splicing, but does not guarantee that its decimal value remains unchanged.

public static void main(String[] args) {
    
    
	byte b = -127;//10000001
	int a =  b;
	System.out.println(a);
	a =  b&0xff;
	System.out.println(a);
}	//输出结果-127,129
using System;
using System.Text;
class Program
{
    
    
    static void Main(string[] args)
    {
    
    
        sbyte b = -127;
        int a = b;
        Console.WriteLine(a);
        a = b & 0xff;
        Console.WriteLine(a);
    }
}

At first glance, b is an 8-bit binary number, on top 0xff(that is 1111 1111,), isn't it itself, why is the output in the console result 129?
insert image description here

First of all, the storage in the computer is in accordance 补码存储with (if you don't know the complement code, you can see this original code, inverse code, complement code ), and the -127complement code is expressed as1000 0001

int a = b;

When the byte type is promoted to int, the b's complement is promoted to32 bitComplement the high order of the complement with 1, that is:

1111 1111 1111 1111 1111 1111 1000 0001

Convert the complement of negative numbers to the original codeThe sign bit does not changeInvert other bits

1000 0000 0000 0000 0000 0000 0111 1110

Add 1, the complement of the positive number, the inverse code is itself.

The result is
1000 0000 0000 0000 0000 0000 0111 1111that expressed as decimal is also -127.

that isbyte -> int guarantees that the decimal number remains unchanged, but sometimes, such as when the file stream is converted to a byte array,

We don't care about whether the decimal number has changed, but whether the complement has changed. At this time, we need to &go to the0xff

In this example, the byte is converted to int, and the upper 24 bits must be used 补1. At this time, the complement code obviously changes.
1111 1111 1111 1111 1111 1111 1000 0001

Then &, 0xffreset the high 24 to 0,
0xff:
0000 0000 0000 0000 0000 0000 1111 1111

The result is
0000 0000 0000 0000 0000 0000 1000 0001

so thatGuaranteed Consistency of Two's Complement,certainlySince the sign bit changes, the decimal number represented will change

It is the same as the original complement, but obviously the sign bit has changed, and the represented decimal number has changed to 129

Summarize

When the basic type is extended from a small to a large data type, the positive number is extended by zero-fill anyway because the sign bit is 0, but the zero-fill extension of a negative number is completely different from the extension of the sign bit of 1, so the negative number is extended with the sign bit of 1 to ensure that Decimal numbers don't change

For example, byte>>>int -127 is automatically extended according to the sign bit 1, and the sign bit is 1 in the upper 24 bits, and the represented decimal number remains unchanged.

The zero-pad extension ensures the consistency of the complement, but the decimal representation changes.

Guess you like

Origin blog.csdn.net/weixin_44394801/article/details/123079700