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]

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
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");
}
}