【问题标题】:Preserving bit-order in BitArray when using MSB-first bit order使用 MSB-first 位顺序时保留 BitArray 中的位顺序
【发布时间】:2014-05-18 01:23:17
【问题描述】:

我需要将整数值序列化为字节数组Byte[],这样输入值的最高有效位也是目标数组中的最高有效位。它还需要允许存储位置的每位(而不是每字节)偏移量。

这是一个简单的例子,我正在编写一个与字节边界对齐的整数(MSByte-first,MSbit-first-order):

Byte[] buffer = new Byte[99];
Encode( buffer, 0, 0x1234 ); // Encode the value 0x1234 inside buffer at bit-offset 0.
Assert.AreEqual( buffer[0], 0x12 ); // The integer value is stored most-significant-byte first
Assert.AreEqual( buffer[1], 0x34 );

这里有类似的东西,但偏移了 1 位

Array.Initialize( buffer ); // Reset the buffer's bytes to 0.
Encode( buffer, 1, 0x0102 ); // Encode 0x0102 at bit-offset 1
// In binary 0x0102 is 00000001 00000010, but the final buffer will be this: 00000000 10000001 00000000
Assert.AreEqual( buffer[0], 0x00 ); // The first byte will be zero
Assert.AreEqual( buffer[1], 0x81 ); // 10000001 == 0x81
Assert.AreEqual( buffer[2], 0x00 );

我目前正在使用BitArray 实例,但是BitArray 反转字节内的位顺序,即。 bitArray[0] 是其缓冲区中第一个字节的最低有效位,而我需要它是缓冲区中第一个字节的最高有效位。

【问题讨论】:

    标签: .net endianness bitarray


    【解决方案1】:

    我可以解决这个问题的唯一方法是实现我自己的 BitArray 类,该类保留了最高到最低有效位顺序。

    我觉得我被骗了,因为在内部我使用Boolean[] 来存储位值,而不是像BitArray 那样使用Int32[],但我对我得到的性能很满意。

    这是我使用的逻辑:

    /// <summary>A bit-array that works with bytes in big-endian order (that is, this[0] == big-endian-bit of the first byte).</summary>
    public class BitArray2 : IEnumerable<Boolean> {
    
        private Boolean[] _bits;
    
        public BitArray2(Int32 byteCount, Boolean initialValue) {
    
            this._bits = new Boolean[ byteCount * 8 ];
            for(int i=0;i<this._bits.Length;i++) {
                this._bits[i] = initialValue;
            }
        }
    
        public BitArray2(Byte[] copyFrom) {
    
            this._bits = new Boolean[ copyFrom.Length * 8 ];
    
            for(int i=0;i<copyFrom.Length;i++) {
                Byte b = copyFrom[i];
    
                this._bits[ (i*8) + 0 ] = (b & 0x80) == 0x80;
                this._bits[ (i*8) + 1 ] = (b & 0x40) == 0x40;
                this._bits[ (i*8) + 2 ] = (b & 0x20) == 0x20;
                this._bits[ (i*8) + 3 ] = (b & 0x10) == 0x10;
                this._bits[ (i*8) + 4 ] = (b & 0x08) == 0x08;
                this._bits[ (i*8) + 5 ] = (b & 0x04) == 0x04;
                this._bits[ (i*8) + 6 ] = (b & 0x02) == 0x02;
                this._bits[ (i*8) + 7 ] = (b & 0x01) == 0x01;
            }
        }
    
        public Boolean this[Int32 bitIndex] {
            get { return this._bits[bitIndex]; }
            set { this._bits[bitIndex] = value; }
        }
    
        public void CopyTo(Byte[] buffer) {
    
            for(int i=0;i<_bits.Length;i+=8) {
    
                Int32 destIndex = i / 8;
    
                Byte b = 0;
                if( this._bits[ i + 0 ] ) b |= 0x80;
                if( this._bits[ i + 1 ] ) b |= 0x40;
                if( this._bits[ i + 2 ] ) b |= 0x20;
                if( this._bits[ i + 3 ] ) b |= 0x10;
                if( this._bits[ i + 4 ] ) b |= 0x08;
                if( this._bits[ i + 5 ] ) b |= 0x04;
                if( this._bits[ i + 6 ] ) b |= 0x02;
                if( this._bits[ i + 7 ] ) b |= 0x01;
    
                buffer[ destIndex ] = b;
            }
        }
    
        public IEnumerator<Boolean> GetEnumerator() {
            // See http://stackoverflow.com/questions/1272673/obtain-generic-enumerator-from-an-array
            return ((IEnumerable<Boolean>)this._bits).GetEnumerator();
        }
        IEnumerator IEnumerable.GetEnumerator() {
            return this.GetEnumerator();
        }
    }
    

    【讨论】:

    • 我刚刚发现了 BitArray,很沮丧地发现这是一个问题。我很想找到能解释为什么会这样的人。
    猜你喜欢
    • 1970-01-01
    • 2015-06-09
    • 1970-01-01
    • 1970-01-01
    • 2022-08-08
    • 1970-01-01
    • 1970-01-01
    • 2017-06-18
    • 2012-05-31
    相关资源
    最近更新 更多