Hi, how is this code working? As per me since aNum is int8 so left shifting aNum by 8 would make it zero, how is it maintaining this? if i left shift it by 32 it becomes zero? unsigned __int8 aNum = 5; printf("%d",aNum << 16); Thanks Keshav -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
![]() |
0 |
![]() |
Keshav wrote: > Hi, > how is this code working? As per me since aNum is int8 so left > shifting aNum by 8 would make it zero, how is it maintaining this? > if i left shift it by 32 it becomes zero? > > unsigned __int8 aNum = 5; > printf("%d",aNum << 16); > > The code isn't working. :-) If you shift by more than the size of the integer, the result is undefined. On some hardware it might become zero, or stay unchanged, on still others the shift count will be modulo the size, on others we don't know. Bo Persson -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
![]() |
0 |
![]() |
On Oct 30, 1:18 pm, Keshav <gupta.kes...@gmail.com> wrote: > Hi, > how is this code working? As per me since aNum is int8 so left > shifting aNum by 8 would make it zero, how is it maintaining this? if > i left shift it by 32 it becomes zero? > > unsigned __int8 aNum = 5; > printf("%d",aNum << 16); Just a guess: integral promotion? 16 is an int literal. An builtin operator on a __int8 and an int will first promote the __int8 value to an int, perform the int operation, and return the int value. Your system appears to be a 32 bit system, and it appears int is the natural word size of the machine, 32 bits, which explains why when you shift it by 32 it becomes 0. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
![]() |
0 |
![]() |
On Oct 30, 3:18 pm, Keshav <gupta.kes...@gmail.com> wrote: > Hi, > how is this code working? As per me since aNum is int8 so left > shifting aNum by 8 would make it zero, how is it maintaining this? if > i left shift it by 32 it becomes zero? It would be useful if you can specify what was the actual output and what was your expected output. Also providing a complete compilable code would be appreciated. Here is an example, and everything works as expected. $ cat int8.cc # include <iostream> # include <bitset> int main() { unsigned char i = 5; std::bitset<8> bi(i); for (int sp=0; sp < 10; ++sp) { unsigned char j = (i << sp); std::bitset<8> bj(j); std::cout << "i << " << sp << ": " << bj << std::endl; } } $ g++ int8.cc $ ./a.exe i << 0: 00000101 i << 1: 00001010 i << 2: 00010100 i << 3: 00101000 i << 4: 01010000 i << 5: 10100000 i << 6: 01000000 i << 7: 10000000 i << 8: 00000000 i << 9: 00000000 $ g++ --version g++ (GCC) 3.4.4 (cygming special, gdc 0.12, using dmd 0.125) Copyright (C) 2004 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. $ Rgds, anna -- Love of a Father http://missingrainbow.blogspot.com/2008/07/love-of-father.html [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
![]() |
0 |
![]() |
On 30 Okt., 21:18, Keshav <gupta.kes...@gmail.com> wrote: > Hi, > how is this code working? Well - obviously it is not. > As per me since aNum is int8 so left > shifting aNum by 8 would make it zero, how is it maintaining this? What makes you believe so? aNum << 16 is an integer expression, as both opearands are converted to int. Also, shifting is undefined on an integer number, so only shift unsigned quantities. > if > i left shift it by 32 it becomes zero? Not necessarily. If your int is 32 bits, shifting by 32 (or larger) gets implementation defined. I believe my compiler would return the original number. Only use shifts in lowlevel code, and only with unsigned values. > > unsigned __int8 aNum = 5; > printf("%d",aNum << 16); > Also avoid printf, prefering std::cout. Especially in cases like this where you seem to be unsure about the result of the parameters. std::cout is cleaner and typesafe. printf might (sadly) have a performance advantage with most common implementations, but unless it really matters, stay away from the printf family. /Peter -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
![]() |
0 |
![]() |
Keshav wrote: > Hi, > how is this code working? As per me since aNum is int8 so left > shifting aNum by 8 would make it zero, how is it maintaining this? if > i left shift it by 32 it becomes zero? > > unsigned __int8 aNum = 5; > printf("%d",aNum << 16); 5.8/1: "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." The question now is how long in bits the promoted aNum is. On 32-bit systems where int is 32 bits long, aNum will be promoted to int, aNum << 16 may not make it zero, and aNum << 32 will be undefined. Note here that the shift operation is done not on a 8-bit value, but on a 32-bit value. On the other hand, in this example: unsigned __int8 aNum = 5; aNum <<= 5; the result will be assigned back to a 8-bit value, during which "the laws of arithmetic modulo 2^n" applies and only the least significant 8 bits are taken, which is zero. -- Seungbeom Kim [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
![]() |
0 |
![]() |
On Thu, 30 Oct 2008 14:18:10 CST, Keshav <gupta.keshav@gmail.com> wrote in comp.lang.c++.moderated: > Hi, > how is this code working? As per me since aNum is int8 so left > shifting aNum by 8 would make it zero, how is it maintaining this? if > i left shift it by 32 it becomes zero? > > unsigned __int8 aNum = 5; > printf("%d",aNum << 16); I see three replies already, but none of the correct. Regardless of what you think "as per you", as per the C++ language standard you are just plain wrong. You are not shifting an 8-bit object, in fact you can't shift an 8-bit value in C++. When you perform an arithmetic or logical operation on an integer type smaller than int, the value is promoted to either int (in this case) or unsigned int (in some special cases). This has nothing to do with the type of the right hand operand. So you are shifting a 16-bit or more likely a 32-bit integer rvalue right by 16. If int is 16 bits on your system, the behavior is undefined. It is undefined behavior to shift an integer type by a negative value, or by a value greater than or equal to the number of bits in the integer type. There is no guarantee that any size shift will generate the value 0, especially when shifting a signed type. -- Jack Klein Home: http://JK-Technology.Com FAQs for comp.lang.c http://c-faq.com/ comp.lang.c++ http://www.parashift.com/c++-faq-lite/ alt.comp.lang.learn.c-c++ http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
![]() |
0 |
![]() |
On Oct 31, 7:42 am, "Bo Persson" <b...@gmb.dk> wrote: > Keshav wrote: > > Hi, > > how is this code working? As per me since aNum is int8 so left > > shifting aNum by 8 would make it zero, how is it maintaining this? > > if i left shift it by 32 it becomes zero? > > > unsigned __int8 aNum = 5; > > printf("%d",aNum << 16); > > The code isn't working. :-) > > If you shift by more than the size of the integer, the result is > undefined. > > On some hardware it might become zero, or stay unchanged, on still > others the shift count will be modulo the size, on others we don't > know. > > Bo Persson > Basically this is what happens, assuming a 32-bit machine: unsigned __int8 aNum = 5; printf("%d",(unsigned _int32)aNum << 16); That is, there's promotion to a 32-bit data type so that things now look like {0, byte-value, 0, 0}, a 32-bit value. The max you can shift is 24. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
![]() |
0 |
![]() |
> Also, shifting is undefined on an > integer number, the current ISO C++0x draft says, >> is implementation-defined for negative integers, and for all positive integers, signed or unsigned, equivalent to: x / (2 raised to y). So (aNum = 5) >> 32 is (or will be in future) 0, regardless of what integer type aNum is. I don't have the ISO 2003 version at hand. Wolf Lammen -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
![]() |
0 |
![]() |
On Nov 1, 7:48 am, Jack Klein <jackkl...@spamcop.net> wrote: > On Thu, 30 Oct 2008 14:18:10 CST, Keshav <gupta.kes...@gmail.com> > wrote in comp.lang.c++.moderated: > > > Hi, > > how is this code working? As per me since aNum is int8 so left > > shifting aNum by 8 would make it zero, how is it maintaining this? if > > i left shift it by 32 it becomes zero? > > > unsigned __int8 aNum = 5; > > printf("%d",aNum << 16); > > I see three replies already, but none of the correct. The first reply, mine: On Oct 30, 3:43 pm, JoshuaMaur...@gmail.com wrote: > Just a guess: integral promotion? 16 is an int literal. An builtin > operator on a __int8 and an int will first promote the __int8 value to > an int, perform the int operation, and return the int value. Your > system appears to be a 32 bit system, and it appears int is the > natural word size of the machine, 32 bits, which explains why when you > shift it by 32 it becomes 0. Quoting the C++ 03 standard, 5.8 shift operators, subsection 3: > The value of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has > an unsigned type or if E1 has a signed type and a nonnegative value, > the value of the result is the integral part of the quotient of E1 > divided by the quantity 2 raised to the power E2. If E1 has a signed > type and a negative value, the resulting value is > implementation-defined. I'm curious, where was I wrong? -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
![]() |
0 |
![]() |
On 1 Nov., 16:57, "wolf.lammen" <wolf.lam...@googlemail.com> wrote: > > Also, shifting is undefined on an > > integer number, > > the current ISO C++0x draft says, >> is implementation-defined for > negative integers, and for all positive integers, signed or unsigned, > equivalent to: x / (2 raised to y). So (aNum = 5) >> 32 is (or will be > in future) 0, regardless of what integer type aNum is. > I don't have the ISO 2003 version at hand. > That is true: my wording was misleading. What I meant was that shifting of signed integers is unspecified. You are correct that for signed integers that turn out to be positive (as in the OPs code), the result is well defined, but the point I tried to make (not to well!) was that you should not shift signed integers: if they are less than zero, you get unspecified behaviour and if they are bigger than zero, you could just as well have used an unsigned quantity in the first place. As for the ability to shift with an arbitrary amount, you are mistaken - at least according to my draft (n2798). [expr.shift] .... 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. Thus, your shifting 32 bits will be undefined on a 32-bit machine - also in C++0x. /Peter -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
![]() |
0 |
![]() |
JoshuaMaurice@gmail.com wrote: > The first reply, mine: > > On Oct 30, 3:43 pm, JoshuaMaur...@gmail.com wrote: >> Just a guess: integral promotion? 16 is an int literal. An builtin >> operator on a __int8 and an int will first promote the __int8 value to >> an int, perform the int operation, and return the int value. Your >> system appears to be a 32 bit system, and it appears int is the >> natural word size of the machine, 32 bits, which explains why when you >> shift it by 32 it becomes 0. > > Quoting the C++ 03 standard, 5.8 shift operators, subsection 3: [...] > > I'm curious, where was I wrong? You read 5.8/3, but missed 5.8/1. See the previous post of mine in this thread. -- Seungbeom Kim [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
![]() |
0 |
![]() |