2009-08-14 8 views
1

Привет быстрый вопрос относительно немного о переключениибитов сдвига N битов

У меня есть значение в HEX = новый байт [] {0x56, 0xAF};

который 0101 0110 1010 1111

я хочу первых п битов, например, 12

затем переложить оставшиеся 4 (16-12), чтобы получить 0000 0101 0110 1010 (1386 декабрь)

Я наклоняю голову вокруг него и делаю ее масштабируемой для n бит.

Спасибо!

ответ

1

вы хотите что-то вроде ...

var HEX = new byte[] {0x56, 0xAF}; 
var bits = new BitArray(HEX); 
int bitstoShiftRight = 4; 
for (int i = 0; i < bits.Length; i++) 
{ 
    bits[i] = i < (bits.Length - bitstoShiftRight) ? bits[i + bitstoShiftRight] : false; 
} 
bits.CopyTo(HEX, 0); 
+0

спасибо, мне понравился этот подход, проблема заключается в том, что конструктор BitArray изменил порядок Endian на каждый байт, значение которого было ошибочным после завершения метода, id должен отменить порядок битов на каждый байт до создания экземпляра битового массива с помощью byes – Bobby

0

Если у вас есть общие K бит, и вы хотите, чтобы «первый» (как в наиболее значимых) п бит, вы можете просто щелкнуть правой сдвиг kn раз. Последние k-n бит будут удалены, как бы «падающие» с конца, и первое n будет перенесено на наименее значимую сторону.

+0

Спасибо за ответ, проблема в том, что я не могу на самом деле бить сдвиг массива байтов, мне нужно делать их индивидуально, а затем я теряю переполнение, поэтому моя альтернатива заключалась в том, чтобы отбросить все 16 бит до int 16 и shift в этот момент нет того, чего я хотел, так как теперь мне нужно знать длину и применить к этому типу, а затем сдвинуть – Bobby

0

Ответ с использованием C-подобных обозначений, предполагая bits_in_byte это число битов в байте определяется в другом месте:

int remove_bits_count= HEX.count*bits_in_byte - bits_to_keep; 
int remove_bits_in_byte_count= remove_bits_count % bits_in_byte; 

if (remove_bits_count > 0) 
{ 
    for (int iteration= 0; iteration<min(HEX.count, (bits_to_keep + bits_in_byte - 1)/bits_in_byte); ++iteration) 
    { 
     int write_index= HEX.count - iteration - 1; 
     int read_index_lo= write_index - remove_bits_count/bits_in_byte; 

     if (read_index_lo>=0) 
     { 
      int read_index_hi= read_index_lo - (remove_bits_count + bits_in_byte - 1)/bits_in_byte; 

      HEX[write_index]= 
       (HEX[read_index_lo] >> remove_bits_in_byte_count) | 
       (HEX[read_index_hi] << (bits_in_byte - remove_bits_in_byte_count)); 
     } 
     else 
     { 
      HEX[write_index]= 0; 
     } 
    } 
} 

Предполагая, что вы перезаписать исходный массив, вы в основном принимать каждый байт вы пишете и выяснить, байты, из которых он получит свои сдвинутые биты. Вы переходите от конца массива к фронту, чтобы не перезаписывать данные, которые вам нужно прочитать.

6

Некоторое время назад я закодированы эти две функции, первая сдвигает байт [] определенное количество битов слева, второй делает то же самое направо:

сдвиг влево:

public byte[] ShiftLeft(byte[] value, int bitcount) 
{ 
    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 temp; 
} 

сдвига вправо:

public byte[] ShiftRight(byte[] value, int bitcount) 
{ 
    byte[] temp = new byte[value.Length]; 
    if (bitcount >= 8) 
    { 
     Array.Copy(value, 0, temp, bitcount/8, temp.Length - (bitcount/8)); 
    } 
    else 
    { 
     Array.Copy(value, temp, temp.Length); 
    } 
    if (bitcount % 8 != 0) 
    { 
     for (int i = temp.Length - 1; i >= 0; i--) 
     { 
      temp[i] >>= bitcount % 8; 
      if (i > 0) 
      { 
       temp[i] |= (byte)(temp[i - 1] << 8 - bitcount % 8); 
      } 
     } 
    } 
    return temp; 
} 

Если вам нужна дополнительная объяснение, пожалуйста, комментарий по этому вопросу, я затем редактировать свой пост для уточнения ...

+0

Неплохая идея скопировать 8-битное переполнение переполнения заранее. У моей реализации было 2 встроенных for-s для обработки переполнения, прежде чем я увидел эту идею. – vellotis

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