Есть ли способ изменить порядок бит в 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