The conversion of single-byte data to multi-byte data in C language requires the sign bit to be complemented

In this article, we analyzed the range of uchar/char and the over-limit situation.

During the period, there is a phenomenon analyzed here as follows:

We found that the output of uchar in hexadecimal format is FF, but the output of char type in hexadecimal format is ff ff ff ff

    uchar ch1 = 0xFF;

    char ch2 = 0xFF;

    printf("%d,%d\n%X,%x\n",ch1,ch2,ch1,ch2);
    printf("%d",sizeof(int));

Analysis: The compiler is 32-bit, so it is ff ff ff ff, a total of 32 bits, 4 bytes. And because, for the char type, ff(1111 1111), the first bit is 1, so it is a negative number, so after expanding to 4 bytes, the front is all 1

For details, please refer to this article

The principle of complement sign:

If the data type is signed (such as char type), and the highest bit of the data is 1, when converted to a multi-byte number, the high bits are all complemented with 1, that is, the hexadecimal numbers are all F.

Including when the data is negative, such as int = -32768;

If the data type is unsigned (such as uchar type), all high bits are filled with 0s, that is, the hexadecimal numbers are all 0s, and the default is not to write.

In addition, the bit operation of char and multibyte (that is, when it is forced to multibyte) , and the following shift operations are also involved in the problem of sign complement.

The data stored in the computer is binary. If it is a positive number, the original code is stored (it can also be understood as a complement, because the original code of a positive number is the same as the complement). If it is a negative number, the complement is stored, which is summarized as,

1) The data stored in the computer are all complements ;

2) If the integer is a hexadecimal number, it means the complement; //char ch = 0xaa; 

3) If the integer data is a decimal number, it needs to be converted into a two's complement form (hexadecimal);

4) The same number is stored in the same data type with the same number of digits, and the stored binary (hexadecimal) is exactly the same, and no bit loss will occur. The final conversion to a decimal number or expansion to a multi-byte number is How much is determined by the form we want to analyze.

// char ch1=-1; uchar ch2 = -1; The binary stored in both is FF;

//printf("%x,%x",ch1,ch2);//The output is FF FF FF FF; FF

5) Data conversion process: uchar ch =-1; printf("%x,%d,%u",ch,ch,ch);

  • Compile on a 32-bit machine: -1 The default is int type, converted to binary: FF FF FF FF
  • The uchar bit is one byte, so the lower eight bits are truncated, which is FF;
  • According to the principle of complement sign, according to the rules of %x,%d,%u, parse the output;

For example:

   //十进制数显示问题
uchar ch1 =-1;
printf("%x,%d,%u\n",ch1,ch1,ch1);
char ch2 =-1;
printf("%x,%d,%u\n",ch2,ch2,ch2);
printf("*****************\n");

//十六进制数显示问题
uchar ch3 =0xAA;
printf("%x,%d,%u\n",ch3,ch3,ch3);
char ch4 =0xAA;
printf("%x,%d,%u\n",ch4,ch4,ch4);
printf("*****************\n");

//数据类型强转后数据显示问题
uchar ch5 = -1;
printf("%x,%d,%u\n",ch5,ch5,ch5);
char ch6 = -1;
printf("%x,%d,%u\n",(uchar)ch6,(uchar)ch6,(uchar)ch6);
printf("*****************\n");

//不同数据类型相互赋值后的显示问题
uchar ch7 = -1;
char ch8 = -1;

char ch9 = ch7;
uchar ch10 = ch8;
int ch11 = ch7;        //短字节扩展为长字节需要补符号位
uint ch12= ch7;        //短字节扩展为长字节需要补符号位
int ch13= ch8;         //短字节扩展为长字节需要补符号位
uint ch14 = ch8;       //短字节扩展为长字节需要补符号位

printf("%x,%d,%u\n",ch7,ch7,ch7);
printf("%x,%d,%u\n",ch8,ch8,ch8);
printf("%x,%d,%u\n",ch9,ch9,ch9);
printf("%x,%d,%u\n",ch10,ch10,ch10);
printf("%x,%d,%u\n",ch11,ch11,ch11);
printf("%x,%d,%u\n",ch12,ch12,ch12);
printf("%x,%d,%u\n",ch13,ch13,ch13);
printf("%x,%d,%u\n",ch14,ch14,ch14);

 

    short si = -32768;
    unsigned short usi=si;
    int i = si;
    unsigned int ui=usi;
    unsigned int ui2=-32768;
    unsigned int ui3=0xAA;
    printf("short:          decimal:%d  Hexadecimal:%x\n",si,si);
    printf("unsigned short: decimal:%d   Hexadecimal:%x\n",usi,usi);
    printf("int:            decimal:%d  Hexadecimal:%x\n",i,i);
    printf("unsigned int:   decimal:%d   Hexadecimal:%x\n",ui,ui);
    printf("unsigned int:   decimal:%d   Hexadecimal:%x\n",ui2,ui2);
    printf("unsigned int:   decimal:%d   Hexadecimal:%x\n",ui3,ui3);

 

    short svalue= -32769;
    printf("%d,%x\n",svalue,svalue);

 

 

 

Guess you like

Origin blog.csdn.net/modi000/article/details/113520144