C# (csharp) Bitfields - PackedByte, PackedUShort
DZone's Guide to
C# (csharp) Bitfields - PackedByte, PackedUShort
Join the DZone community and get the full member experience.
Join For FreeIn c++ it is possible to have fields smaller than one byte with bitfields:
struct Tile
{
char Type:4;
bool River:1;
bool Fortress:1;
char Road:2;
};
Below is a way to have bitfields in C#. The speed is quite acceptable, and in this example PackedByte allowed to fit four byte values in one byte.
How to use:
public struct Tile
{
PackedByte data1;
///
/// 4 bits (0-15)
///
public byte Type
{
get { return (byte)data1.Get(0,4); }
set { data1.Set(0,4,(byte)value); }
}
///
/// 1 bit
///
public bool River
{
get { return data1.Get(4,1)!=0; }
set { data1.Set(4,1,value?(byte)1:(byte)0); }
}
///
/// 1 bit
///
public bool Fortress
{
get { return data1.Get(5,1)!=0; }
set { data1.Set(5,1,value?(byte)1:(byte)0); }
}
///
/// 2 bits (0-3)
///
public RoadState Road
{
get { return (RoadState)data1.Get(6,2); }
set { data1.Set(6,2,(byte)value); }
}
}
public struct PackedByte
{
public PackedByte(byte data)
{
this.data=data;
}
static byte[] masks=
{
0,
2-1,//1
4-1,//2
8-1,//3
16-1,//4
32-1,//5
64-1,//6
128-1,//7
256-1,//8
};
public byte Get(int start,int count)
{
byte mask=masks[count];
return (byte)((data&(mask<
>start);
}
public void Set(int start,int count,byte data)
{
byte mask=masks[count];
if (data>mask)
{
throw new ArgumentOutOfRangeException();
}
this.data=(byte)(this.data&(~(mask<
>start);
}
public void Set(int start,int count,ushort data)
{
ushort mask=masks[count];
if (data>mask)
{
throw new ArgumentOutOfRangeException();
}
this.data=(ushort)(this.data&(~(mask<
Topics:
Opinions expressed by DZone contributors are their own.
{{ parent.title || parent.header.title}}
{{ parent.tldr }}
{{ parent.linkDescription }}
{{ parent.urlSource.name }}