# Thread: logical shift and arithmetic shift.(bit shifting in C )

1. ## logical shift and arithmetic shift.(bit shifting in C )

From what I'm told, right shifting of signed integers on some machine cause 1's to be shifted in and on others 0's are shifted in. Now for a signed integer, say -32, is only the last one shifted in as a 1 if its multiple shifts to the right?

And if its shifting in zeros, how does it know its negative without the 1 in the most significant bit spot? Can someone give me an example of this?

2. Machines that do sign extension just shift in whatever the sign bit is for each shift to the right. This way the sign doesn't change when shifting right.
Kurt

3. Originally Posted by ZuK
Machines that do sign extension just shift in whatever the sign bit is for each shift to the right. This way the sign doesn't change when shifting right.
Kurt
So if its 3 shifts to the right it shifts in 3 1s? Beyond the sign bit that would change the value of the number wouldnt it? And what about the ones that shift in zeros?

4. Originally Posted by A34Chris
So if its 3 shifts to the right it shifts in 3 1s?
Yes.
And what about the ones that shift in zeros?
Don't know. Never worked with such a machine.
I understand that in C right shifting of signed types is implementation defined. Sign extension might as well be done by code.
Check the compiler doc.
Kurt

5. Originally Posted by A34Chris
Beyond the sign bit that would change the value of the number wouldnt it?
Right shifting always changes the value of the number, so why should there be a problem?

Bye, Andreas

6. Just do not use the shifting of signed values and you will have no need to understand the undefined behavior caused by it.

7. Originally Posted by AndiPersti
Right shifting always changes the value of the number, so why should there be a problem?

Bye, Andreas
Yes its dropping it down by a factor of two but what about the on bits that are shifted in? I'm confused. I'm not sure I'm expressing myself well.

8. Originally Posted by vart
Just do not use the shifting of signed values and you will have no need to understand the undefined behavior caused by it.
Actually isn't this implementation defined behavior, not undefined behavior?

what about the on bits that are shifted in?
The bits shifted in are 0's.

Jim

9. ok. My assignment is:

Write a program that determines whether your particular computer performs an arithmetic or logical right shift.
So I gotta dig a little bit into this topic to wrap my head around it. It is interesting.

10. Originally Posted by A34Chris
Yes its dropping it down by a factor of two but what about the on bits that are shifted in? I'm confused.
Just try this
Code:
```#include <stdio.h>

void print_bits(int value ) {
unsigned int mask = 1 << 31;
int i;
printf("\n%12d = ", value );
for( i = 31; i >= 0; --i ) {
printf("%c", value & mask ? '1' : '0' );
}
}

int main() {
int v = 123;
print_bits( v );
print_bits( v >> 2);
puts("");
v = -123;
print_bits( v );
print_bits( v >> 2);
puts("");
return 0;
}```
my output
Code:
```         123 = 00000000000000000000000001111011
30 = 00000000000000000000000000011110

-123 = 11111111111111111111111110000101
-31 = 11111111111111111111111111100001```
The only thing that might be a little confusing is that shifting -123 two positions to the right gives -31. But that is how integer truncation is defined. it gives the next lower value.

Kurt

11. Thank you! Thats interesting.

Did you whip that up just now?

12. Originally Posted by jimblumberg
Actually isn't this implementation defined behavior, not undefined behavior?
The bits shifted in are 0's.
You're contradicting yourself! It is, as you say, implementation defined, so it's not always 0's.

The bits shifted in are 0's if the sign bit is 0 no matter what the implementation's choice between arithmetic or logical shifts.

But if the number is negative, then an arithmetic shift will shift in 1's while a logical shift will still shift in 0's. Thus, an arithmetic shift retains the sign of the number.

So to tell which one your machine uses (my guess is arithmetic!), just take a negative number, shift it one place right, and see if it's still negative.
Code:
```int n = -1;
n >>= 1;
puts((n < 0) ? "arithmetic" : "logical");```

13. God I wish I had a printer.

14. I also have a system with a motorola 68000. I can run this code on that too and see if it does a logical or arithmetic right shift. Very interesting!

Thank you all for your time and help! This has been very informative. Dont lock this thread, I might be back next week with more questions!

15. And if you want to simulate a logical shift on an implementation which uses arithmetic shift add the following line to Kurt's code:
Code:
`print_bits((v >> 2) & 0x3FFFFFFF);   // assuming your ints are 4 bytes`
Bye, Andreas