Talking about the bit-shift operation of negative numbers in c language

Recently, a friend used the negative shift of hexadecimal numbers in the program (the compiler is gcc). I was curious for the first time, so I did some research.

Negative bit-shifting of a number is non-standard, but possible.
Specific example:
char tmp = 0x10;
tmp = tmp << -1;
Guess what the result is, some people guess that tmp is shifted by -1 bit to the left, isn't it shifted by 1 bit to the right? The result is 0x01?
Unfortunately, computers and human brains are not the same. result is 0
why? In order to find out why, I did some small tests and made solid results.

Since I know the difference between +0 and -0, I first set tmp << -128 (-128 is -0), as I guessed, the result is 0x10
And -128 in binary is 1000 000b
Continue, set tmp << -127, the result is 0x20, shifted 1 bit to the left
-127 in binary is 1000 0001b
Can't wait, tried tmp << -126, the result is 0x40, shifted left by 2 bits
-126 in binary is 1000 0010b
At this time, everyone should have seen the clue like me, but don't say it, let's see that they move to the right by the same value:
First put tmp >> -128 (-128 is -0), the result is 0x10
And -128 in binary is 1000 000b
Continue, set tmp >> -127, the result is 0x08, shifted 1 bit to the right
-127 in binary is 1000 0001b
Can't wait, tried tmp >> -126, it turned out to be 0x04, shifted right by 2 bits
-126 in binary is 1000 0010b

At this time, you can make a bold guess. If the shift operation is a negative number, the number of bits shifted is determined by the lower seven bits of the binary form of the negative number.
If you still have doubts, continue to test:
tmp << -255 results in 0x20, -255 in binary is 0x1 0000 0001b
tmp << -511 results in 0x20, -511 in binary is 0x10 0000 0001b
tmp << -1023 The result is 0x20, the binary of -1023 is 0x100 0000 0001b

Now we can say for sure: if the shift operation is a negative number, then the number of bits shifted is determined by the lower seven bits of the binary form of the negative number. ( The current longlong type seems to have a maximum length of only 64 bits. To reach 128 bits, the compiler needs to be modified.)

After writing this article, I accidentally discovered something wrong at work. The above results only represent the shifting rules of the signed char type. Therefore, the above conclusions need to be further expanded.
Here is the expanded conclusion:
When a number is a signed number, set the binary number of the signed number to k (for example, int type in a 32-bit system, its binary number is 32), then the number is shifted to the left or right by n bits When , the number is shifted only by the positive digit indicated by the lower k-1 bits in the binary form of the n number.
When a number is an unsigned number, set the binary number of the signed number to k (for example, int type in a 32-bit system, its binary number is 32), then the number is shifted to the left or right by n bits When , the number is shifted only by the positive number indicated by the lower k bits in the binary form of the n number.

Due to my limited level, please correct me if I am wrong. I am very grateful.




Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325893202&siteId=291194637