Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unexpected result with right shift after bitwise negation

Tags:

I expected that below code will output 10 because (~port) equal to 10100101 So, when we right shift it by 4 we get 00001010 which is 10. But the output is 250! Why?

int main() {     uint8_t port = 0x5a;     uint8_t result_8 =  (~port) >> 4;     //result_8 = result_8 >> 4;      printf("%i", result_8);      return 0; } 
like image 806
Islam Abdeen Avatar asked Apr 15 '19 00:04

Islam Abdeen


People also ask

What is the result of right shift operator?

The right shift operator ( >> ) returns the signed number represented by the result of performing a sign-extending shift of the binary representation of the first operand (evaluated as a two's complement bit string) to the right by the number of bits, modulo 32, specified in the second operand.

How does bitwise right shift operator work?

The bitwise shift operators move the bit values of a binary object. The left operand specifies the value to be shifted. The right operand specifies the number of positions that the bits in the value are to be shifted.

What are bitwise shift operators?

The bitwise shift operators are the right-shift operator ( >> ), which moves the bits of an integer or enumeration type expression to the right, and the left-shift operator ( << ), which moves the bits to the left.

How do you shift binary numbers to the right?

A bit-shift moves each digit in a number's binary representation left or right. Within right-shifts, there are two further divisions: logical right-shift and arithmetic right-shift. A left-shift is represented by the << operator, while a right-shift is represented by the >> operator.

How to use bitwise unsigned right shift operator in Java?

In this article we will see the use of Bitwise Unsigned Right Shift operator in Java programming language. Bitwise Unsigned Right Shift which is represented by >>> symbol. It shifts the bits of a number towards right with specified position.

What is bitwise shift in C?

The bitwise shift operators move the bit values of a binary object. The left operand specifies the value to be shifted. The right operand specifies the number of positions that the bits in the value are to be shifted. The result is not an lvalue.

What is the unsigned right shift operator?

Table of contents Table of contents Syntax Description Examples Specifications Browser compatibility See also Unsigned right shift (>>>) The unsigned right shift operator (>>>)(zero-fill right shift) shifts the first operand the specified number of bits to the right. Excess bits shifted off to the right are discarded.

What is a zero-fill right shift?

Excess bits shifted off to the right are discarded. Zero bits are shifted in from the left. The sign bit becomes 0, so the result is always non-negative. Unlike the other bitwise operators, zero-fill right shift returns an unsigned 32-bit integer. Syntax a >>>b Description


1 Answers

C promotes uint8_t to int before doing operations on it. So:

  1. port is promoted to signed integer 0x0000005a.
  2. ~ inverts it giving 0xffffffa5.
  3. An arithmetic shift returns 0xfffffffa.
  4. It's truncated back into a uint8_t giving 0xfa == 250.

To fix that, either truncate the temporary result:

uint8_t result_8 = (uint8_t)(~port) >> 4; 

mask it:

uint8_t result_8 = (~port & 0xff) >> 4; 

or xor it (thanks @Nayuki!):

uint8_t result_8 = (port ^ 0xff) >> 4; 
like image 159
Yakov Galka Avatar answered Nov 23 '22 22:11

Yakov Galka