Bitwise opperations

I've not done much work on using variables for bit flags so I wanted to check that this is correct before putting it into my code.

Lets say if I want to change the very last 4 bits on a string ONLY and keep the rest of the variable the same would this work?

1
2
3
4
5
//taken from wikipedia so I don't really trust it
char var = 10011001; //Okay I know this isn't right but lets just imagine it's all in bits please
char newBit = 00000110;
char flag = 00001111;
var |= (flag & newBit);


So hopefully "var" will now equal 10010110 correct?
If I work it out in my head I get 10011111.

My bitwise isn't fantastic, though.
The (flag & newBit) should equate to 00000110
Which I'm confident with but I need to know if the |= assignment leaves the first 4 bits alone sets the last four to 0110 no matter what there previous state.
the 'or' operator does not set any bits to 0.
iHutch105 is correct here.

(flag & newBit):
 00000110  <-- newBit
&00001111  <-- flag
 00000110


var |= (flag & newbit) is equivalent to var = var | (flag & newbit).
 10011001  <-- var
|00000110  <-- (flag & newBit) 
 10011111

if the bit in var OR the bit in (flag & newbit) == 1, then the result bit is 1.

So the end result should be 10011111.

So no. |= will not leave the first four bits alone. It will OR them together.
Last edited on
You should be able to make a binary number using an 0b ( 0 the number ) prefix:
int x = 0b010; // x = 2;
LowestOne wrote:
You should be able to make a binary number using an 0b ( 0 the number ) prefix
You can make a binary number by using chars like the OP did as well. Or you can use bitsets which allow you to output the number in binary.
1
2
3
4
5
#include <bitset>
typedef std::bitset<8> byte;

byte b(10110001);
std::cout << b;
10110001


EDIT:
@OP
What exactly are you trying to accomplish with the bits? Maybe I can be of more help if I knew what result you were looking for.
Last edited on
@Thumper
I think you might have made a typo in your code. Your point is better illustrated if you pass a decimal number into your bitset typedef.
@iHutch105
The above code works exactly as I intended.
What do you mean by "pass a decimal number"? Could you elaborate?
Last edited on
1
2
3
4
5
6
7
8
9
#include <iostream>
#include <bitset>

typedef std::bitset<8> byte;

int main( int argc, char* argv[] )
{
  std::cout << byte( 255 ) << std::endl;
}
Ah. That works too. I wanted to illustrate that you could construct a bitset with a number's binary form as well.
> You should be able to make a binary number using an 0b ( 0 the number ) prefix:

with -std=c++11 -pedantic-errors

int i = 0b1011011 ; // error: binary constants are a GCC extension

Expected to be available in C++14.


> construct a bitset with a number's binary form as well.

std::bitset<8> bs( "10111001" ) ; // construct from std::string


Thumper wrote:
What exactly are you trying to accomplish with the bits?


Well take this for example:
1
2
3
4
5
6
7
8
enum COLLISION{
    C_OFF           = 0001;
    C_ON            = 0010;
    C_EX            = 0011;
    BOX             = 0100;
    POLYGON         = 1000;
    OCTREE          = 1100;
};


These are collision states, the left 2 bits represent how the collisions should be calculated, the right 2 bits is simply whether to even start calculating collision (on, off, or this object can collide with scenes but not other objects (C_EX))

Lets say that halfway through the game I want to change C_ON to C_OFF for some reason.
I wanna call a function like updateCollide(C_OFF) and from there I'll swap the last 2 bits from 10 to 01

So if I had an object with collision state 1110 it would change to 1101
Last edited on
You could do it in two steps.

First AND the existing value with a mask. The mask has a 1 in the bits that are to remain unchanged, and a 0 in the bits that are to be set OFF.

Then OR the result with a value having 0 in all bit positions except those that you want to force ON.
I think you may have an issue with the values used in the enum, you have overlapping bits. I ussualy use 1 bit per flag.
1
2
3
4
5
6
7
8
enum COLLISION{
   // C_OFF         ;//this one seems redundant to me, just test if C_ON is off
    C_ON            = 1,// 00001
    C_EX            = 2,// 00010
    BOX             = 4,// 00100
    POLYGON         = 8,// 01000
    OCTREE          = 16// 10000
};
doing this you can have any or all flags on or off.
http://ideone.com/Jz6pvg
Last edited on
@naraku9333 dont worry the overlap is intentional there.

And yeah I was looking for a method to do it in one step but the description I followed was horribly unclear.
But I've worked the method out to be
1
2
value &= flag;
value |= (flag & newBits);


Sorry for all the confusion guys
Topic archived. No new replies allowed.