Need more than 64 bits for mask - Long data type

  • Thread starter Thread starter Richard Dixson
  • Start date Start date
R

Richard Dixson

I have a need for a variable to hold a bitwise mask that can exceed 64
possible values. What is the best way to do this using C#?

For example, currently I have a variable called optionsMask that is defined
as a Long. Then I set the constants like this:
public const long BLACK = 0L; // 1st
public const long GREEN = 1L; // 2nd
public const long RED = 2L; // 3rd
public const long BLUE = 4L; // 4th
public const long PURPLE = 8L; // 5th
public const long PINK = 16L; // 6th
public const long GRAYBLUE = 32L; // 7th
...
public const long HONEYDUE = 4611686018427387904L; // 64th, max
possible :(

Then in my code I am doing things like: long optionsMast = BLACK | RED |
HONEYDUE;

Also other developers in my group set the bitmask in their code and pass it
into my library via a setter (if this matters).

Now of course the challenge is that I have run out of values for the mask at
64! If I change to use a ulong that gets me one more value
(9223372036854775808), but on the next one (18446744073709551616) I of
course get the error "Integral constant is too large".

So this brings me back to my main question - what is the best approach to be
able to use a single variable to store combinations of flags that go beyond
64?

I realize I could start another mask, like optionsMask2, but that would get
very messy in the code (having to check two different variables for set
bits, plus developers would have to know which bits to set on which mask
variable - this would be very poor I think).

For performance reasons it is very important that I do this using some sort
of numeric representation that can be tested to see what bits are set in the
mask very quickly. For example the current approach works great, except its
limited to 64 combinations. For instance I could not use an approach that
used strings like "black, green, blue " and then seached in the string for
values like ", green" to see if there was a match.

I am using C#. Ideally I would like whatever new approach is needed to
solve this issue to also work with the .NET framework 1.0. However if there
is a much more elegant version in 1.1 I would consider it.

Can someone please let me know if there is some sort of construct that would
enable me to create a bitwise mask (or something equal in performance) for
combining more than 64 combinations? If it matters, this is something that
my developers use outside via a setting (for example they currently build
the mask in their C# code and pass it in via a setter property in my code
library). Ideally the approach would not be limit future expansion to
another max ceiling number; however an approach that gets me about another
20 or 30 options should do ok for a while at least.

Thank you very much in advance,

Richard
 
System.Collections.BitArray?

Richard Dixson said:
I have a need for a variable to hold a bitwise mask that can exceed 64
possible values. What is the best way to do this using C#?

For example, currently I have a variable called optionsMask that is
defined as a Long. Then I set the constants like this:
public const long BLACK = 0L; // 1st
public const long GREEN = 1L; // 2nd
public const long RED = 2L; // 3rd
public const long BLUE = 4L; // 4th
public const long PURPLE = 8L; // 5th
public const long PINK = 16L; // 6th
public const long GRAYBLUE = 32L; // 7th
...
public const long HONEYDUE = 4611686018427387904L; // 64th, max
possible :(

Then in my code I am doing things like: long optionsMast = BLACK | RED |
HONEYDUE;

Also other developers in my group set the bitmask in their code and pass
it into my library via a setter (if this matters).

Now of course the challenge is that I have run out of values for the mask
at 64! If I change to use a ulong that gets me one more value
(9223372036854775808), but on the next one (18446744073709551616) I of
course get the error "Integral constant is too large".

So this brings me back to my main question - what is the best approach to
be able to use a single variable to store combinations of flags that go
beyond 64?

I realize I could start another mask, like optionsMask2, but that would
get very messy in the code (having to check two different variables for
set bits, plus developers would have to know which bits to set on which
mask variable - this would be very poor I think).

For performance reasons it is very important that I do this using some
sort of numeric representation that can be tested to see what bits are set
in the mask very quickly. For example the current approach works great,
except its limited to 64 combinations. For instance I could not use an
approach that used strings like "black, green, blue " and then seached in
the string for values like ", green" to see if there was a match.

I am using C#. Ideally I would like whatever new approach is needed to
solve this issue to also work with the .NET framework 1.0. However if
there is a much more elegant version in 1.1 I would consider it.

Can someone please let me know if there is some sort of construct that
would enable me to create a bitwise mask (or something equal in
performance) for combining more than 64 combinations? If it matters, this
is something that my developers use outside via a setting (for example
they currently build the mask in their C# code and pass it in via a setter
property in my code library). Ideally the approach would not be limit
future expansion to another max ceiling number; however an approach that
gets me about another 20 or 30 options should do ok for a while at least.

Thank you very much in advance,

Richard
 
Richard Dixson said:
I have a need for a variable to hold a bitwise mask that can exceed 64
possible values. What is the best way to do this using C#?

Now of course the challenge is that I have run out of values for the mask
at 64! If I change to use a ulong that gets me one more value
(9223372036854775808), but on the next one (18446744073709551616) I of
course get the error "Integral constant is too large".

Why not just use RGB values, which fit into 32 bits? This would be easier
to manage as well as having better performance. It is faster to check n ==
constant than it is to test a bit in a 128 bit bitfield.

-- Alan
 
Its critical that the developers that use my library can refer to these
options by name. So I need some sort of system based around enums or some
sort of predefined values/constants they can refer to. For example:
myLib.options = something.RED | something.BLUE | something.HONEYDUE;

Maybe I do not understand what has been proposed here so far but from the
sounds of it these proposed solutions would be good internal tracking but
not allow for values to be set by name (such as RED, BLUE etc). Nor would I
be able to check it in my code by constant name (which makes the code much
more readable and easier to obtain). Am I missing something?

Thanks.
 
Thanks for the suggestion. However I am not actually tracking color
options. I just picked colors for demonstration purposes to try and keep
the example simple. I'm trying to find out if the C# language has a
construct of sorts that allows for what I am after. I think its sort of
like an enum, but with the ability to combine enums into a mask, or
something like that.
 
Richard Dixson said:
Thanks for the suggestion. However I am not actually tracking color
options. I just picked colors for demonstration purposes to try and keep
the example simple. I'm trying to find out if the C# language has a
construct of sorts that allows for what I am after. I think its sort of
like an enum, but with the ability to combine enums into a mask, or
something like that.

OK. Is it always the case where there will only be ONE bit set at a time?
You really only need a mask if there is the possibility of multiple bits set
simultaneously.

-- Alan
 
Yes, in most typical cases there is anywhere from at least 2 - 20 bits set
simultaneously. In some cases just about all bits are set with the
exception of a few.

Richard
 
Thanks for the suggestion. However I am not actually tracking color
options. I just picked colors for demonstration purposes to try and
keep the example simple. I'm trying to find out if the C# language
has a construct of sorts that allows for what I am after. I think its
sort of like an enum, but with the ability to combine enums into a
mask, or something like that.

What about a System.Collections.BitArray? You can't directly use enums to
represent it, but it will hold as many bits as you want. You could use
enum values to represent which bit in the array hold that value, and some
methods to get/set them.

-mdb
 
Richard Dixson said:
Yes, in most typical cases there is anywhere from at least 2 - 20 bits set
simultaneously. In some cases just about all bits are set with the
exception of a few.

As mdb says, then, I would use a BitArray, and use const ints or enums to
define the bit in the array.

public enum Bits {
Black = 0,
Blue = 1,
etc.
}

System.Collections.BitArray x = new System.Collections.BitArray(128 or
whatever);

Then later in code:

x[Black] = true;
if (x[Blue]) {
// whatever
}

etc.

-- Alan
 
Looks promising. Thanks for showing the syntax for checking the bits - that
is very helpful.

What would the syntax look like for setting the bits? Is there a convenient
way for the developers using my library to set these values in one line?

For example, now they can just do this:
long options = BLUE | GREEN | RED | GRAY;

Is there some construct that will accept multiple bits to be set together
(on line line, sort of like what I showed above) using this new approach you
are recommending? And if so, what what that syntax look like? What I'd
like to avoid is a situation where they have to do something like this:

Thanks.

Alan Pretre said:
Richard Dixson said:
Yes, in most typical cases there is anywhere from at least 2 - 20 bits
set simultaneously. In some cases just about all bits are set with the
exception of a few.

As mdb says, then, I would use a BitArray, and use const ints or enums to
define the bit in the array.

public enum Bits {
Black = 0,
Blue = 1,
etc.
}

System.Collections.BitArray x = new System.Collections.BitArray(128 or
whatever);

Then later in code:

x[Black] = true;
if (x[Blue]) {
// whatever
}

etc.

-- Alan
 
Richard Dixson said:
Looks promising. Thanks for showing the syntax for checking the bits -
that is very helpful.

What would the syntax look like for setting the bits? Is there a
convenient way for the developers using my library to set these values in
one line?

For example, now they can just do this:
long options = BLUE | GREEN | RED | GRAY;

Is there some construct that will accept multiple bits to be set together
(on line line, sort of like what I showed above) using this new approach
you are recommending? And if so, what what that syntax look like? What
I'd like to avoid is a situation where they have to do something like
this:

I don't see a way to set them conveniently with standard members. But it
would be easy enough to derive a class from the framework class and make a
new methods like so:

public enum Colors {
Black = 0,
Blue = 1,
Red = 2,
etc.
}

// Constructor:
public MyBitArray(params Colors[] SetColors) : base(128) {
foreach (Colors Color in SetColors) this[Color] = true;
return;
}

// Setter:
public void Set(params Colors[] SetColors) {
this.SetAll(false);
foreach (Colors Color in SetColors) this[Color] = true;
return;
}

Then you could do:
MyBitArray x = new MyBitArray(Colors.Black);
MyBitArray x = new MyBitArray(Colors.Black, Colors.Red);
MyBitArray x = new MyBitArray(Colors.Black, Colors.Blue, Colors.Red);
x.Set(Colors.Black);
x.Set(Colors.Black, Colors.Red);
x.Set(Colors.Black, Colors.Blue, Colors.Red);

-- Alan
 
You can use constants for indexing in a bitarray. So you just have to store
one bit per color every time and you can have unlimited colors.

class Colors
{
public const int RED = 1;
// more colors
public const int FUNNY_COLOR = 1;
}

colors[Colors.RED] = true;
 
Back
Top