Есть ли способ изменить порядок бит в Matlab

То, что я пытаюсь получить двоичное значение числа, например

de2bi(234)

В результате я получаю этот ответ:

 0     1     0     1     0     1     1     1

Теперь я хочу, чтобы это был обратный порядок без изменения значений:

11101010

я пытался bitrevorder() функция, но у меня нет желаемого ответа. Любая помощь и предложения будут оценены.

6 ответов

Решение

Пример:

>>de2bi(234)

ans =  0     1     0     1     0     1     1     1

>> fliplr(ans)

ans =

     1     1     1     0     1     0     1     0

Используйте функцию fliplr. Это может быть использовано для изменения порядка массива.

Попробуйте использовать флаг 'left-msb' (согласно документации на http://www.mathworks.com/help/comm/ref/de2bi.html)

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

t = de2bi(12,[],3) % Convert 12 to base 3.

tleft = de2bi(12,[],3,'left-msb') % Significant digit on left
The output is

t =

     0     1     1


tleft =

     1     1     0

Вам просто нужно использовать 'left-msb' вариант в de2bi:

>>de2bi(234, 'left-msb')
ans =
     1     1     1     0     1     0     1     0

Вы можете использовать более простую команду под названием dec2bin который дает желаемый результат:

>> dec2bin(234)

ans =

11101010

Вот документы: http://www.mathworks.com/help/matlab/ref/dec2bin.html?refresh=true

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

В моем случае мне нужно поменять 16-битные числа, поэтому я попробовал три метода:

1) Использование fliplr() отменить согласно предложениям:

 uint16(bin2dec(fliplr(dec2bin(data,16))))

Чтобы проверить скорость, я решил попробовать контрольную сумму 12 МБ данных. Используя приведенный выше код в моем CRC, потребовалось 2000 секунд! Большую часть этого времени выполнял разворот битов.

2) Затем я разработал более оптимальное решение, но не для однострочного кода, оно оптимизировано для скорости:

reverse = uint16(0);
for i=1:16
    reverse = bitor(bitshift(reverse,1), uint16(bitand(forward,1)));
    forward = bitshift(forward,-1);
end

Используя тот же код CRC, но с использованием этого вместо (1), для его завершения потребовалось чуть более 500 секунд, так что уже он делает вычисления CRC в четыре раза быстрее!

3) Это все еще слишком много времени для моего вкуса, поэтому вместо этого я переместил все в функцию mex. Это позволяет использовать код из примеров битовых поворотов, которые используются для оптимальной производительности. Я переместил весь код CRC в функцию mex и использовал следующие две другие функции для инвертирования битов.

unsigned char crcBitReverse8(unsigned char forward) {
    return (unsigned char)(((forward * 0x0802LU & 0x22110LU) | (forward * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16); 
}
unsigned short crcBitReverse16(unsigned short forward) {
    unsigned char inByte0 = (forward & 0xFF);
    unsigned char inByte1 = (forward & 0xFF00) >> 8;
    return (unsigned short )((crcBitReverse8(inByte0) << 8) | (crcBitReverse8(inByte1)));
}

Просто для сравнения: для расчета CRC для того же блока данных размером 12 МБ потребовалось всего 0,14 секунды (и в вычислениях нет ошибок, контрольные суммы CRC для всех трех методов соответствуют ожидаемым).


В общем, если вам приходится делать это много раз (например, для CRC), я серьезно советую вам написать мекс-функцию для выполнения реверсирования. Для такой простой операции нативный код MATLAB очень медленный.

Почему бы не использовать bitget?

>> bitget( 234, 8:-1:1 )

ans =

 1     1     1     0     1     0     1     0
Другие вопросы по тегам