Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!


1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!


[.net] Bitwise check - best way?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
16 replies to this topic

#1 devronious   Members   -  Reputation: 108

Like
0Likes
Like

Posted 07 February 2008 - 07:27 AM

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

Sponsor:

#2 jonahrowley   Members   -  Reputation: 300

Like
0Likes
Like

Posted 07 February 2008 - 07:33 AM

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.

#3 Machaira   Moderators   -  Reputation: 1028

Like
0Likes
Like

Posted 07 February 2008 - 07:37 AM

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

#4 devronious   Members   -  Reputation: 108

Like
0Likes
Like

Posted 07 February 2008 - 09:04 AM

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.

#5 KulSeran   Members   -  Reputation: 2621

Like
0Likes
Like

Posted 07 February 2008 - 09:18 AM

you really only need to write
if (this.bufferDataChanged & DataType.Vertex)
the == DataType.Vertex is redundant


#6 Niksan2   Members   -  Reputation: 265

Like
0Likes
Like

Posted 07 February 2008 - 10:48 AM

> 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.


#7 Scet   Members   -  Reputation: 960

Like
0Likes
Like

Posted 07 February 2008 - 10:54 AM

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.



#8 devronious   Members   -  Reputation: 108

Like
0Likes
Like

Posted 07 February 2008 - 04:37 PM

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.

#9 Leandro GR   Members   -  Reputation: 533

Like
0Likes
Like

Posted 08 February 2008 - 12:42 AM

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.

#10 SiCrane   Moderators   -  Reputation: 9802

Like
0Likes
Like

Posted 08 February 2008 - 02:08 AM

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...}



#11 devronious   Members   -  Reputation: 108

Like
0Likes
Like

Posted 08 February 2008 - 02:50 AM

Quote:
You are only missing one nice feature of .Net, the FlagsAttribute


Super awesome! Didn't know that. I will use that from now on.

Hey, along that subject, what's the difference between [Flags] and [Flags()]? Is there? Or is it just extra typing?

SiCrane,

Holy Crap, how did you figure that out? That's pretty interesting and smart. Thanks. I wonder if a universal one can be made for various different enums? Or if we can somehow custom add our own operator to Visual Studio 2005-2008? Perhaps thru the SDK? Hmmm...

-Devin

#12 SiCrane   Moderators   -  Reputation: 9802

Like
0Likes
Like

Posted 08 February 2008 - 03:44 AM

If you really want one for all Enums:

class Contains {
Contains(Int64 d) { v = d; }
Int64 v;
public static bool operator &(Contains c, Enum d) {
return (c.v & Convert.ToInt64(d)) != 0;
}
public static explicit operator Contains(Enum d) {
return new Contains(Convert.ToInt64(d));
}
}

It's still evil, however.

#13 devronious   Members   -  Reputation: 108

Like
0Likes
Like

Posted 09 February 2008 - 08:25 AM

Cool, I also put in a feature request for something to this effect with a keyword.

[edit]

Quote:
It's still evil, however


Ya I would tend to think that is a bit around the corner and down the road and across the bridge thru some towns, and so on :) But still you figured it out which gives merit.

[Edited by - devronious on February 10, 2008 8:25:45 PM]

#14 Nypyren   Crossbones+   -  Reputation: 5574

Like
0Likes
Like

Posted 13 February 2008 - 04:49 PM

Quote:
Original post by SiCrane
If you really want one for all Enums:

class Contains {
Contains(Int64 d) { v = d; }
Int64 v;
public static bool operator &(Contains c, Enum d) {
return (c.v & Convert.ToInt64(d)) != 0;
}
public static explicit operator Contains(Enum d) {
return new Contains(Convert.ToInt64(d));
}
}

It's still evil, however.


You might go the extra mile and make a C# 3.0 extension method on the Enum base class itself. I don't have my tools installed on this machine yet (building a new computer) but it seems like you should be able to make something less "evil" that way.

#15 SiCrane   Moderators   -  Reputation: 9802

Like
0Likes
Like

Posted 14 February 2008 - 01:54 AM

I'm not really familiar with C# 3 right now. Could you give an example when you're set up?

Quote:

Cool, I also put in a feature request for something to this effect with a keyword.

Though if you really want something that looks like a keyword:

public struct Proxy {
internal long v;

public Proxy(long val) {
v = val;
}

public static bool operator >(Proxy p, Enum e) {
return (p.v & Convert.ToInt64(e)) != 0;
}

public static bool operator <(Proxy p, Enum e) {
return (p.v & Convert.ToInt64(e)) != 0;
}
}

struct C {
public static Proxy operator <(Enum e, C c) {
return new Proxy(Convert.ToInt64(e));
}
public static Proxy operator >(Enum e, C c) {
return new Proxy(Convert.ToInt64(e));
}

static C contains = new C();
}

if (this.bufferDataChanged <C.contains> DataType.Vertex) {do this...}
// or
C contains = new C();
if (this.bufferDataChanged <contains> DataType.Vertex) {do this...}

As you may imagine, still evil.

#16 benryves   Members   -  Reputation: 1998

Like
0Likes
Like

Posted 14 February 2008 - 02:48 AM

A C#3 example could be something like this:
public static class EnumContains {
public static bool Contains(this Enum e, Enum bit) {
return (Convert.ToInt32(e) & Convert.ToInt32(bit)) != 0;
}
}


You could then use it like this:
class Program {

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

static void Main(string[] args) {

var Test = DataType.UV | DataType.Norm;

Console.WriteLine("Test = {0}", Test);

foreach (DataType Bit in Enum.GetValues(typeof(DataType))) {
Console.WriteLine("Test.Contains({0})\t={1}", Bit, Test.Contains(Bit));
}

}
}

[Website] [+++ Divide By Cucumber Error. Please Reinstall Universe And Reboot +++]

#17 devronious   Members   -  Reputation: 108

Like
0Likes
Like

Posted 15 February 2008 - 02:12 PM

Thanks guys, really interesting to see the different solutions to the same problem. Goes to show how programming is so broad and open.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS