views:

112

answers:

2

How to I use logical operators to determine if a bit is set, or is bit-shifting the only way?

I found this question that uses bit shifting, but I would think I can just AND out my value.

For some context, I'm reading a value from Active Directory and trying to determine if it a Schema Base Object. I think my problem is a syntax issue, but I'm not sure how to correct it.

foreach (DirectoryEntry schemaObjectToTest in objSchema.Children)
        {
            var resFlag = schemaObjectToTest.Properties["systemFlags"].Value;
            //if bit 10 is set then can't be made confidential.
            if (resFlag != null)
            {
                byte original = Convert.ToByte( resFlag );
                byte isFlag_Schema_Base_Object = Convert.ToByte( 2);
                var result = original & isFlag_Schema_Base_Object;
                if ((result) > 0)
                {
                       //A non zero result indicates that the bit was found
                }
            }
        }

When I look at the debugger: resFlag is an object{int} and the value is 0x00000010. isFlag_Schema_Base_Object, is 0x02

+7  A: 

resFlag is 0x00000010 which is 16 in decimal, or 10000 in binary. So it seems like you want to test bit 4 (with bit 0 being the least significant bit), despite your comment saying "if bit 10 is set".

If you do need to test bit 4, then isFlag_Schema_Base_Object needs to be initialised to 16, which is 0x10.

Anyway, you are right - you don't need to do bit shifting to see if a bit is set, you can AND the value with a constant that has just that bit set, and see if the result is non-zero.

If the bit is set:

                 original  xxx1xxxx
                      AND
isFlag_Schema_Base_Object  00010000
-----------------------------------
                        =  00010000 (non-zero)

But if the bit isn't set:

                 original  xxx0xxxx
                      AND
isFlag_Schema_Base_Object  00010000
-----------------------------------
                        =  00000000 (zero)

Having said that, it might be clearer to initialise isFlag_Schema_Base_Object using the value 1<<4, to make it clear that you're testing whether bit 4 is set.

Richard Fearn
Just to clarify, will my AND be nonzero if resflag is: 0x00011010? That is my goal.
MakerOfThings7
Yes - as long as `isFlag_Schema_Base_Object` itself has only one bit set, then `AND`ing it with `original` will give you either zero (if the bit is set), or `isFlag_Schema_Base_Object` (non-zero, meaning the bit is set). You can test either whether the result is zero/non-zero, or whether it's equal/not equal to `isFlag_Schema_Base_Object`. The tests are equivalent. And if you're in any doubt, try it out :-)
Richard Fearn
@MakerOfThings7: Yup. Your AND will result in 0 for the other bits, but 1 for the one you're checking (if and only if that bit you're checking is set).
Platinum Azure
@Richard - Thanks with an extra +1 for the bitshift for readability
MakerOfThings7
A: 

If you know which bit to check and you're dealing with int's you can use BitVector32.

int yourValue = 5;
BitVector32 bv = new BitVector32(yourValue);
int bitPositionToCheck = 3;
int mask = Enumerable.Range(0, bitPositionToCheck).Select(BitVector32.CreateMask).Last();
bool isSet = bv[mask];

Using bitshifting is probably cleaner than using CreateMask. But it's there :)

Mikael Svenson