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

Community
  • 1
  • 1
makerofthings7
  • 60,103
  • 53
  • 215
  • 448

2 Answers2

7

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
  • 25,073
  • 7
  • 56
  • 55
  • Just to clarify, will my AND be nonzero if resflag is: 0x00011010? That is my goal. – makerofthings7 Sep 29 '10 at 18:22
  • 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 Sep 29 '10 at 18:25
  • @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 Sep 29 '10 at 18:26
0

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
  • 39,181
  • 7
  • 73
  • 79