`

c# - Bit fields in C#

    博客分类:
  • C#
c# 
阅读更多

this is a thread that is inspired by the thoght and discusson from the stackoverflow. and hte original post is here:  Bit fields in C#.

 

 

As a background/foundamental knowledge,or the first question to ask: what is bit fields?

 

 

Bit Fields is a extremely space saving technique which is quit commonly used in C++ proramms

 

 

here is one example of the BitField in C++:

 

 

 

class BitFields { 
  public:
    int mode : 2;
	int full_flag : 1;
	int empty_flag : 1;

  };

 

 and you can use it this way:

 

 

enum { On = 0, Off = 1 } ;
enum { Yes = 0, No = 1 };

int main() { 
    BitFields bitFields;
	bitFields.mode |= On;
	bitFields.full_flag &= ~Yes;
}

 

 

 

 

Why do we need the Bit Fields classes, it is space effecient, and it is easy to manipulate. But they are not natively built inside the C# language. 

 

 

 

 

Given an example.

 

 

suppose that we are going to model a flag as this: 

 

 

byte-6    
bit0 - original_or_copy  
bit1 - copyright  
bit2 - data_alignment_indicator  
bit3 - PES_priority  
bit4-bit5 - PES_scrambling control.  
bit6-bit7 - reserved

 

 

 

and you can do this in C

 

 

struct PESHeader  {
    unsigned reserved:2;
    unsigned scrambling_control:2;
    unsigned priority:1;
    unsigned data_alignment_indicator:1;
    unsigned copyright:1;
    unsigned original_or_copy:1;
};

 

 

 

Let's first examine some solution that has been discussed.

 

The StructLayoutAttribute solution

 

 

 

static class StructLayoutResolution
  {
    // the Fool structure is using a union approach.
    // or you can change the Explicit location so that they can aligh with each other sequentially
    // or you can try the LayoutKind.Sequential
    public void DemoStructLayoutResolution()
    {
      
      Foo foo = new Foo();
      Console.WriteLine("foo.original_or_copy = {0}", foo.original_or_copy);

    }

    const byte _original_or_copy = 1;
    const byte _copyright = 2;

    static bool original_or_copy(this Foo foo)
    {
      return (foo.original_or_copy & _original_or_copy) == _original_or_copy;
    }
  }

  // you can use the StructlayoutAttribute 
  //   http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.structlayoutattribute%28VS.71%29.aspx
  [StructLayout(LayoutKind.Explicit, Size = 1, CharSet=CharSet.Ansi)]
  public struct Foo
  {
    [FieldOffset(0)]
    public byte original_or_copy;
    [FieldOffset(0)]
    public byte copyright;
    [FieldOffset(0)]
    public byte data_alignment_indicator;
    [FieldOffset(0)]
    public byte PES_prioirty;
    [FieldOffset(0)]
    public byte reserved;
  }
 

 

The code shown above is the union approach, but you can use the bit fields approach, by changing the Layoutkind from LayoutKind.Explicit to LayoutKind.Sequential.

 

 

The custom attributes solution

 

 

 

// this is using a custmo attribute , where you can decorate the fields just as you can do with the StructLayoutAttribute
  class CustomAttributeResoltuion
  {
    public static void DemoCustomAttributeTechnique()
    {
      PSEHeader p = new PSEHeader();
      p.reserved = 3;
      p.scrambling_control = 2;
      p.data_alignment_indicator = 1;

      long l = PrimitiveConversion.ToLong(p);

      for (int i = 63; i >= 0; i--)
      {
        Console.WriteLine(((l & (1L << i)) > 0) ? "1" : "0");
      }
      Console.WriteLine();
      return;
    }
  }

  [AttributeUsage(AttributeTargets.Field, AllowMultiple=false)]
  sealed class BitfieldLengthAttribute : Attribute
  {
    uint length;

    public BitfieldLengthAttribute(uint length)
    {
      this.length = length;
    }

    public uint Length { get { return this.length; } }
  }

  // this is a helper class that helps you to convert a structure that is decorated with BitfieldLengthAttribute 
  // to a long value
  static class PrimitiveConversion
  {
    public static long ToLong<T>(T t) where T : struct
    {
      long r = 0;
      int offset = 0;

      foreach (var f in t.GetType().GetFields())
      {
        var attrs = f.GetCustomAttributes(typeof(BitfieldLengthAttribute), false);
        if (attrs.Length == 1)
        {
          uint fieldlength = ((BitfieldLengthAttribute)attrs[0]).Length;

          long mask = 0;
          for (int i = 0; i < fieldlength; i++)
            mask |= 1 << i;

          r |=( (UInt32)f.GetValue(t) & mask) << offset;

          offset += (int)fieldlength;
        }

      }
      return r;
    }
  }

  struct PSEHeader
  {
    [BitfieldLength(2)]
    public uint reserved;
    [BitfieldLength(2)]
    public uint scrambling_control;
    [BitfieldLength(1)]
    public uint priority;
    [BitfieldLength(1)]
    public uint data_alignment_indicator;
    [BitfieldLength(1)]
    public uint copyright;
    [BitfieldLength(1)]
    public uint original_or_copy;
  }

 

 

 

However, be cautions that this approach uses the Type.GetFields() call, which, according to the MSDN, does not guarantee to return the fields in the order that they are declared.

 

 

So you have to use it with caution.

 

 

BitVector approach

This is probably the most native one, the bit vector is a managed class and it is natural to use. 

 

public static class BitVectorMethod
  {
    public static void BitVectorDemo()
    {
      rcSpan rcspan = new rcSpan();
      rcspan.smin = 13;

      rcSpan2 rcspan2 = new rcSpan2();
      rcspan2.smin = 13;
    }
  }


  public struct rcSpan
  {
    internal static readonly BitVector32.Section sminSection = BitVector32.CreateSection(0x1FFF);
    internal static readonly BitVector32.Section smaxSection = BitVector32.CreateSection(0x1FFF, sminSection);
    internal static readonly BitVector32.Section areaSection = BitVector32.CreateSection(0x3F, smaxSection);

    // the internal storage class object.
    internal BitVector32 data;


    // public uint smin: 13;
    public uint smin
    {
      get { return (uint)data[sminSection]; }
      set { data[sminSection] = (int)value; }
    }

    // public uint smax: 13;
    public uint smax
    {
      get { return (uint)data[smaxSection]; }
      set { data[smaxSection] = (int)value; }
    }
    // public uint area: 6;
    public uint area
    {
      get { return (uint)data[areaSection]; }
      set { data[areaSection] = (int)value; } 
    }

    


  }

  // or you can do some handmade access this way

  public struct rcSpan2
  {
    // andyou can do more
    // such as provide the handmade accessors for every fields

    internal uint data;

    // pulbic uint smin: 13
    public uint smin
    {
      get { return (uint)data & 0x1FFFF; }
      set { data = (data & ~0x1FFFFu) | (value & 0x1FFFF); }
    }

    //public uint smax : 13; 
    public uint smax
    {
      get { return (data >> 13) & 0x1FFF; }
      set { data = (data & ~(0x1FFFu << 13)) | (value & 0x1FFF) << 13; }
    }

    //public uint area : 6; 
    public uint area
    {
      get { return (data >> 26) & 0x3F; }
      set { data = (data & ~(0x3F << 26)) | (value & 0x3F) << 26; }
    }
  }
 

As you can see, that in the code above, we are not only show the native bitvector approach, we are actually using some custom handmade bitvector acesss, but the priciple is the same.

 

 

 

 

分享到:
评论

相关推荐

    基于springboot个人公务员考试管理系统源码数据库文档.zip

    基于springboot个人公务员考试管理系统源码数据库文档.zip

    bimdata_api_client-4.2.1-py3-none-any.whl

    bimdata_api_client-4.2.1-py3-none-any.whl

    numpy-1.20.2-cp39-cp39-linux_armv7l.whl

    numpy-1.20.2-cp39-cp39-linux_armv7l.whl

    matplotlib-3.3.2-cp39-cp39-linux_armv7l.whl

    matplotlib-3.3.2-cp39-cp39-linux_armv7l.whl

    bimdata_api_client-4.0.0-py3-none-any.whl

    bimdata_api_client-4.0.0-py3-none-any.whl

    ta_lib-0.5.1-cp312-cp312-win32.whl

    ta_lib-0.5.1-cp312-cp312-win32.whl

    基于springboot的非学勿扰学习交流平台源码数据库文档.zip

    基于springboot的非学勿扰学习交流平台源码数据库文档.zip

    基于springboot云平台的信息安全攻防实训平台源码数据库文档.zip

    基于springboot云平台的信息安全攻防实训平台源码数据库文档.zip

    pillow-10.4.0-cp311-cp311-linux_armv7l.whl

    pillow-10.4.0-cp311-cp311-linux_armv7l.whl

    springboot229基于Spring Boot的企业员工薪酬关系系统的设计.zip

    论文描述:该论文研究了某一特定领域的问题,并提出了新的解决方案。论文首先对问题进行了详细的分析和理解,并对已有的研究成果进行了综述。然后,论文提出了一种全新的解决方案,包括算法、模型或方法。在整个研究过程中,论文使用了合适的实验设计和数据集,并进行了充分的实验验证。最后,论文对解决方案的性能进行了全面的评估和分析,并提出了进一步的研究方向。 源码内容描述:该源码实现了论文中提出的新的解决方案。源码中包含了算法、模型或方法的具体实现代码,以及相关的数据预处理、实验设计和性能评估代码。源码中还包括了合适的注释和文档,以方便其他研究者理解和使用。源码的实现应该具有可读性、可维护性和高效性,并能够复现论文中的实验结果。此外,源码还应该尽可能具有通用性,以便在其他类似问题上进行进一步的应用和扩展。

    基于springboot+web的学生作业管理系统源码数据库文档.zip

    基于springboot+web的学生作业管理系统源码数据库文档.zip

    springboot244基于SpringBoot和VUE技术的智慧生活商城系统设计与实现.zip

    论文描述:该论文研究了某一特定领域的问题,并提出了新的解决方案。论文首先对问题进行了详细的分析和理解,并对已有的研究成果进行了综述。然后,论文提出了一种全新的解决方案,包括算法、模型或方法。在整个研究过程中,论文使用了合适的实验设计和数据集,并进行了充分的实验验证。最后,论文对解决方案的性能进行了全面的评估和分析,并提出了进一步的研究方向。 源码内容描述:该源码实现了论文中提出的新的解决方案。源码中包含了算法、模型或方法的具体实现代码,以及相关的数据预处理、实验设计和性能评估代码。源码中还包括了合适的注释和文档,以方便其他研究者理解和使用。源码的实现应该具有可读性、可维护性和高效性,并能够复现论文中的实验结果。此外,源码还应该尽可能具有通用性,以便在其他类似问题上进行进一步的应用和扩展。

    基于springboot网上书店源码数据库文档.zip

    基于springboot网上书店源码数据库文档.zip

    numpy-2.1.3-cp311-cp311-linux_armv7l.whl

    numpy-2.1.3-cp311-cp311-linux_armv7l.whl

    基于springboot的校园消费点评系统源码数据库文档.zip

    基于springboot的校园消费点评系统源码数据库文档.zip

    ta_lib-0.5.1-cp37-cp37m-win32.whl

    ta_lib-0.5.1-cp37-cp37m-win32.whl

    java高校学生信息管理系统源码数据库 MySQL源码类型 WebForm

    Java高校学生信息管理系统源码 一、源码介绍 高校学生信息管理系统设计主要应用JAVA语言编程和mysql数据库连接等相关知识,需要熟练掌握Struts2、Spring、Hibernate基础 二、主要功能 高校学生信息管理系统设计主要应用JAVA语言编程和mysql数据库连接等相关知识,需要熟练掌握Struts2、Spring、Hibernate基础,将所 学知识在生活中灵活运用,高校学生信息管理系统的主要设计功能如下: (1)学生信息管理模块:包括所有学生信息的查询(用分页列表显示)、查看某个学生的详细信息、删除某学生信息、修改某学生信息以及学生信息的录入等子功能 (2)学生成绩管理模块:包括成绩信息录入、学生成绩查询、查看某个学生的成绩表以及删除学生

    opencv_python-4.4.0.42-cp39-cp39-linux_armv7l.whl

    opencv_python-4.4.0.42-cp39-cp39-linux_armv7l.whl

    基于springboot扶贫助农系统源码数据库文档.zip

    基于springboot扶贫助农系统源码数据库文档.zip

    springboot235基于SpringBoot的房屋交易平台的设计与实现.zip

    论文描述:该论文研究了某一特定领域的问题,并提出了新的解决方案。论文首先对问题进行了详细的分析和理解,并对已有的研究成果进行了综述。然后,论文提出了一种全新的解决方案,包括算法、模型或方法。在整个研究过程中,论文使用了合适的实验设计和数据集,并进行了充分的实验验证。最后,论文对解决方案的性能进行了全面的评估和分析,并提出了进一步的研究方向。 源码内容描述:该源码实现了论文中提出的新的解决方案。源码中包含了算法、模型或方法的具体实现代码,以及相关的数据预处理、实验设计和性能评估代码。源码中还包括了合适的注释和文档,以方便其他研究者理解和使用。源码的实现应该具有可读性、可维护性和高效性,并能够复现论文中的实验结果。此外,源码还应该尽可能具有通用性,以便在其他类似问题上进行进一步的应用和扩展。

Global site tag (gtag.js) - Google Analytics