2009-02-18 13 views
27

У меня есть BitArray с длиной 8, и мне нужна функция для преобразования его в byte. Как это сделать?Конвертировать из BitArray в байт

В частности, мне нужно правильно функцию ConvertToByte:

BitArray bit = new BitArray(new bool[] 
{ 
    false, false, false, false, 
    false, false, false, true 
}); 

//How to write ConvertToByte 
byte myByte = ConvertToByte(bit); 
var recoveredBit = new BitArray(new[] { myByte }); 
Assert.AreEqual(bit, recoveredBit); 

ответ

40

Это должно работать:

byte ConvertToByte(BitArray bits) 
{ 
    if (bits.Count != 8) 
    { 
     throw new ArgumentException("bits"); 
    } 
    byte[] bytes = new byte[1]; 
    bits.CopyTo(bytes, 0); 
    return bytes[0]; 
} 
+6

Mind: он вычисляет биты в обратном порядке, например. BitArray из примера преобразуется в 128, а не 1! – tehvan

+0

Почему это происходит в обратном порядке? –

+1

@kornelijepetak: Именно так работает BitArray с точки зрения способа копирования значений. –

4

Это должно сделать трюк. Однако предыдущий ответ, скорее всего, лучший вариант.

public byte ConvertToByte(BitArray bits) 
    { 
     if (bits.Count > 8) 
      throw new ArgumentException("ConvertToByte can only work with a BitArray containing a maximum of 8 values"); 

     byte result = 0; 

     for (byte i = 0; i < bits.Count; i++) 
     { 
      if (bits[i]) 
       result |= (byte)(1 << i); 
     } 

     return result; 
    } 

В примере, в котором вы отправили полученный байт, будет 0x80. Другими словами, первое значение в BitArray соответствует первому биту в возвращаемом байте.

5

бедняка решение:

protected byte ConvertToByte(BitArray bits) 
{ 
    if (bits.Count != 8) 
    { 
     throw new ArgumentException("illegal number of bits"); 
    } 

    byte b = 0; 
    if (bits.Get(7)) b++; 
    if (bits.Get(6)) b += 2; 
    if (bits.Get(5)) b += 4; 
    if (bits.Get(4)) b += 8; 
    if (bits.Get(3)) b += 16; 
    if (bits.Get(2)) b += 32; 
    if (bits.Get(1)) b += 64; 
    if (bits.Get(0)) b += 128; 
    return b; 
} 
27

Немного поздно пост, но это работает для меня:

public static byte[] BitArrayToByteArray(BitArray bits) 
{ 
    byte[] ret = new byte[(bits.Length - 1)/8 + 1]; 
    bits.CopyTo(ret, 0); 
    return ret; 
} 

Работает с:

string text = "Test"; 
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(text); 
BitArray bits = new BitArray(bytes); 
bytes[] bytesBack = BitArrayToByteArray(bits); 
string textBack = System.Text.Encoding.ASCII.GetString(bytesBack); 
// bytes == bytesBack 
// text = textBack 

.

+11

Вместо« bits.Length/8 »вы должны использовать« (bits.Length - 1)/8 + 1 », в противном случае, если BitArray имеет длину 7, ваш массив байтов будет быть пустым. Часть «- 1» гарантирует, что кратное 8 не вернется плюс один. Благодаря http://stackoverflow.com/questions/17944/how-to-round-up-the-result-of-integer-division/503201#503201 – iano

+1

Хорошая точка. Math.Max ​​(1, bits.Length/8) также будет работать, я думаю (немного читаем). Я всегда работаю с 8-битными байтами, поэтому я не рассматривал условие underflow. –

+1

@TeddHansen Что относительно 15? –

2

Это должно быть конечным. Работает с любой длиной массива.

private List<byte> BoolList2ByteList(List<bool> values) 
    { 

     List<byte> ret = new List<byte>(); 
     int count = 0; 
     byte currentByte = 0; 

     foreach (bool b in values) 
     { 

      if (b) currentByte |= (byte)(1 << count); 
      count++; 
      if (count == 7) { ret.Add(currentByte); currentByte = 0; count = 0; };    

     } 

     if (count < 7) ret.Add(currentByte); 

     return ret; 

    } 
+0

Я считаю, что здесь есть ошибка - поскольку 'count ++;' уже запущен, следующая строка должна быть 'if (count == 8) {...}' –

0
byte GetByte(BitArray input) 
{ 
    int len = input.Length; 
    if (len > 8) 
    len = 8; 
    int output = 0; 
    for (int i = 0; i < len; i++) 
    if (input.Get(i)) 
     output += (1 << (len - 1 - i)); //this part depends on your system (Big/Little) 
     //output += (1 << i); //depends on system 
    return (byte)output; 
} 

Ура!

0

Маленький преобразователь матрицы байтов: первый бит (с индексом «0») в битаррите , предполагаемый как наименее значащий бит (самый правый бит в бит-октете), который интерпретируется как «ноль» или «один» как двоичный ,

public static class BitArrayExtender { 

    public static byte[] ToByteArray(this BitArray bits) { 

     const int BYTE = 8; 
     int length = (bits.Count/BYTE) + ((bits.Count % BYTE == 0) ? 0 : 1); 
     var bytes = new byte[ length ]; 

     for (int i = 0; i < bits.Length; i++) { 

      int bitIndex = i % BYTE; 
      int byteIndex = i/BYTE; 

      int mask = (bits[ i ] ? 1 : 0) << bitIndex; 
      bytes[ byteIndex ] |= (byte)mask; 

     }//for 

     return bytes; 

    }//ToByteArray 

}//class 
1

В дополнение к @JonSkeet ответ вы можете использовать универсальный метод, как удар:

public static byte ToByte(this BitArray bits) 
     { 
      if (bits.Count != 8) 
      { 
       throw new ArgumentException("bits"); 
      } 
      byte[] bytes = new byte[1]; 
      bits.CopyTo(bytes, 0); 
      return bytes[0]; 
     } 

И использовать как:

BitArray foo = new BitArray(new bool[] 
{ 
    false, false, false, false,false, false, false, true 
}); 

foo.ToByte(); 
0

К сожалению, класс BitArray частично реализован в .NET Основной класс (UWP). Например, класс BitArray не может вызвать методы CopyTo() и Count(). Я написал это расширение, чтобы заполнить пробел:

public static IEnumerable<Byte> ToBytes(this BitArray bits, bool MSB = false) 
    { 
     int bitCount = 7; 
     int outByte = 0; 

     foreach (bool bitValue in bits) 
     { 
      if (bitValue) 
       outByte |= MSB ? 1 << bitCount : 1 << (7 - bitCount); 
      if (bitCount == 0) 
      { 
       yield return (byte) outByte; 
       bitCount = 8; 
       outByte = 0; 
      } 
      bitCount--; 
     } 
     // Last partially decoded byte 
     if (bitCount < 7) 
      yield return (byte) outByte; 
    } 
} 

Метод декодирует BitArray в массив байтов, используя логику LSB (Less младший байт). Это та же логика, которая используется классом BitArray. Вызов метода с параметром MSB, установленным в true, приведет к декодированию байтов в MSB. В этом случае помните, что вам, возможно, также придется отменить окончательную выходную байтовую коллекцию.

 Смежные вопросы

  • Нет связанных вопросов^_^