Есть ли встроенная функция для изменения порядка следования битов

Я придумал несколько ручных способов сделать это, но мне все время интересно, есть ли что-то встроенное в .NET, которое Является ли это.

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

Например: 1001 1101 = 9D превратится в 1011 1001 = B9

Один из способов сделать это - использовать побитовые операции, если следовать этому псевдо код:

for (i = 0; i<8; i++)
{
  Y>>1
  x= byte & 1
  byte >>1
  y = x|y;
}

Интересно, есть ли где-нибудь функция, которая позволит мне сделать все это в одной строчке . Кроме того, вы знаете термин для такой операции, я уверен, что он есть, но сейчас я не могу его вспомнить.

Спасибо

30
задан Bogdan Stăncescu 13 June 2018 в 14:14
поделиться

4 ответа

Пожалуйста, ознакомьтесь с этими подробными инструментами для перестановки битов, а именно, вы хотите «Обратить биты в байте с помощью 3 операций (64-битное умножение и деление по модулю)»

int lVal = 0x9D;
int lNewVal = (int)((((ulong)lVal * 0x0202020202UL) & 0x010884422010UL) % 1023);
System.Diagnostics.Debug.WriteLine(string.Format("{0:X2}", lNewVal));

Когда вы запустите это, вы обнаружите, что значение меняется на 0xB9.

1
ответ дан 27 November 2019 в 23:32
поделиться

Вы можете найти алгоритмы преобразования битов в fxtbook. В главе 1.14 приведены следующие алгоритмы перестановки битов:

    static uint bitSwap1(uint x) {
        uint m = 0x55555555;
        return ((x & m) << 1) | ((x & (~m)) >> 1);
    }
    static uint bitSwap2(uint x) {
        uint m = 0x33333333;
        return ((x & m) << 2) | ((x & (~m)) >> 2);
    }
    static uint bitSwap4(uint x) {
        uint m = 0x0f0f0f0f;
        return ((x & m) << 4) | ((x & (~m)) >> 4);
    }

Что делает ваше значение байта инвертированным:

    public static byte swapBits(byte value) {
        return (byte)(bitSwap4(bitSwap2(bitSwap1(value))));
    }

Компилятор x86 JIT не очень хорошо оптимизирует этот код. Если скорость имеет значение, вы можете использовать ее для инициализации byte[], чтобы вместо этого сделать быстрый поиск.

3
ответ дан 27 November 2019 в 23:32
поделиться

По ссылке @Chads

byte b; 
b = 0x9D;
b = (byte)((b * 0x0202020202 & 0x010884422010) % 1023); 

Редактировать: Забыл состав

2
ответ дан 27 November 2019 в 23:32
поделиться

Нет, в BCL для этого ничего нет.

Но если вам нужно что-то быстрое:

  • Поскольку имеется только 8 бит, стоит развернуть цикл (используйте 4 оператора вместо цикла for).

  • Для еще более быстрого решения создайте таблицу поиска из 256 записей.

И вы, конечно, можете обернуть оба метода в функцию, чтобы их использование занимало только 1 оператор.

Я нашел страницу по этой проблеме.

14
ответ дан 27 November 2019 в 23:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: