🔒 Locked
Bitwise Shift Question
Advertisement
Original Post
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
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
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
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
176 (or 10110000) << 32 would be either 0 or 128 (10000000).
Can anyone shed any light on this?
Aface
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...
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...
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]
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
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 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.
But, from everything I''ve read, both C and C++ guarantee that bitwise shifts to not wrap around.
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
You must have been some kind of tired, though!! LOL!
Later.
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement