LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 10-24-2004, 11:19 PM   #1
eshwar_ind
Member
 
Registered: Feb 2004
Location: Bangalore
Distribution: Redhat
Posts: 144

Rep: Reputation: 15
about bitwise operators?


Hi all!!!
Can anybody explain me why is this wrong?



unsigned int X;
X = X >> 32; ( any how value will be zero , Why shouldnt we shift more than number of bits of operand )

unsigned short Y;
Y = Y << 16 ; ( again same )

Can someone please explain me why is it so? ( at the cpu register level )

Thanks in advance
bye,
Eshwar.
 
Old 10-25-2004, 12:23 AM   #2
gizmo_thunder
Member
 
Registered: Apr 2004
Posts: 101

Rep: Reputation: 15
im' not sure.. about it but this might be because
the representation of number is different in big-endian
and small-endian representations.
 
Old 10-25-2004, 12:50 AM   #3
itsme86
Senior Member
 
Registered: Jan 2004
Location: Oregon, USA
Distribution: Slackware
Posts: 1,246

Rep: Reputation: 58
Are you asking why the value is always 0?

Say you're working with an 8-bit char and the value is something like 129:
10000001

If you shift it left 8 times you'll do this:
00000010
00000100
00001000
00010000
00100000
01000000
10000000
00000000

As you can see, it's impossible for it to be anything but 0. The same happens if you shift it right 8 times. The incoming bits are always 0 and since you're shifting as many time as there are bits in the variable then there's no way to keep any 1s in the variable.
 
Old 10-25-2004, 01:09 AM   #4
eshwar_ind
Member
 
Registered: Feb 2004
Location: Bangalore
Distribution: Redhat
Posts: 144

Original Poster
Rep: Reputation: 15
No, I am asking about why shouldnt we shift an operand more than the number of bits it has. Some books say that this is the wrong way.
you shouldnt shift a charater more than 7 times, similarly short more than 15, int 31 .
Even we shift the operand more than the number of bits it has we get zero. Then why shouldnt we perform that shift operations?
I hope you got my question.
Any how thanks for your replies.
if anyone knows the answer please reply me
bye,
Eshwar .
 
Old 10-25-2004, 01:18 AM   #5
itsme86
Senior Member
 
Registered: Jan 2004
Location: Oregon, USA
Distribution: Slackware
Posts: 1,246

Rep: Reputation: 58
I think they just mean "shouldn't" as in "it's completely pointless". Doing unsigned char a; a = 0; is easier and clearer than unsigned char a; a <<= 8;.

I could be wrong, but I don't see any possible way that it can cause any ill side effects though.
 
Old 10-25-2004, 01:18 AM   #6
alagenchev
Member
 
Registered: Oct 2004
Location: USA
Distribution: Slackware, Debian, Ubuntu
Posts: 223

Rep: Reputation: 30
ok this is simple to explain. int or signed int goes from 2^15- 1 for MAX number and -(2^15-1) for negative number if you notice there's a -1 this is because of what is called clockwise aritmethic which this is not the place to explain :

let's say you have some integer: 0|(some number) this is positive(indicated by the first bit(sign bit)) then the number 1|(some number) is negative well OK imagine you have a number:
0|(all ones) and you add one to it - you will get 1|(all zeros) well this is the smallest negative number by default which is -(2^15-1)= -32767 so when you add one to 32767 you get -32767 , overflow, weird ah? OK well this was for signed int, but what happens if you have unsigned, that means that you do not have any positive or negative numbers and now you can have all the bits to represent your number and you have from 0 to 65535(2^31-1), so when you go from positive MAX +1 you will get zero, basically this is what you do when you >>32 you move your bit from the first place to the sign bit or if it is not on the first place it overflows and still gives you a zero (this actually depends on the architecture and the compiler some people may get a different answer depending on how much they shift)

and you were asking why this is so.
answer:
when you initialize a variable you basically allocate a space in memory for it, when you initialize unsigned int in your case, you get 2^32 i believe bits if you shift to the left or to the right of those 32 bits you will actually overwrite over some other data, which may be dangerous, since you don;t know what you will write over. this makes sure that you stay in your 32 bits and don;t F UP your OS or PC or whatever, so just use a long for whatever you are doing and don't worry about it. if you have any other questions ask. Oh i forgot those sizes are architecture dependent as well so don't quote me on that but it is the ANSI C standart what i posted here
 
Old 10-25-2004, 01:20 AM   #7
alagenchev
Member
 
Registered: Oct 2004
Location: USA
Distribution: Slackware, Debian, Ubuntu
Posts: 223

Rep: Reputation: 30
oh well by the time i post they answered your first question, read my post and i answered the 2nd
 
Old 10-25-2004, 01:21 AM   #8
alagenchev
Member
 
Registered: Oct 2004
Location: USA
Distribution: Slackware, Debian, Ubuntu
Posts: 223

Rep: Reputation: 30
so basically the compiler (and)or OS make sure you don't go over your allocated space
 
Old 10-25-2004, 01:23 AM   #9
alagenchev
Member
 
Registered: Oct 2004
Location: USA
Distribution: Slackware, Debian, Ubuntu
Posts: 223

Rep: Reputation: 30
i know some compilers will let you get different numbers, not only zero's if you shift from max >>some number you may even get -10 for signed or let's say 4 for unsigned, it all depends
 
Old 10-25-2004, 01:35 AM   #10
eshwar_ind
Member
 
Registered: Feb 2004
Location: Bangalore
Distribution: Redhat
Posts: 144

Original Poster
Rep: Reputation: 15
Dear alagenchev,
thanks for your reply.
So you mean to say that bitwise opearators are performed directly on memory locations. If its on cpu registers then i feel that there is no chance of overwriting. Now again same question why is it so?
If its on memory locations your exp answers my question. If its not please clear my doubt.....
bye,
Eshwar.
 
Old 10-25-2004, 01:50 AM   #11
alagenchev
Member
 
Registered: Oct 2004
Location: USA
Distribution: Slackware, Debian, Ubuntu
Posts: 223

Rep: Reputation: 30
all operations in C are on memory locations(or should I say most) I am not sure if there's any exceptions but if you have ever used malloc() with pointers you know that you cannot do anything with them untill you allocate the memory because it usually gives "segmentation fault" error- tells you that there's something wrong with your memory bounderies and will give you wrong output. Well arrays are the same as pointers but their space is allocated at definition of the array. if you have used arrays and pointers you will know that only the first element is addressable in memory (to address the nth element you give it the address of first element+n(size of type of element)) that is like if you want to access 3rd element in an integer array the compiler tells the OS to start from 0th element and go +3*(2 bytes) and access that element. well when you initialize the variable it;s almost like initializing an array except you are given location in memory and also 2or however many bytes depending on the type so if you try to access the second bit in the integer and output the result you will get crap. Don't ask me how to do that cause I can't think from top of my head. but while you run your program you are using space in memory, where exactly that space is I am not sure, but I know that if you define your variables from type REGISTER they will be in the computer register, but here is 2 AM and is hard to think so I hope this answers ask again if you got questions
 
Old 10-25-2004, 01:56 AM   #12
alagenchev
Member
 
Registered: Oct 2004
Location: USA
Distribution: Slackware, Debian, Ubuntu
Posts: 223

Rep: Reputation: 30
i guess the answer is yeah it is in memory locations but not exactly sure where exactly
 
Old 10-25-2004, 01:57 AM   #13
itsme86
Senior Member
 
Registered: Jan 2004
Location: Oregon, USA
Distribution: Slackware
Posts: 1,246

Rep: Reputation: 58
Whoa, hold up. Variables are stored in memory, but the CPU is incapable of doing things like bitshifting directly on memory locations. What actually happens is something like this:

C code:
num <<= 5;

CPU instructions:
Read memory at address for num and store it in some free register
Shift value in that register left 5 times
Write the value in that register to memory at address for num
 
Old 10-25-2004, 01:58 AM   #14
eshwar_ind
Member
 
Registered: Feb 2004
Location: Bangalore
Distribution: Redhat
Posts: 144

Original Poster
Rep: Reputation: 15
Dear alagenchev,
What ever you said is correct, but when you are performing arithmetic or some operations you read the data from memory into cpu registers then you perform the operation and place the result in the proper location. I think this is the way how a computer works. So based on this can you explain me the question? hey if you are tired then dont need, we can see it on tomorrow. ok good night
Mr alagenchev.
Any other replies on this.....
bye,
Eshwar.
 
Old 10-25-2004, 02:01 AM   #15
itsme86
Senior Member
 
Registered: Jan 2004
Location: Oregon, USA
Distribution: Slackware
Posts: 1,246

Rep: Reputation: 58
Here, you can see it here:
Code:
itsme@dreams:~/C$ cat shift.c
#include <stdio.h>

int main(void)
{
  volatile unsigned int num = 17;

  num <<= 5;

  return 0;
}
itsme@dreams:~/C$ gcc -S shift.c
itsme@dreams:~/C$ cat shift.s
        .file   "shift.c"
        .version        "01.01"
gcc2_compiled.:
.text
        .align 4
.globl main
        .type    main,@function
main:
        pushl %ebp
        movl %esp,%ebp
        subl $24,%esp
        movl $17,-4(%ebp)
        movl -4(%ebp),%eax
        movl %eax,%edx
        sall $5,%edx
        movl %edx,-4(%ebp)
        xorl %eax,%eax
        jmp .L2
        .p2align 4,,7
.L2:
        leave
        ret
.Lfe1:
        .size    main,.Lfe1-main
        .ident  "GCC: (GNU) 2.95.3 20010315 (release)"
itsme@dreams:~/C$
Look at the lines in bold. The fact that the shifting is done in an isolated register and not in memory is what makes me think there's no way that shifting too many bits would touch any adjacent memory locations.

Last edited by itsme86; 10-25-2004 at 02:05 AM.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
? on logical operators in BASH eroica Linux - Software 10 02-01-2005 01:12 PM
Operators *^ and >> GodSendDeath Programming 4 11-01-2004 09:47 PM
Bitwise operators kamransoomro84 Programming 8 04-22-2004 10:46 PM
operators linuxanswer Programming 3 12-14-2003 06:09 PM
arithmetic operators in Kylix3 (C++) herbie_52 Programming 2 05-23-2003 07:36 AM


All times are GMT -5. The time now is 07:43 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration