Support LQ: Use code LQ3 and save \$3 on Domain Registration
 Home Forums HCL Reviews Tutorials Articles Register Search Today's Posts Mark Forums Read
 LinuxQuestions.org Bitwise >> formula concept...
 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

 08-31-2006, 05:13 AM #1 debiant Member   Registered: Jul 2006 Distribution: Source Mage 0.9.6 Posts: 196 Rep: Bitwise >> formula concept... Ok, so I've been studying bitwise operators tonight, yay! I came up with the formula (I'm sure I'm not the first) x << y x=x*2^y for a left shift and x >> y x=x/2^y for a right shift, the only problem is that if x = 1 then the 2nd formula doesn't ring true, so I'm just going to live with that even though my OCD doesn't wish it to be so. Am I correct with these formulas or am I in err? As a side not, is their a mathematical notation for an exception. I would just like to know for my own piece of mind so that I can notate it.
 08-31-2006, 05:30 AM #2 debulu Member   Registered: May 2006 Location: India Distribution: Redhat Posts: 49 Rep: You are spot on if U are considering operation on integers and result to be an integer. Also I assume that x<>y=x/(2^y). I think that even if x=1 the formulae still holds.. like 1>>1=1/2^1=1/2=0(considering integer values)
 08-31-2006, 05:39 AM #3 debiant Member   Registered: Jul 2006 Distribution: Source Mage 0.9.6 Posts: 196 Original Poster Rep: Doh! Yes, you are correct in that assumption. That is funny, because I just wrote down the Operator Precedence chart while waiting for a response. You're absolutely right about the formula, I was not thinking about integer division properly. Thank you,
 08-31-2006, 06:55 AM #4 debiant Member   Registered: Jul 2006 Distribution: Source Mage 0.9.6 Posts: 196 Original Poster Rep: Also tying this into my learning on pointers, would unsigned int *c; c++; change the pointer c to the next memory address, and if so, would: unsigned int *c; c<<16; (assuming that int is 16 bit) do the same thing?
 08-31-2006, 07:15 AM #5 cupubboy Member   Registered: May 2003 Location: Bucharest,Romania Distribution: Fedora Core 7 Posts: 109 Rep: I'm afraid of being wrong .. but if the int is 16 bits .. and you left shift it 16 other bits .. wouldn't that turn the pointer to null?? I mean wouldn't the pointer adress 0x0000? also c++ changes the pointer to the next memory address but in increments depending on the pointer type .. vor example for chars the increment will be 1 byte .. where as for int it will be 4 bytes (assuming 32-bit int) I'm still not sure if I'm correct and am waiting for someone to set me straight Cheers --Edit And even though the int is a 16 bit value .. most of the time ( I mean % of the values it can take) will fit in less than 16 bit Last edited by cupubboy; 08-31-2006 at 07:44 AM.
08-31-2006, 07:19 AM   #6
dmail
Member

Registered: Oct 2005
Posts: 970

Rep:
Quote:
 Also tying this into my learning on pointers, would unsigned int *c; c++; change the pointer c to the next memory address
Yes effectively this is
T* c;
c += sizeof(T);

Quote:
 and if so, would: unsigned int *c; c<<16; (assuming that int is 16 bit) do the same thing?
No, left shift by 16 is the same as multiplying by 65536.(ie the max value of int16)

Thanks this has just fixed something I needed. Compile time unsigned range based on type.(for uint8 and uint16)
Code:
```template<typename T>
struct unsigned_range
{
enum{value = ( ( 1<< (sizeof(T)<<3) ) -1)};
};```

or simpler still
Code:
```template<typename T>
struct unsigned_range
{
enum {value = T(~0)};
};```

Last edited by dmail; 08-31-2006 at 11:32 AM.

 08-31-2006, 07:23 PM #7 debiant Member   Registered: Jul 2006 Distribution: Source Mage 0.9.6 Posts: 196 Original Poster Rep: Would you explain that code for me a little bit please. if sizeof(T) were 4 first one, would it be: 1 * (2^4) =16 * (2^3)= 128 - 1 = 127 (?) second one, I have no clue what it is saying... I dont' know what I was thinking about the bitwise operator, I was thinking of moving a 1 over 16 bits but yeah, I see now. Last edited by debiant; 08-31-2006 at 07:28 PM.
 08-31-2006, 07:48 PM #8 dmail Member   Registered: Oct 2005 Posts: 970 Rep: the first one and the second one do the same thing first one Code: `value = ( ( 1<< (sizeof(T)<<3) ) -1)};` This is valid for 16 and 8 bit, unsigned ints 32 on a 32 bit machine causes a problem that its over size, but anyway... If T is a unsigned char then sizeof is 1, this is then multiplied by 8 (bit shift left 3, 2^3). this then is the total number of bits that this type occupies (ie 8). one is pushed to the high bit and -1 deducted. giving 255.(well that nearly what happens, infact we push it a bit further, that why the deduction of one is there) then second one is better and less work(although its compile time so it doesn't matter). Code: `value = T(~0);` this sets the value to zero's complement, if we use the example of a unsigned char again setting to zero would give 00000000 and complementing this would give 11111111(ie complement just turns 0's to 1's and 1's to 0's) this now shows 255 the maximum value which a unsigned char can contain.
 08-31-2006, 08:12 PM #9 debiant Member   Registered: Jul 2006 Distribution: Source Mage 0.9.6 Posts: 196 Original Poster Rep: I'm still not getting you on the first part of code because if you do 1 << 1 that equals two? then 2 << 3 would equal 16? 16 bits -1 = Since bitwise operators are evaluated left to right.' EDIT: IGNORE MISSED PAREN. so 1 << 3 = 8; 1 << 8 = 256 -1 = 255 gotcha, shwew! in binary (for my understanding) 1 << 11 = 1000; 1 << 1000 = 100000000 -1 = 11111111 Last edited by debiant; 08-31-2006 at 08:21 PM.
08-31-2006, 08:26 PM   #10
dmail
Member

Registered: Oct 2005
Posts: 970

Rep:
Quote:
 Originally Posted by debiant ...Since bitwise operators are evaluated left to right...
True but there are parenthesis there to stop the order, maybe if I brake it down
Code:
```int main(int argc, char* argv[ ])
{
std::cout <<"number of bits for unsigned char is:"<< (sizeof(unsigned char)<<3) <<std::endl;
std::cout <<"max value plus one is:"<< (1 << (sizeof(unsigned char)<<3)) <<std::endl;
std::cout <<"max value is:"<< (1 << (sizeof(unsigned char)<<3))-1 <<std::endl;
return 0;
}

output:
number of bits for unsigned char is:8
max value plus one is:256
max value is:255```
 I see you have it now

Last edited by dmail; 08-31-2006 at 08:27 PM.

08-31-2006, 08:28 PM   #11
debiant
Member

Registered: Jul 2006
Distribution: Source Mage 0.9.6
Posts: 196

Original Poster
Rep:
Quote:
 Originally Posted by dmail True but there are parenthesis there to stop the order, maybe if I brake it down Code: ```int main(int argc, char* argv[ ]) { std::cout <<"number of bits for unsigned char is:"<< (sizeof(unsigned char)<<3) <

Thanks for helping me understand that, I realized I had missed the paren shortly after posting. That's usually the way it works. My brain doesn't kick in until after I've spoken.