Platinum Partner

C# (csharp) Bitfields - PackedByte, PackedUShort

In 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<
{{ tag }}, {{tag}},

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}
{{ parent.authors[0].realName || parent.author}}

{{ parent.authors[0].tagline || parent.tagline }}

{{ parent.views }} ViewsClicks
Tweet

{{parent.nComments}}