Bit Shifting for Flags ( Constructive Criticism Please)

I came up with a class that handles flag manipulation using Bitwise operators. Does anyone think this is more efficient than using boolean variables for flags? Or is this just overkill.

The reason Im asking is Ive used this approach before on Muds that I have written/updated. Just wondering if it is outdated.

/*

* Allows for 64 different on/off flags.

*/

publicclass State

{

publicstaticfinalbyte ST_00 = (byte)0 ;

publicstaticfinalbyte ST_01 = (byte)1 ;

....fill here......

publicstaticfinalbyte ST_63 = (byte)63 ;

privateint lowStates = 0;

privateint highStates = 0 ;

publicboolean is(byte bitIndex )

{

if( bitIndex > 31 )

return ( (highStates & ( 1 << (bitIndex%32) )) == 1 ?true :false ) ;

else

return ( (lowStates & ( 1 << bitIndex ) ) == 1 ?true :false ) ;

}

publicvoid remove(byte bitIndex )

{

if( bitIndex > 31 )

highStates &= ~(1 << (bitIndex%32) ) ;

else

lowStates &= ~(1 << bitIndex ) ;

}

publicvoid set(byte bitIndex )

{

if( bitIndex > 31 )

highStates |= (1 << (bitIndex%32) ) ;

else

lowStates |= (1 << bitIndex ) ;

}

publicvoid toggle(byte bitIndex )

{

if( bitIndex > 31 )

highStates ^= (1 << (bitIndex%32) ) ;

else

lowStates ^= (1 << bitIndex) ;

}

}

/*

* Simple implementation

*/

publicclass INeedFlags

{

publicstaticfinalbyte FLAG_1 = ST_00 ;

publicstaticfinalbyte FLAG_2 = ST_01 ;

public State flags =new State() ;

publicstaticvoid main(String[] args)

{

INeedFlags obj =new INeedFlags() ;

obj.flags.set( FLAG_1 );

obj.flags.toggle( FLAG_2 ) ;

if( obj.flags.is( FLAG_1 ) )

System.out.println("Yep its set");

}

}

[4562 byte] By [yoda23] at [2007-9-27 19:06:12]
# 1

Your method is good for tedious flag-checking like MUDs would do. Though more often such applications require checking of a group of flags. So, I suggest that a constructor State( int numberOfFlags ) be written together with methods like isAllSet(), isAllClear(), setAll(), clearAll().

Nevertheless, boolean flags are still superb because they allow grouping. The only drawbacks are of course its requiring a large memory pool and many different names.

Unless you've got a tight "budget" of memory use, I will always suggest using boolean.

Hope that helps.

Faifai

Yfaifai at 2007-7-6 21:21:17 > top of Java-index,Other Topics,Java Game Development...
# 2
If you've got the memory, why not use a typesafe enum and a Set?
YATArchivist at 2007-7-6 21:21:17 > top of Java-index,Other Topics,Java Game Development...
# 3

if you have 64 states why don't you just use a long? then each bit corresponds to a state.

state 0 = 2^0 = 0x0000000000000001L

state 1 = 2^1 = 0x0000000000000002L

state 2 = 2^2 = 0x0000000000000004L

state 3 = 2^3 = 0x0000000000000008L

etc.

.

.

.

state 63 = 2^63 = 0x8000000000000000L

alee1010 at 2007-7-6 21:21:17 > top of Java-index,Other Topics,Java Game Development...
# 4
thats basically what Im doing. Since you cant shift for check bits on anything but an int, Im just using two separate int values.
yoda23 at 2007-7-6 21:21:17 > top of Java-index,Other Topics,Java Game Development...
# 5
> thats basically what Im doing. Since you cant shift> for check bits on anything but an int, Im just using> two separate int values.?Bytes and shorts cast to ints. Bit operations work on both ints and longs.
alee1010 at 2007-7-6 21:21:17 > top of Java-index,Other Topics,Java Game Development...
# 6
Wierd. I kept getting compile errors when trying that before. But it works now.
yoda23 at 2007-7-6 21:21:17 > top of Java-index,Other Topics,Java Game Development...
# 7

i often use bit flags.

my variation is to have the flag constants as long bitmasks.

this allows for multiple flag set / test in one instruction :

if (flags.has(FLAG_1 | FLAG_3)) {..}

also no bitshifting required should make it as fast as comparing booleans.

( in c++, the compiler optimises it away to almost nothing).

the java code is a quick hack of your post (sorry about the indents)

Adrian

/*

* Allows for 64 different on/off flags.

*/

public class State

{

public static final long ST_00 = 0x00000001 ;

public static final long ST_01 = 0x00000002 ;

public static final long ST_02 = 0x00000004 ;

....fill here......

public static final long ST_62 = 0x40000000 ;

public static final long ST_63 = 0x80000000 ;

public State(long bitFlags)

{

state = bitFlags;

}

private int state = 0;

public long value()

{

return ( state );

}

public boolean equals( long bitFlags )

{

return ( state == bitFlags ) ;

}

public boolean is( long bitFlag )

{

return ( has(bitFlag) ) ;

}

public boolean has( long bitFlags )

{

return ( (state & bitFlags) != 0 ) ;

}

public void clear( )

{

state = 0 ;

}

public void remove( long bitFlags )

{

state &= ~bitFlags ;

}

public void set( long bitFlags )

{

state |= bitFlags ;

}

public void toggle( long bitFlags )

{

state ^= bitFlags ;

}

}

/*

* Simple implementation

*/

public class INeedFlags

{

public static final long FLAG_1 = ST_00 ;

public static final long FLAG_2 = ST_01 ;

public static final long FLAG_3 = ST_02 ;

public State flags = new State() ;

public static void main(String[] args)

{

/*

* This still works

*/

INeedFlags obj = new INeedFlags() ;

obj.flags.set( FLAG_1 );

obj.flags.toggle( FLAG_2 ) ;

if( obj.flags.is( FLAG_1 ) )

System.out.println("Yep its set");

/*

* but you can also say

*/

obj.flags.clear( );

obj.flags.set(FLAG_1 | FLAG_2);

if( obj.flags.has( FLAG_2 | FLAG_3 ) )

System.out.println("one of them is set");

}

}

AdrianAS at 2007-7-6 21:21:17 > top of Java-index,Other Topics,Java Game Development...
# 8
That is what I origionally had, with the ST_00 being = 1 << 0 ; etc. but I thought it wouldn't work with longs. With that back in place, and changing the toggle.remove.set methods to work with the multiple values, this will work much better. Thanks for the input.
yoda23 at 2007-7-6 21:21:17 > top of Java-index,Other Topics,Java Game Development...