Archived

This topic is now archived and is closed to further replies.

Bitwise Shift Question

This topic is 5621 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi Guys, I have a question about how the bitwise shift operators (<< and >>) work. Specifically what happens when bits get shifted outside the range of the data type. Using MSVC6 the following gives a result of the oneByte variable having a value of 176. //declare a one byte variable unsigned char oneByte; //check that it really is one byte - a was 1 int a = sizeof(oneByte); //set the variable to some arbitray value oneByte = 176; //results in oneByte with a value of 176 oneByte = oneByte << 32; I would have assumed any one byte variable bit shifted either way 8 bits would be 0? Alex

Share this post


Link to post
Share on other sites
I would have assumed any one byte variable bit shifted either way 8 bits would be 0?


For all intents and purposes yes, but it can also depend on what instruction the compiler chooses for the bit-shift. You can bit-shift "logically" or "arithmetically". Logical shift is the straight forward shift (inserting 0''s where appropriate), but arithmetic shift will preserve the leading bit if you shift right. This is so you can preserve the sign bit for negative numbers. So I think you could arithmetically shift the number 10000000 8 bits to the right, and it would still be 10000000

I am pretty sure this is accurate... but not 100% sure so don''t quote me on it

Share this post


Link to post
Share on other sites
foofightr - I was not aware of that so thanks for letting me know. Thing is, 176 is not simply the leading bit ''turned on''. It is 10110000 (as far as im aware). This is what i dont understand. I would have thought the answer to
176 (or 10110000) << 32 would be either 0 or 128 (10000000).

Can anyone shed any light on this?
Aface

Share this post


Link to post
Share on other sites
The vacated bits are guaranteed to be zero. However, the result is undefined if you shift a number of bits that are equal to or larger than the size of the (promoted) left operand. Since you are shifting 32 bits, you are invoking undefined behaviour.

Share this post


Link to post
Share on other sites
hmm....

i think the thing is as follows:

- chars are stored in 32 bit registers
- your c code above in asm code uses the shl instruction in vs6.0
- if you shift << with shl then your bits from the char are "hiking left" in the register
- if the first bit is at the end of the 32 bit register it will be the set to the first bit again. This means the bits rotate in the register like in a circle.
- So, after every 32 shifts you will still get the old value

I hope someone can understand this stummering...

Share this post


Link to post
Share on other sites
quote:
Original post by Botcher
hmm....

i think the thing is as follows:

- chars are stored in 32 bit registers
- your c code above in asm code uses the shl instruction in vs6.0
- if you shift << with shl then your bits from the char are "hiking left" in the register
- if the first bit is at the end of the 32 bit register it will be the set to the first bit again. This means the bits rotate in the register like in a circle.
- So, after every 32 shifts you will still get the old value

I hope someone can understand this stummering...


shift operations do not, DO NOT, go 'round-n-round, in a circle.

When a bit is shifted off the register it is gone. Forever.

The C ARM - 4th Edition (Sam P. Harbison, Guy L. Steele, Jr. - Prentice Hall - 1995, pg 206, 1st para.) defines the result of shift operations as

"... The bits shifted in from the left for >> depend on the type of the converted left operand: if it is unsigned (or signed and nonnegative), the 0-bits are shifted in from the left; but if it is signed, the at the implimentor's option either 0-bits or copies of the leftmost bit of the operand are shifted in from the left. Therefore, applying the shift operator >> to signed operands is not portable.

The result value of the shift operators is undefined if the value of the right operand is negative, so specifying a negative shift distance does not (necessarily) cause << to shift to the right or >> to shift to the left. The result value is also undefined if the value of the right operand is greater than or equal to the width (in bit positions) of the value of the converted left operand. Note, however, that the right operand may be 0, in which case no shift occurs and the result value is identical to the value of the converted left operand."

ie: it's platform and compiler specific.

I hope this clears any confusion.

By the way, foofightr said it well.

[edited by - Like2Byte on July 24, 2002 11:05:29 AM]

Share this post


Link to post
Share on other sites
sorry... sorry... sorry Like2Byte. I mad a big mistake. I was a little bit confused this morning. I mixed it with the rotate instructions. i am really sorry for that.

But the real answer why 176 << 32 is still 176 is that the processor(i am talking right now about intel pentium processors) do an AND 1Fh with the shift operand. So he transform 176 << 32 to 176 << 0 what means that nothing happens.

That this is true can be seen in intels: IA-32 Intel Architecture Software Developers''s Manual Volume 2 Instruction Set Page 3-693

nice greetings

Botcher

Share this post


Link to post
Share on other sites
I think that wrap-arround shifts not so common as the bit-bucket versions. While C easily could have had another pair of operators for the former, they clearly decided that it was easy enough to code a library function for it.

But, from everything I''ve read, both C and C++ guarantee that bitwise shifts to not wrap around.

Share this post


Link to post
Share on other sites
quote:
Original post by Botcher
sorry... sorry... sorry Like2Byte. I mad a big mistake. I was a little bit confused this morning. I mixed it with the rotate instructions. i am really sorry for that.

But the real answer why 176 << 32 is still 176 is that the processor(i am talking right now about intel pentium processors) do an AND 1Fh with the shift operand. So he transform 176 << 32 to 176 << 0 what means that nothing happens.

That this is true can be seen in intels: IA-32 Intel Architecture Software Developers''s Manual Volume 2 Instruction Set Page 3-693

nice greetings

Botcher


I wrote "DO NOT" for the benifit of the original poster - it could have been very confusing for a newbie (not n00b) reading what you wrote as it pertained to shift operations. I hope you didn''t think I was attacking you.

You must have been some kind of tired, though!! LOL!

Later.

Share this post


Link to post
Share on other sites