【问题标题】:Defining a bit[] array in C#在 C# 中定义 bit[] 数组
【发布时间】:2014-04-10 19:20:40
【问题描述】:

目前我正在研究质数计算器/检查器的解决方案。该算法已经在工作并且非常高效(前 9012330 个素数为 0,359 秒)。这是声明所有内容的上部区域的一部分:

const uint anz = 50000000;


uint a = 3, b = 4, c = 3, d = 13, e = 12, f = 13, g = 28, h = 32;
bool[,] prim = new bool[8, anz / 10];
uint max = 3 * (uint)(anz / (Math.Log(anz) - 1.08366));
uint[] p = new uint[max];

现在我想进入下一个级别并使用 ulong 代替 uint 来覆盖更大的区域(您已经可以看到),我在这里遇到了我的问题:bool-array。 就像每个人都应该知道的那样,bool 的长度只有一个字节,这在创建数组时会占用大量内存......所以我正在寻找一种更资源友好的方式来做到这一点。 我的第一个想法是位数组-> 不是字节!

【问题讨论】:

    标签: c# primes bit bitarray


    【解决方案1】:

    您可以使用 BitArray 集合: http://msdn.microsoft.com/en-us/library/system.collections.bitarray(v=vs.110).aspx

    MSDN 说明: 管理一个紧凑的位值数组,表示为布尔值,其中 true 表示该位打开 (1),false 表示该位关闭 (0)。

    【讨论】:

      【解决方案2】:

      您可以(并且应该)使用经过良好测试和知名的库。

      但如果你想学习一些东西(看起来确实如此),你可以自己做。

      您可能想要使用自定义位数组的另一个原因是使用硬盘驱动器来存储数组,这在计算素数时会派上用场。为此,您需要进一步拆分addr,例如最低 3 位用于掩码,接下来的 28 位用于 256MB 内存存储,然后从那里开始 - 缓冲区文件的文件名。

      然而自定义位数组的另一个原因是在专门搜索素数时压缩内存使用。毕竟超过一半的位将是“假的”,因为与它们对应的数字是偶数,所以事实上,如果你甚至不存储偶数位,你既可以加快计算速度,又可以减少内存需求。您可以通过更改 addr 的解释方式来做到这一点。此外,您还可以排除可被 3 整除的数字(每 6 个数字中只有 2 个有可能成为素数),因此与普通位数组相比,内存需求减少了 60%。

      注意使用移位和逻辑运算符使代码更高效。

      byte mask = (byte)(1 << (int)(addr & 7)); 例如可以写成 byte mask = (byte)(1 << (int)(addr % 8));

      addr >> 3可以写成addr / 8

      测试移位/逻辑运算符与除法显示 2.6 秒 vs 4.8 秒,支持 200000000 次操作的移位/逻辑。

      代码如下:

      void Main()
      {
          var barr = new BitArray(10);
          barr[4] = true;
          Console.WriteLine("Is it "+barr[4]);
          Console.WriteLine("Is it Not "+barr[5]);
      }
      
      public class BitArray{ 
          private readonly byte[] _buffer; 
      
          public bool this[long addr]{
            get{
      
               byte mask = (byte)(1 << (int)(addr & 7));  
               byte val = _buffer[(int)(addr >> 3)];
               bool bit = (val & mask) == mask;
               return bit;
            }
            set{
               byte mask = (byte) ((value ? 1:0) << (int)(addr & 7));
               int offs = (int)addr >> 3;
               _buffer[offs] = (byte)(_buffer[offs] | mask);
            }
          }
      
          public BitArray(long size){
             _buffer = new byte[size/8 + 1]; // define a byte buffer sized to hold 8 bools per byte. The spare +1 is to avoid dealing with rounding.
          } 
      }
      

      【讨论】:

        猜你喜欢
        • 2018-07-05
        • 2012-04-08
        • 2013-12-08
        • 1970-01-01
        • 1970-01-01
        • 2022-12-01
        • 2012-07-27
        • 2018-11-01
        • 1970-01-01
        相关资源
        最近更新 更多