【问题标题】:Shifting a BitArray移动位数组
【发布时间】:2014-10-25 03:34:27
【问题描述】:

我目前正在尝试移动 BitArray,同时保持其长度。由于没有内置方法,我正在努力构建一个但无法使其工作,不幸的是。

我的初始 BitArray 代码将 BitArray 的长度设置为 421。

var b = new BitArray(length: 421);

然后,我正在分配一些值进行测试。例如: b.设置(0,真); b.Set(1, true);

但是,我不知道如何移动位数组。 尝试: - 我认为我可以将其转换为 long 而不是进行位操作。但是,long 与我的确切 BitArray 长度不匹配,这会导致稍后在我对两个 BitArray 应用按位运算时出错(我的全部要求是 (array1 |= array2 >> 20)。 - 我尝试将 BitArray 转换为 byte[],进行操作并返回它(参见 Bit shifting N bits):

    public static byte[] ToBytesArray(this BitArray array, int startIndex, int count)
    {
        // Get the size of bytes needed to store all bytes
        int bytesize = count / ByteLength;

        // Any bit left over another byte is necessary
        if (count % ByteLength > 0)
        {
            bytesize++;
        }

        // For the result
        byte[] bytes = new byte[bytesize];

        // Must init to good value, all zero bit byte has value zero
        // Lowest significant bit has a place value of 1, each position to
        // to the left doubles the value
        byte value = 0;
        byte significance = 1;

        int bytepos = 0;
        int bitpos = startIndex;

        while (bitpos - startIndex < count)
        {
            // If the bit is set add its value to the byte
            if (array[bitpos])
                value += significance;

            bitpos++;

            if (bitpos % ByteLength == 0)
            {
                // A full byte has been processed, store it
                // increase output buffer index and reset work values
                bytes[bytepos] = value;
                bytepos++;
                value = 0;
                significance = 1;
            }
            else
            {
                // Another bit processed, next has doubled value
                significance *= 2;
            }
        }

        return bytes;
    }

    public static BitArray ShiftLeft(this BitArray array, int bitcount)
    {
        byte[] value = array.ToBytesArray();
        byte[] temp = new byte[value.Length];
        if (bitcount >= 8)
        {
            Array.Copy(value, bitcount / 8, temp, 0, temp.Length - (bitcount / 8));
        }
        else
        {
            Array.Copy(value, temp, temp.Length);
        }

        if (bitcount % 8 != 0)
        {
            for (int i = 0; i < temp.Length; i++)
            {
                temp[i] <<= bitcount % 8;
                if (i < temp.Length - 1)
                {
                    temp[i] |= (byte)(temp[i + 1] >> 8 - bitcount % 8);
                }
            }
        }

        return new BitArray(temp);
    }

但是,byte 的长度是 8,也不太适合我的长度。结果是 416 或 424(另一个字节)而不是 421。

  • 最后,我尝试了“原始”的方式:

        for (int i = 0; i < bitcount; i++)
        {
            var lastValue = array[0];
            for (var j = 0; j < array.Length - 1; j++)
            {
                array[j] = array[j + 1];
            }
    
            array[array.Length - 1] = lastValue;
        }
    

我还检查了 SO(例如 BitArray - Shift bits),但对我没有任何帮助。

任何帮助将不胜感激!

【问题讨论】:

  • 不是 100% 确定问题是什么以及这些链接如何没有回答它。你想要一个可以左右移动的数组(我假设在移动时添加 0)或循环数组(所以如果你向右移动,并且边缘有一个 1,它会移动到开头?)跨度>
  • 您是否在算术(最左边的位符号填充)和逻辑(最左边的位零填充)位移之间遇到混淆?根据 MSDN,左操作数(有符号或无符号整数类型)的性质决定了在 C# 规范下出现的情况。请注意,C++ 规范将处方保留为依赖于实现。 msdn.microsoft.com/en-us/library/xt18et0d.aspx
  • @Noctis - 我想要一个非循环操作。我正在使用 std::bitset 将 C++ 中的实现转换为 .NET。我认为这不是我的问题,因为标准原始类型(例如 int 或 unit)无法帮助我,因为我需要自定义位数组长度。我的目标是使用 BitArray 将 C++ std::bitset operator>> 和

标签: c# bit-shift bitarray


【解决方案1】:
public static bool[] Left_shiftBitArray(bool[] Array, int count)
        {
            Array = BitArray_LRotat(Array, count);
            for (int i=Array.GetLength(0)-1; i>=(Array.GetLength(0)-count); i--)
            {
                Array[i] = false;
            }

            return Array;
        }

        public static bool[] BitArray_LRotat(bool[] input, int x)
        {
            //bool [] temp= new bool[input.Length];
            bool[] final = new bool[input.Length];
            for (int i = input.Length; i > x; i--)
            {
                final[i - x - 1] = input[i - 1];
            }
            for (int i = x; i > 0; i--)
            {
                final[(input.Length) - i] = input[x - i];
            }
            return final;
        }

【讨论】:

    【解决方案2】:

    仍然不能 100% 确定是什么问题。这是一个简单的实现:

    void Main()
    {
        // Creates and initializes a BitArrays of size 7 (you have 421).
        bool[] myBools = new bool[7] { true,false,false,true,true,false,true };
        BitArray myBA1 = new BitArray(myBools );
    
        PrintBitArray(myBA1);              // 1001101
        PrintBitArray(ShiftRight(myBA1));  // 0100110
        PrintBitArray(ShiftLeft (myBA1));  // 0011010
    }
    
    BitArray ShiftRight(BitArray aSource) {
        bool[] new_arr  = new bool[( aSource.Count)];
        for (int i = 0; i < aSource.Count -1; i++)
            new_arr[i+1] = aSource[i];
    
        return new BitArray(new_arr);
    }   
    
    BitArray ShiftLeft(BitArray aSource) {
        bool[] new_arr  = new bool[( aSource.Count)];
        for (int i = 0; i < aSource.Count -1; i++)
            new_arr[i] = aSource[i+1];
    
        return new BitArray(new_arr);
    }
    
    string PrintBitArray(BitArray aSource) {
        StringBuilder sb  = new StringBuilder();
        foreach (var bit in aSource)
        {
            sb.Append( (bool)bit ? 1 : 0 );
        }
        return sb.ToString();
    }
    

    注意位是如何在循环中复制的,第三个 PrintBitArray 是在原始输入上完成的,而不是在第二个输入上完成的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-06
      • 2017-03-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多