LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   Bitwise >> formula concept... (http://www.linuxquestions.org/questions/programming-9/bitwise-formula-concept-479059/)

debiant 08-31-2006 05:13 AM

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.

debulu 08-31-2006 05:30 AM

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) and 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)

debiant 08-31-2006 05:39 AM

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,

debiant 08-31-2006 06:55 AM

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?

cupubboy 08-31-2006 07:15 AM

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

dmail 08-31-2006 07:19 AM

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)};
};

[edit] :)
or simpler still
Code:

template<typename T>
struct unsigned_range
{
        enum {value = T(~0)};
};


debiant 08-31-2006 07:23 PM

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.

dmail 08-31-2006 07:48 PM

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.

debiant 08-31-2006 08:12 PM

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

dmail 08-31-2006 08:26 PM

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

[edit] I see you have it now :)

debiant 08-31-2006 08:28 PM

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) <<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

[edit] I see you have it now :)


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.


All times are GMT -5. The time now is 08:53 AM.