Take you to understand & 0xff in the process

When writing large assignments, the operation of & 0xff was always in doubt.
byte [i] is 8-bit binary, and 0xff converted to 8-bit binary is 11111111, so is n’t byte [i] & 0xff still byte [i] itself?

Are you kidding me?
Convert four bytes to an int type
For this problem, I saw a demo online is very interesting:

#include<stdio.h>
int main(void)
{
     char byte = -127;
     int a;
     a = byte;
     printf("%d\n", a);
     a = byte & 0xff;
     printf("%d", a);
     
     return 0;
}

However ~
Insert picture description here
things started to get interesting ...

Why is it wrong to add & 0xff?

Let's review the concept of complement first :

For the original code of positive number (00000001), the first bit represents the sign bit, and the inverse and complement are both themselves.
For the original code of negative number (100000001), the inverse code is to invert the original code except the sign bit (111111110) Then do the +1 operation ie (111111111)

Then introduce the concept of symbol expansion :

Taking 8-bit binary numbers as an example, sign extension refers to converting them into 16-bit and 32-bit binary numbers while keeping the current value unchanged. The rule is that no matter whether it is a positive number or a negative number represented by a complement, all you need to do is fill in the high-order bits with the value of the sign bit (0 or 1).

Into the title:

When -127 is assigned to byte, byte is a char type, and its computer's complement is 10000001 (8 bits) [in computers, negative numbers are stored in the form of complements].

  a = byte;//-127

When the byte was first output to the console as an int type, the compiler made a sign expansion process. Because the int type is a 32-bit binary number, the complement of byte expansion is 1111111111111111111111111 10000001 (32-bit), this The decimal number represented by 32-bit two's complement is also -127. This means that sign expansion does not affect the current value of the corresponding decimal number.

This is a very good property, but when we convert the char type to int type, the purpose is not only to ensure the invariance of the corresponding decimal number. For example, our big job this time is to convert 4 char types into 1 int type, which needs to ensure the consistency of two's complement, that is, the binary 01 sequence corresponding to 4 char types is intact As a binary sequence of 4 bytes of the int type (the upper eight bits among the eight bits and the lower eight bits).

    a = byte & 0xff;//129

So why do we change the value of a the second time we assign values?
Let's analyze it in detail:
before introducing the concept of symbol expansion, when byte ( 10000001 ) is to be converted to int, the high 24 bits will inevitably be filled with 1. In this way, its two's complement has actually changed. While & 0xff ( 11111111 ) can change byte to int, the upper 24 bits are set to 0, and the lower 8 bits remain as they are.

Then some students may be wondering: Why wouldn't the 24 bits that are 0xff as high as 1? This is because 0xff or 0xFF itself is an int literal constant, which is 32 bits long, so it will not be sign extended.

Of course, when I want to ensure the consistency of the two's complement, the decimal number corresponding to the binary number naturally changes. It is impossible to have both ~

Let's take a look at the specific implementation of the code:

    a = byte & 0xff;//129

byte & 0xff = 111111111111111111111111110000001 & 11111111
= 000000000000000000000000 10000001The

binary digit weight is 129.

This is a good explanation for why adding & 0xff results in an error:

Because the program at this time ensures the consistency of the two's complement rather than the consistency of the corresponding decimal number.

At last

Let's go back to the problem of the conversion algorithm for large jobs. We want to ensure the consistency of two's complement, so we must first perform & 0xff operation on byte. Of course, if the sign bit of byte is 0, then & 0xff is meaningless. But when the sign bit of byte is 1, you need to weigh it, because you are finally going to perform a logical OR operation with value (a high probability that the binary sequence you have worked hard to get will all become 1. )! !

Published 1 original article · praised 7 · visits 153

Guess you like

Origin blog.csdn.net/Ziyang1060/article/details/105567083