# How does bit shift work in C / C ++?

14

I'd like to understand how bit shifting works in C / C ++ . I would also like to understand how the processor performs the calculations and how it handles all of this.

I have some examples in C / C ++ :

``````void USART_Init(unsigned int ubrr0){
UBRR0H = (unsigned char)(ubrr0>>8); //Ajusta a taxa de transmissão
UBRR0L = (unsigned char)ubrr0;

UCSR0A = 0;
UCSR0B = (1<<RXEN0)|(1<<TXEN0);     //Habilita a transmissão e a recepção
}
``````

I would also like to understand the difference between < and > > .

Edit

``````int x = 1;
x = (x << 8);
``````

`x` will be `0001 0000 0000` ?

What happens if I "exceed" the number of bits of a variable? Example:

``````int x = 1;
//Representação na memória:
//{4º byte} {3º byte} {2º byte} {1º byte}
//0000 0000 0000 0000 0000 0000 0000 0001
x = (x << 50); //Como ficaria?
``````

Edit 2:

What operations does the processor do to make the value:

``````int x = 1;          //Corresponde a 0000 0001
``````

Stay this way in memory:

``````int x1 = (x << 1);  //Corresponde a 0000 0010
``````

How does he figure it out? Does it store in a temporary "variable" (register) and then return the original position? Do you do any mathematical calculations? (what?) or is it just memory manipulation?

asked by anonymous 22.03.2014 / 15:08

8

Bitwise operators "move" all bits of the variable left or right.

C \ C ++ has the operators:

> > Right Shift

<

For example, if you move a variable `x` to the left:

``````int x = 1; // 0000 0001

int x0 = (x << 0); // 0000 0001 Não deslocado
int x1 = (x << 1); // 0000 0010
int x2 = (x << 2); // 0000 0100
int x3 = (x << 3); // 0000 1000
int x4 = (x << 4); // 0001 0000
int x5 = (x << 5); // 0010 0000
int x6 = (x << 6); // 0100 0000
int x7 = (x << 7); // 1000 0000
``````

Now move to the right:

``````int x = 128; // 1000 0000

int x0 = (x >> 0); // 1000 0000 Não deslocado
int x1 = (x >> 1); // 0100 0000
int x2 = (x >> 2); // 0010 0000
int x3 = (x >> 3); // 0001 0000
int x4 = (x >> 4); // 0000 1000
int x5 = (x >> 5); // 0000 0100
int x6 = (x >> 6); // 0000 0010
int x7 = (x >> 7); // 0000 0001
``````

In your example they are possibly used to configure a serial (or something like) communication, in which the offsets are used to enable the configuration bits more simply.

For example, if I want to enable some specific bits of a `UCSR0B` variable, assuming that `RXEN0` is 4 and `TXEN0` is 3:

``````(1<<RXEN0) -> (1 << 4) -> (00000001 << 4) -> (00010000)
(1<<TXEN0) -> (1 << 3) -> (00000001 << 3) -> (00001000)
``````

What is the same thing to do:

``````UCSR0B = 0x10 | 0x8;
``````

This `(1 << VALOR)` operation is a way of telling the compiler "I want number whose bit number VALUE (for base zero) is 1 and the rest 0".

In case you exceed the limits of a variable, the result is undefined, as it says in the pattern:

(C11, 6.5.7p3) "If the value of the right operand is negative   greater than or equal to the width of the left left operand, the   behavior is undefined "

(C ++ 11, 5.8p1) "The behavior is undefined if the operand is   negative, or greater than or equal to the length in bits of the   promoted left operand. "

If you need a limit greater than 32 bits, you can use a `uint64_t` ( `stdint.h` ) variable to perform this operation.

To know how processor does, the best way is to observe the `assembly` code generated by the compiler. Which in the case is this (generated by Visual Studio 2013):

``````; int x = 1;
mov DWORD PTR _x\$[ebp], 1

; int x1 = (x << 1);
mov eax, DWORD PTR _x\$[ebp]
shl eax, 1
mov DWORD PTR _x1\$[ebp], eax
``````

In this case, all you want to know is how the `shl` statement works, which shifts the value to `eax` . Now, how `shl` does this will depend on the processor.

22.03.2014 / 15:47
0

See any C / C ++ documentation, such as:
``````<< : deslocamento para a esquerda