[.net] Bitwise check - best way?

Started by
15 comments, last by devronious 16 years, 2 months ago
I'm looking for the best way to check for a bit within a value. My current operation does the following, but I think it's cumbersome maybe:


//here's the enum with the bitwise values:

    /// <summary>
    /// This enumerates the various data types that can be modified within the buffers of the VertexEngine system.
    /// </summary>
    public enum DataType
    {
        /// <summary>
        /// Indicates None.
        /// </summary>
        None=0,
        /// <summary>
        /// Indicates Vertex data.
        /// </summary>
        Vertex=1,
        /// <summary>
        /// Indicates Index data.
        /// </summary>
        Index = 2,
        /// <summary>
        /// Indicates UV data.
        /// </summary>
        UV = 4
    }

//here's the check I do to see if a member (this.bufferDataChanged) holds one of the enums:

    if ((this.bufferDataChanged & DataType.Vertex) == DataType.Vertex) {do this...}


Thanks for any help, Devin
Advertisement
That's pretty much the standard way to check for a bit in a bitfield. If you're looking for that bit and that bit only, then yes, you'll need to be using the == operator. A bitfield is used to indicate a range of options which may exist in any combination. If you only check for one sole condition (a single bit begin set), then you don't want a bitfield, you want a variable holding the enum value.
What's wrong with that? That's the way I do it.

Former Microsoft XNA and Xbox MVP | Check out my blog for random ramblings on game development

Quote:If you only check for one sole condition (a single bit begin set), then you don't want a bitfield, you want a variable holding the enum value.


Not sure what you mean, can you explain more please?

Quote:What's wrong with that? That's the way I do it.


I guess I'm looking for something more C# like :) ya know like:

if (this.bufferDataChanged 'contains' DataType.Vertex) {do this...}


Seems like that would be a pretty common use for us programmers. I guess I thought there was something already there that I was missing. Perhaps not.
you really only need to write
if (this.bufferDataChanged & DataType.Vertex)
the == DataType.Vertex is redundant
> Not sure what you mean, can you explain more please?

I assume he means, you don't really need to use bits if only one of the bits can be set a given time, and not multiple bits, so you probably would be better using enumeration or something.
Quote:Original post by KulSeran
you really only need to write
if (this.bufferDataChanged & DataType.Vertex)
the == DataType.Vertex is redundant


Maybe in some other languages, but in C# that statement will return a DataType not a bool, and the compiler will complain.

Quote:Maybe in some other languages, but in C# that statement will return a DataType not a bool, and the compiler will complain.


That's what I thought but wasn't sure. I haven't tried it yet, still just coding, not compiling yet.

Quote:I assume he means, you don't really need to use bits if only one of the bits can be set a given time, and not multiple bits, so you probably would be better using enumeration or something.


Yea it is a bitwise enumeration:

public enum DataType
{
None=0,
Vertex=1,
Index = 2,
UV = 4,
XYZ = 8,
Norm = 16
}

Setting the values of each enum member to the corresponding bit placement. Then I can mix enum members together as I will. Because I do in fact need to mix two or more enum members together at times.
You are only missing one nice feature of .Net, the FlagsAttribute

[Flags]public enum DataType{    None=0,    Vertex=1,    Index = 2,    UV = 4,    XYZ = 8,    Norm = 16}


If you have something like

DataType dt = DataType.Vertex | DataType.Index;

If you are not using the FlagsAttribute, when you check the value while debugging or when you use the ToString you will see the value 3, as expected, but with FlagsAttribute you will see the value "Vertex | Index" while debugging and ToString will return "Vertex, Index" instead of 3, so you don't have to figure out which bits are set while debugging.
If you just want to reduce the amount of typing you do, you can use != 0 rather than == DataType.Vertex. Or for the evil operator overloading crowd:
  class Contains {    Contains(DataType d) { v = d; }    DataType v;    public static bool operator &(Contains c, DataType d) {      return (c.v & d) != 0;    }    public static explicit operator Contains(DataType d) {      return new Contains(d);    }  }  if ((Contains)this.bufferDataChanged & DataType.Vertex) {do this...}

This topic is closed to new replies.

Advertisement