Aqeel Abbas
Aqeel Abbas

Reputation: 169

Is there any way to reverse the order of bits in matlab

What I am trying is getting binary value of a number e.g

de2bi(234)

Which results me in having this answer :

 0     1     0     1     0     1     1     1

now what I want is that is its reverse order without changing its values like this :

11101010

i have tried bitrevorder() function but i am not having my desired answer. any help and suggestions will be appreciated.

Upvotes: 3

Views: 6129

Answers (6)

Shai
Shai

Reputation: 114866

why not use bitget?

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

ans =

 1     1     1     0     1     0     1     0

Upvotes: 0

Tom Carpenter
Tom Carpenter

Reputation: 571

While this is an old question, I needed to do the same thing for a CRC checksum and feel I should share the results.

In my case I need to reverse 16bit numbers, so, I've tried three methods:

1) Using fliplr() to reverse as per the suggestions:

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

To test out the speed I decided to try and checksum 12MB of data. Using the above code in my CRC, it took 2000 seconds to complete! Most of this time was performing the bit reversal.

2) I then devised a more optimal solution, though not a one line code it is optimised for speed:

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

Using the same CRC code, but with this used instead of (1), it took a little over 500 seconds to complete, so already it makes the CRC calculations four times faster!

3) That is still too much time for my liking, so instead I moved everything to a mex function. This allows the use of code from the bit twiddling examples that are floating around for optimum performance. I moved the whole CRC code to the mex function and used the following two other functions to do the bit reversal.

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)));
}

Just for comparison, it took just 0.14 seconds to compute the CRC for the same 12MB data chunk (and there is no mistake in the calculation, the CRC checksums for all three methods match what is expected).


So basically, if you have to do this a lot of times (e.g. for CRC) I seriously suggest you write a mex function for doing the reversal. For such a simple operation, native MATLAB code is embarrassing slow.

Upvotes: 1

Luis Mendo
Luis Mendo

Reputation: 112749

You just need to use the 'left-msb' option in de2bi:

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

Upvotes: 2

zenpoy
zenpoy

Reputation: 20136

You can use a more simple command called dec2bin which produces the desired result:

>> dec2bin(234)

ans =

11101010

Here is the docs: http://www.mathworks.com/help/matlab/ref/dec2bin.html?refresh=true

Upvotes: 1

zenpoy
zenpoy

Reputation: 20136

Try using the flag 'left-msb' (according to the documentation in http://www.mathworks.com/help/comm/ref/de2bi.html)

The commands below show how to convert a decimal integer to base three without specifying the number of columns in the output matrix. They also show how to place the most significant digit on the left instead of on the right.

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

Upvotes: 3

lakshmen
lakshmen

Reputation: 29084

Example:

>>de2bi(234)

ans =  0     1     0     1     0     1     1     1

>> fliplr(ans)

ans =

     1     1     1     0     1     0     1     0

Use the function fliplr. It can be used to reverse the order of array.

Upvotes: 4

Related Questions