473,625 Members | 3,329 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

shifting bits, shift 32 bits on 32 bit int

GGG
Noticed something odd in the way bit shifting was working today.

As far as I have ever heard, shifting will shift in zeros(signed ints
aside)

However I foudn something odd when I am shifting exactly the number of
bits in a value... i.e.
uint32_t x = 5;
uint32_t y = x << 32;
uint32_t z = x << 32;

In the above example y and z are both still 5. Why is this?

Now I understand doing a shift like this seems silly, but in this code
sometimes the resulting shift validly turns out to be exactly the
number of bits in that data type, and expects the result to be 0.

I can change the code to handle this special case... I was just
wondering why this was happening..
Jul 22 '05 #1
9 8728
GGG wrote:
Noticed something odd in the way bit shifting was working today.

As far as I have ever heard, shifting will shift in zeros(signed ints
aside)

However I foudn something odd when I am shifting exactly the number of
bits in a value... i.e.
uint32_t x = 5;
uint32_t y = x << 32;
uint32_t z = x << 32;

In the above example y and z are both still 5. Why is this?

Now I understand doing a shift like this seems silly, but in this code
sometimes the resulting shift validly turns out to be exactly the
number of bits in that data type, and expects the result to be 0.

I can change the code to handle this special case... I was just
wondering why this was happening..


It shifts the number of bits determined from the right operand by
taking the remainder from dividing by the number of total bits in
the left operand. Take 32, divide by 32, take the remainder, you
get 0. That's the number of bits shifted to the left. IOW, none.

If you do

uint32_t x = 5;
uint32_t y = x << 33;

you will have y == (uint32_t)10 (most likely, given common meaning
of 'uint32_t').

V
Jul 22 '05 #2
Victor Bazarov 2004-05-26 :
GGG wrote:
Noticed something odd in the way bit shifting was working today.

As far as I have ever heard, shifting will shift in zeros(signed ints
aside)

However I foudn something odd when I am shifting exactly the number of
bits in a value... i.e.
uint32_t x = 5;
uint32_t y = x << 32;
uint32_t z = x << 32;

In the above example y and z are both still 5. Why is this?

Now I understand doing a shift like this seems silly, but in this code
sometimes the resulting shift validly turns out to be exactly the
number of bits in that data type, and expects the result to be 0.

I can change the code to handle this special case... I was just
wondering why this was happening..


It shifts the number of bits determined from the right operand by
taking the remainder from dividing by the number of total bits in
the left operand. Take 32, divide by 32, take the remainder, you
get 0. That's the number of bits shifted to the left. IOW, none.

If you do

uint32_t x = 5;
uint32_t y = x << 33;

you will have y == (uint32_t)10 (most likely, given common meaning
of 'uint32_t').


Exactly, and the reason is simple: most hardware simply takes as many bits
from the shift value as needed, ignoring the higher valued bits.
In the case of uint32_t, 5 bits. In other words,
uint32_t(x) << y == uint32_t(x) << (y & 31)

Walter Tross
Jul 22 '05 #3
"GGG" schrieb
uint32_t x = 5;
uint32_t y = x << 32;
uint32_t z = x << 32;

In the above example y and z are both still 5. Why is this?

Now I understand doing a shift like this seems silly, but in this code
sometimes the resulting shift validly turns out to be exactly the
number of bits in that data type, and expects the result to be 0.


It doesn't matter what you are expecting. The behaviour of shifts defined only if the value of the right operand is less than the number of bits in the left operand. So shifting a 32-bit value by 32 or more is undefined or at least not specified in the standard and each compiler may do whatever it thinks to be best.

Heinz
Jul 22 '05 #4
GGG
Ah... I figured out what was really going on here.

I originally got no compiler warnings from my real program, as the
value I was shifting by was a variable.

I should have payed better attention to my little test program.

uint32_t x = 1 << 32;
//here, x is still 1. Shift any 32 bit int by 32 bits and it stays the
exact same number

That gives a compiler warning because I am shifting by the size of the
data type. The problem here is that it is really just multiplying by
2^32. So... it stays that same. So in reality, shifting doesn't really
"shift in zeros", it does multipication, making it look like it shifts
in zeros. This only becomes apparent when I am shifting by the actual
data type size.
So simply put, if you shift any integer by the number of bits in its
data type, its going to be the exact same number.

Shifting an 8 bit int by 8 bits is NOT 0, it is the same number.
Shifting an 32 bit int by 32 bits is NOT 0, it is the same number.

Kind of interesting I think...
Jul 22 '05 #5
GGG wrote:
Ah... I figured out what was really going on here.

I originally got no compiler warnings from my real program, as the
value I was shifting by was a variable.

I should have payed better attention to my little test program.

uint32_t x = 1 << 32;
//here, x is still 1. Shift any 32 bit int by 32 bits and it stays the
exact same number

That gives a compiler warning because I am shifting by the size of the
data type. The problem here is that it is really just multiplying by
2^32. So... it stays that same. So in reality, shifting doesn't really
"shift in zeros", it does multipication, making it look like it shifts
in zeros. This only becomes apparent when I am shifting by the actual
data type size.
So simply put, if you shift any integer by the number of bits in its
data type, its going to be the exact same number.

Shifting an 8 bit int by 8 bits is NOT 0, it is the same number.
Shifting an 32 bit int by 32 bits is NOT 0, it is the same number.

Kind of interesting I think...


You're wrong. Read Heinz's post.
Jul 22 '05 #6
Jeff Schwab wrote:
GGG wrote:
Ah... I figured out what was really going on here.

I originally got no compiler warnings from my real program, as the
value I was shifting by was a variable.

I should have payed better attention to my little test program.

uint32_t x = 1 << 32;
//here, x is still 1. Shift any 32 bit int by 32 bits and it stays the
exact same number

That gives a compiler warning because I am shifting by the size of the
data type. The problem here is that it is really just multiplying by
2^32. So... it stays that same. So in reality, shifting doesn't really
"shift in zeros", it does multipication, making it look like it shifts
in zeros. This only becomes apparent when I am shifting by the actual
data type size.
So simply put, if you shift any integer by the number of bits in its
data type, its going to be the exact same number.

Shifting an 8 bit int by 8 bits is NOT 0, it is the same number.
Shifting an 32 bit int by 32 bits is NOT 0, it is the same number.

Kind of interesting I think...

You're wrong. Read Heinz's post.


Better yet, read the first part of section 5.8 of the ISO/IEC 14882:2003
standard:

The behavior is undefined if the right operand is negative,
or greater than or equal to the length in bits of the
promoted left operand.
Jul 22 '05 #7
On Wed, 26 May 2004 22:42:52 +0200, "Heinz Ozwirk" <wa******@gmx.d e>
wrote in comp.lang.c++:
"GGG" schrieb
uint32_t x = 5;
uint32_t y = x << 32;
uint32_t z = x << 32;

In the above example y and z are both still 5. Why is this?

Now I understand doing a shift like this seems silly, but in this code
sometimes the resulting shift validly turns out to be exactly the
number of bits in that data type, and expects the result to be 0.


It doesn't matter what you are expecting. The behaviour of shifts defined
only if the value of the right operand is less than the number of bits in
the left operand. So shifting a 32-bit value by 32 or more is undefined or
at least not specified in the standard and each compiler may do whatever
it thinks to be best.

Heinz


First, please find the setting in your news posting software where you
tell it to insert line breaks at some interval in the range of 65 to
89 characters. Thank you.

Next, you are partially correct. The value of the right operand must
not only be less than the width in bits of the (promoted) left
operand, it must also be greater than or equal to 0.

Both a negative right operand, or one as large or larger than the
number of bits in the promoted left operand cause undefined behavior.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.l earn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Jul 22 '05 #8
gs*****@Digital Globe.com (GGG) wrote in message news:<98******* *************** ****@posting.go ogle.com>...
Ah... I figured out what was really going on here.

I originally got no compiler warnings from my real program, as the
value I was shifting by was a variable.

I should have payed better attention to my little test program.

uint32_t x = 1 << 32;
//here, x is still 1. Shift any 32 bit int by 32 bits and it stays the
exact same number

That gives a compiler warning because I am shifting by the size of the
data type. The problem here is that it is really just multiplying by
2^32. So... it stays that same.


No, it doesn't. Unsigned arithmetic, including multiplying, works modulo
2^n. Multiplying by 2^32 modulo 2^32 always gives you 0.

What happens has been pointed out before: undefined behavior.

Regards,
Michiel Salters
Jul 22 '05 #9
GGG
Jack Klein <ja*******@spam cop.net> wrote in message news:<dg******* *************** **********@4ax. com>...
On Wed, 26 May 2004 22:42:52 +0200, "Heinz Ozwirk" <wa******@gmx.d e>
wrote in comp.lang.c++:
"GGG" schrieb
uint32_t x = 5;
uint32_t y = x << 32;
uint32_t z = x << 32;

In the above example y and z are both still 5. Why is this?

Now I understand doing a shift like this seems silly, but in this code
sometimes the resulting shift validly turns out to be exactly the
number of bits in that data type, and expects the result to be 0.


It doesn't matter what you are expecting. The behaviour of shifts defined
only if the value of the right operand is less than the number of bits in
the left operand. So shifting a 32-bit value by 32 or more is undefined or
at least not specified in the standard and each compiler may do whatever
it thinks to be best.

Heinz


First, please find the setting in your news posting software where you
tell it to insert line breaks at some interval in the range of 65 to
89 characters. Thank you.

Next, you are partially correct. The value of the right operand must
not only be less than the width in bits of the (promoted) left
operand, it must also be greater than or equal to 0.

Both a negative right operand, or one as large or larger than the
number of bits in the promoted left operand cause undefined behavior.

Ah, thanks for all the info. Sorry for the long lines... that always annoyed
me too, I am now just stuck no real newsgroup access anymore and it really
blows. I need to use Google to do it...(not to mentioned the ~8 hour delay
when you post on google... I just have to remeber to add in a CR manually
when I post....

Anyways, thanks for setting me straight, my first clue should have been
the compiler warnings that I wasn't paying attention too. Need to pay
better attention...
-grant
Jul 22 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
1276
by: Hannes Allmaier | last post by:
Hi! I found interesting code in a Visualc++-file (all variables are unsigned integers) return (CurrentBfr << (32 - BitsLeft)) >> (32 - N);; so it seems the return value gets right shifted (32-N) times, like this return(CurrentBfr << (32 - BitsLeft))>> (32 - N);
4
1662
by: ben | last post by:
hiyer, say you've got a 32 bit int - is there a nifty way to shift that whole value right by 4 bits and at the same time collect the 4 bits that are being shifted off the edge to the right into another variable? i'm hoping for a way to do it in one foul swoop ... ? probably not, but just wondering if there's a better way than the obvious : x = 0xf & bits; bits >>= 4;
8
1646
by: Nick Patavalis | last post by:
Ok, what is this supposed to print: #include <stdio.h> #include <stdint.h> int main (void) { uint32_t r, s;
6
2883
by: digi.empire | last post by:
trying to wrap my mind around these two exercises: 1. given an int (which is 16 bits in c), if the 16 bits are: A15A14A13A12A11A10A9A8A7A6A5A4A3A2A1A0 it will output an int in whose 16 bits are: A7A6A5A4A3A2A1A0A15A14A13A12A11A10A9A8
10
10687
by: krunalb | last post by:
Hi, I am trying to shift unsigned long long value by 64 bits and this is what i get #include <stdio.h> int main() { unsigned short shiftby= 64;
3
5542
by: Madhur | last post by:
I would like to know the best efficient way to shift a flat buffer by say 4bits. for exaple if the flat buffer is 0x62 0x48 0x23 .... then the result should be 0x06 0x24 0x82 0x3.....
6
2476
by: Madhur | last post by:
I am having the following problem of bit shifting. My program runs on a little endian machine. Consider that if I have the following data represented in big endian... 0x12345678 the little endian representation would be 0x78563412.
9
2250
by: Boltar | last post by:
On 32 bit linux with gcc 4.2 I get unexpected results with this code: main() { int bits = 32; printf("%d\n",(int)1 << (int)32); printf("%d\n",(int)1 << bits); }
12
2099
by: British0zzy | last post by:
Is it a defined operation when I do something like this: char a = 15; a = a<<9;
0
8256
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8635
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8497
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7184
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5570
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4193
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2621
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1803
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1500
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.