In C/C++ what's the simplest way to reverse the order of bits in a byte?
up vote
86
down vote
favorite
While there are multiple ways to reverse bit order in a byte, I'm curious as to what is the "simplest" for a developer to implement. And by reversing I mean:
1110 -> 0111
0010 -> 0100
This is similar to, but not a duplicate of this PHP question.
This is similar to, but not a duplicate of this C question. This question is asking for the easiest method to implement by a developer. The "Best Algorithm" is concerned with memory and cpu performance.
c++ c bit-manipulation
add a comment |
up vote
86
down vote
favorite
While there are multiple ways to reverse bit order in a byte, I'm curious as to what is the "simplest" for a developer to implement. And by reversing I mean:
1110 -> 0111
0010 -> 0100
This is similar to, but not a duplicate of this PHP question.
This is similar to, but not a duplicate of this C question. This question is asking for the easiest method to implement by a developer. The "Best Algorithm" is concerned with memory and cpu performance.
c++ c bit-manipulation
5
Simple or fast?
– Andreas Rejbrand
Apr 8 '10 at 19:38
Use inline assembly. Better, put the function into a separate translation unit. Have one assembly language module for each target platform. Let build process choose the modules.
– Thomas Matthews
Apr 8 '10 at 19:47
@Andreas Simplest implementation
– nathan
Apr 8 '10 at 20:12
1
then do it in hardware ;)
– Hamish Grubijan
Apr 8 '10 at 21:10
add a comment |
up vote
86
down vote
favorite
up vote
86
down vote
favorite
While there are multiple ways to reverse bit order in a byte, I'm curious as to what is the "simplest" for a developer to implement. And by reversing I mean:
1110 -> 0111
0010 -> 0100
This is similar to, but not a duplicate of this PHP question.
This is similar to, but not a duplicate of this C question. This question is asking for the easiest method to implement by a developer. The "Best Algorithm" is concerned with memory and cpu performance.
c++ c bit-manipulation
While there are multiple ways to reverse bit order in a byte, I'm curious as to what is the "simplest" for a developer to implement. And by reversing I mean:
1110 -> 0111
0010 -> 0100
This is similar to, but not a duplicate of this PHP question.
This is similar to, but not a duplicate of this C question. This question is asking for the easiest method to implement by a developer. The "Best Algorithm" is concerned with memory and cpu performance.
c++ c bit-manipulation
c++ c bit-manipulation
edited May 23 '17 at 12:10
Community♦
11
11
asked Apr 8 '10 at 19:32
nathan
3,68722743
3,68722743
5
Simple or fast?
– Andreas Rejbrand
Apr 8 '10 at 19:38
Use inline assembly. Better, put the function into a separate translation unit. Have one assembly language module for each target platform. Let build process choose the modules.
– Thomas Matthews
Apr 8 '10 at 19:47
@Andreas Simplest implementation
– nathan
Apr 8 '10 at 20:12
1
then do it in hardware ;)
– Hamish Grubijan
Apr 8 '10 at 21:10
add a comment |
5
Simple or fast?
– Andreas Rejbrand
Apr 8 '10 at 19:38
Use inline assembly. Better, put the function into a separate translation unit. Have one assembly language module for each target platform. Let build process choose the modules.
– Thomas Matthews
Apr 8 '10 at 19:47
@Andreas Simplest implementation
– nathan
Apr 8 '10 at 20:12
1
then do it in hardware ;)
– Hamish Grubijan
Apr 8 '10 at 21:10
5
5
Simple or fast?
– Andreas Rejbrand
Apr 8 '10 at 19:38
Simple or fast?
– Andreas Rejbrand
Apr 8 '10 at 19:38
Use inline assembly. Better, put the function into a separate translation unit. Have one assembly language module for each target platform. Let build process choose the modules.
– Thomas Matthews
Apr 8 '10 at 19:47
Use inline assembly. Better, put the function into a separate translation unit. Have one assembly language module for each target platform. Let build process choose the modules.
– Thomas Matthews
Apr 8 '10 at 19:47
@Andreas Simplest implementation
– nathan
Apr 8 '10 at 20:12
@Andreas Simplest implementation
– nathan
Apr 8 '10 at 20:12
1
1
then do it in hardware ;)
– Hamish Grubijan
Apr 8 '10 at 21:10
then do it in hardware ;)
– Hamish Grubijan
Apr 8 '10 at 21:10
add a comment |
27 Answers
27
active
oldest
votes
up vote
87
down vote
accepted
If you are talking about a single byte, a table-lookup is probably the best bet, unless for some reason you don't have 256 bytes available.
9
If we're talking about something that's simple to implement without copying a ready-made solution, creating the lookup table does still require another solution. (Of course one might do it by hand, but that's error-prone and time-consuming…)
– Arkku
Apr 8 '10 at 19:52
7
You can squeeze the array into somewhat fewer than 256 bytes if you ignore palindromes.
– wilhelmtell
Apr 8 '10 at 19:56
7
@wilhelmtell - you'd need a table to know which ones are the palindromes.
– Mark Ransom
Apr 8 '10 at 20:01
6
@wilhelmtell: Well, to write the script one still needs another solution, which was my point – a lookup table is simple to use but not simple to create. (Except by copying a ready-made lookup table, but then one might just as well copy any solution.) For example, if the “simplest” solution is considered one that could be written on paper in an exam or interview, I would not start making a lookup table by hand and making the program to do it would already include a different solution (which would be simpler alone than the one including both it and the table).
– Arkku
Apr 8 '10 at 20:18
4
@Arkku what I meant is write a script which outputs the table of the first 256 bytes and their reverse mapping. Yes, you're back to writing the reverse function, but now in your favourite scripting language, and it can be as nasty as you want -- you're going to throw it away as soon as it's done and you ran it once. Have the script's output as C code, even:unsigned int rtable = {0x800, 0x4000, ...};
. Then throw away the script and forget you ever had it. It's much faster to write than the equivalent C++ code, and it will only ever run once, so you get O(1) runtime in your C++ code.
– wilhelmtell
Apr 8 '10 at 21:32
|
show 11 more comments
up vote
192
down vote
This should work:
unsigned char reverse(unsigned char b) {
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
return b;
}
First the left four bits are swapped with the right four bits. Then all adjacent pairs are swapped and then all adjacent single bits. This results in a reversed order.
23
Reasonably short and quick, but not simple.
– Mark Ransom
Apr 8 '10 at 19:58
1
This approach also cleanly generalizes to perform byte swapping for endianness.
– Boojum
Apr 8 '10 at 20:25
9
+1 for some truly brazen bit twisting!
– JustJeff
Apr 9 '10 at 1:11
1
Not the simplest approach, but I like it +1.
– nathan
Apr 9 '10 at 14:10
4
Yes, it is simple. It's a kind of divide and conquer algorithm. Excellent!
– kiewic
May 11 '10 at 4:25
|
show 3 more comments
up vote
105
down vote
I think a lookup table has to be one of the simplest methods. However, you don't need a full lookup table.
//Index 1==0b0001 => 0b1000
//Index 7==0b0111 => 0b1110
//etc
static unsigned char lookup[16] = {
0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf, };
uint8_t reverse(uint8_t n) {
// Reverse the top and bottom nibble then swap them.
return (lookup[n&0b1111] << 4) | lookup[n>>4];
}
// Detailed breakdown of the math
// + lookup reverse of bottom nibble
// | + grab bottom nibble
// | | + move bottom result into top nibble
// | | | + combine the bottom and top results
// | | | | + lookup reverse of top nibble
// | | | | | + grab top nibble
// V V V V V V
// (lookup[n&0b1111] << 4) | lookup[n>>4]
This fairly simple to code and verify visually.
Ultimately this might even be faster than a full table. The bit arith is cheap and the table easily fits on a cache line.
7
That is an excellent way to reduce the complexity of the table solution. +1
– e.James
Apr 8 '10 at 23:55
1
Nice, but will give you a cache miss.
– Johan Kotlinski
Nov 3 '10 at 17:42
6
@kotlinski: what will cause a cache miss? I think the small table version may be more cache efficient than the large one. On my Core2 a cache line is 64 bytes wide, the full table would span multiple lines, whereas the smaller table easily fits one a single line.
– deft_code
Oct 1 '11 at 14:20
4
@kotlinski: Temporal locality is more important for cache hits or replacement strategies, than address locality
– cfi
Sep 25 '13 at 16:39
4
@Harshdeep: Consider the binary encoded indexes of the table entries. index b0000(0) -> b0000(0x0) boring;b0001(1) -> b1000(0x8)
,b0010(2) -> b0100(0x4)
,b1010(10) -> b0101(0x5)
. See the pattern? It is simple enough that you can calculate it in your head (if you can read binary, otherwise you'll need paper to work it out). As for the leap that reversing an 8 bit integer is the same as reversing 4 bit parts then swapping them; I claim experience and intuition (or magic).
– deft_code
Jan 2 '14 at 20:48
|
show 9 more comments
up vote
38
down vote
See the bit twiddling hacks for many solutions. Copypasting from there is obviously simple to implement. =)
For example (on a 32-bit CPU):
uint8_t b = byte_to_reverse;
b = ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
If by “simple to implement” one means something that can be done without a reference in an exam or job interview, then the safest bet is probably the inefficient copying of bits one by one into another variable in reverse order (already shown in other answers).
1
From your URL: 32 bit CPU: b = ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
– Joshua
Apr 8 '10 at 20:13
1
@Joshua: That's my personal favourite as well. The caveat (as stated on the linked page) is that it needs to be assigned or cast into an uint8_t or there will be garbage in the upper bits.
– Arkku
Apr 8 '10 at 20:20
add a comment |
up vote
34
down vote
Since nobody posted a complete table lookup solution, here is mine:
unsigned char reverse_byte(unsigned char x)
{
static const unsigned char table = {
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
};
return table[x];
}
1
Useful, thanks. Seems that my slower shifting method was limiting performance in an embedded app. Placed table in ROM on a PIC (with addition of rom keyword).
– flend
Apr 23 '12 at 10:02
1
A simpler method: graphics.stanford.edu/~seander/bithacks.html#BitReverseTable
– sleepsort
Jun 14 '14 at 1:30
add a comment |
up vote
24
down vote
template <typename T>
T reverse(T n, size_t b = sizeof(T) * CHAR_BIT)
{
assert(b <= std::numeric_limits<T>::digits);
T rv = 0;
for (size_t i = 0; i < b; ++i, n >>= 1) {
rv = (rv << 1) | (n & 0x01);
}
return rv;
}
EDIT:
Converted it to a template with the optional bitcount
sizeof(T) ....?
– N 1.1
Apr 8 '10 at 19:40
@nvl - fixed. I started building it as a template but decided halfway through to not do so... too many > <
– andand
Apr 8 '10 at 19:42
5
@andand For extra extra pendantry, replacesizeof(T)*CHAR_BIT
bystd::numeric_limits<T>::digits
(almost 4 years of pedantry later).
– Morwenn
Feb 25 '14 at 22:09
1
It should beCHAR_BIT
, notCHAR_BITS
.
– Xunie
Nov 8 '16 at 20:36
1
it should be rv = (rv << 1) | (n & 0x01);
– Vignesh
Mar 13 '17 at 23:20
|
show 3 more comments
up vote
14
down vote
Two lines:
for(i=0;i<8;i++)
reversed |= ((original>>i) & 0b1)<<(7-i);
or in case you have issues with the "0b1" part:
for(i=0;i<8;i++)
reversed |= ((original>>i) & 1)<<(7-i);
"original" is the byte you want to reverse.
"reversed" is the result, initialized to 0.
add a comment |
up vote
12
down vote
Although probably not portable, I would use assembly language.
Many assembly languages have instructions to rotate a bit into the carry flag and to rotate the carry flag into the word (or byte).
The algorithm is:
for each bit in the data type:
rotate bit into carry flag
rotate carry flag into destination.
end-for
The high level language code for this is much more complicated, because C and C++ do not support rotating to carry and rotating from carry. The carry flag has to modeled.
Edit: Assembly language for example
; Enter with value to reverse in R0.
; Assume 8 bits per byte and byte is the native processor type.
LODI, R2 8 ; Set up the bit counter
Loop:
RRC, R0 ; Rotate R0 right into the carry bit.
RLC, R1 ; Rotate R1 left, then append carry bit.
DJNZ, R2 Loop ; Decrement R2 and jump if non-zero to "loop"
LODR, R0 R1 ; Move result into R0.
6
I think this answer is the opposite of simple. Non-portable, assembly, and complex enough to be written in pseudo-code instead of the actual assembly.
– deft_code
Apr 8 '10 at 20:59
3
It is quite simple. I put it into pseudo-code because assembly mnemonics are specific to a breed of processor and there are a lot of breeds out there. If you would like, I can edit this to show the simple assembly language.
– Thomas Matthews
Apr 9 '10 at 16:53
add a comment |
up vote
10
down vote
The simplest way is probably to iterate over the bit positions in a loop:
unsigned char reverse(unsigned char c) {
int shift;
unsigned char result = 0;
for (shift = 0; shift < CHAR_BIT; shift++) {
if (c & (0x01 << shift))
result |= (0x80 >> shift);
}
return result;
}
it's CHAR_BIT, without an 's'
– larkey
Jun 22 at 12:25
@larkey: you're right, thanks
– sth
Jun 22 at 18:43
add a comment |
up vote
8
down vote
I find the following solution simpler than the other bit fiddling algorithms I've seen in here.
unsigned char reverse_byte(char a)
{
return ((a & 0x1) << 7) | ((a & 0x2) << 5) |
((a & 0x4) << 3) | ((a & 0x8) << 1) |
((a & 0x10) >> 1) | ((a & 0x20) >> 3) |
((a & 0x40) >> 5) | ((a & 0x80) >> 7);
}
It gets every bit in the byte, and shifts it accordingly, starting from the first to the last.
Explanation:
((a & 0x1) << 7) //get first bit on the right and shift it into the first left position
| ((a & 0x2) << 5) //add it to the second bit and shift it into the second left position
//and so on
Beautiful! My favorite so far.
– Nick Rameau
Nov 22 '16 at 8:15
1
thanks! I think simplicity is key in these scenario
– dau_sama
Nov 22 '16 at 9:11
add a comment |
up vote
7
down vote
For constant, 8-bit input, this costs no memory or CPU at run-time:
#define MSB2LSB(b) (((b)&1?128:0)|((b)&2?64:0)|((b)&4?32:0)|((b)&8?16:0)|((b)&16?8:0)|((b)&32?4:0)|((b)&64?2:0)|((b)&128?1:0))
I used this for ARINC-429 where the bit order (endianness) of the label is opposite the rest of the word. The label is often a constant, and conventionally in octal. For example:
#define LABEL_HF_COMM MSB2LSB(0205)
add a comment |
up vote
6
down vote
You may be interested in std::vector<bool>
(that is bit-packed) and std::bitset
It should be the simplest as requested.
#include <iostream>
#include <bitset>
using namespace std;
int main() {
bitset<8> bs = 5;
bitset<8> rev;
for(int ii=0; ii!= bs.size(); ++ii)
rev[bs.size()-ii-1] = bs[ii];
cerr << bs << " " << rev << endl;
}
Other options may be faster.
EDIT: I owe you a solution using std::vector<bool>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<bool> b{0,0,0,0,0,1,0,1};
reverse(b.begin(), b.end());
copy(b.begin(), b.end(), ostream_iterator<int>(cerr));
cerr << endl;
}
The second example requires c++0x extension (to initialize the array with {...}
). The advantage of using a bitset
or a std::vector<bool>
(or a boost::dynamic_bitset
) is that you are not limited to bytes or words but can reverse an arbitrary number of bits.
HTH
How is bitset any simpler than a pod here? Show the code, or it isn't.
– wilhelmtell
Apr 8 '10 at 19:53
Actu ally, I think that code will reverse the bitset, and then reverse it back to its original. Change ii != size(); to ii < size()/2; and it'll do a better job =)
– Viktor Sehr
Apr 8 '10 at 19:58
(@viktor-sehr no, it will not, rev is different from bs). Anyway I don't like the answer myself: I think this is a case where binary arithmetic and shift operators are better suited. It still remains the simplest to understand.
– baol
Apr 8 '10 at 20:07
ah, youre right, sorry
– Viktor Sehr
Apr 9 '10 at 7:26
How aboutstd::vector<bool> b = { ... }; std::vector<bool> rb ( b.rbegin(), b.rend());
- using reverse iterators directly?
– MSalters
Aug 30 '17 at 21:19
|
show 1 more comment
up vote
3
down vote
Table lookup or
uint8_t rev_byte(uint8_t x) {
uint8_t y;
uint8_t m = 1;
while (m) {
y >>= 1;
if (m&x) {
y |= 0x80;
}
m <<=1;
}
return y;
}
edit
Look here for other solutions that might work better for you
add a comment |
up vote
2
down vote
Before implementing any algorithmic solution, check the assembly language for whatever CPU architecture you are using. Your architecture may include instructions which handle bitwise manipulations like this (and what could be simpler than a single assembly instruction?).
If such an instruction is not available, then I would suggest going with the lookup table route. You can write a script/program to generate the table for you, and the lookup operations would be faster than any of the bit-reversing algorithms here (at the cost of having to store the lookup table somewhere).
add a comment |
up vote
2
down vote
a slower but simpler implementation:
static int swap_bit(unsigned char unit)
{
/*
* swap bit[7] and bit[0]
*/
unit = (((((unit & 0x80) >> 7) ^ (unit & 0x01)) << 7) | (unit & 0x7f));
unit = (((((unit & 0x80) >> 7) ^ (unit & 0x01))) | (unit & 0xfe));
unit = (((((unit & 0x80) >> 7) ^ (unit & 0x01)) << 7) | (unit & 0x7f));
/*
* swap bit[6] and bit[1]
*/
unit = (((((unit & 0x40) >> 5) ^ (unit & 0x02)) << 5) | (unit & 0xbf));
unit = (((((unit & 0x40) >> 5) ^ (unit & 0x02))) | (unit & 0xfd));
unit = (((((unit & 0x40) >> 5) ^ (unit & 0x02)) << 5) | (unit & 0xbf));
/*
* swap bit[5] and bit[2]
*/
unit = (((((unit & 0x20) >> 3) ^ (unit & 0x04)) << 3) | (unit & 0xdf));
unit = (((((unit & 0x20) >> 3) ^ (unit & 0x04))) | (unit & 0xfb));
unit = (((((unit & 0x20) >> 3) ^ (unit & 0x04)) << 3) | (unit & 0xdf));
/*
* swap bit[4] and bit[3]
*/
unit = (((((unit & 0x10) >> 1) ^ (unit & 0x08)) << 1) | (unit & 0xef));
unit = (((((unit & 0x10) >> 1) ^ (unit & 0x08))) | (unit & 0xf7));
unit = (((((unit & 0x10) >> 1) ^ (unit & 0x08)) << 1) | (unit & 0xef));
return unit;
}
add a comment |
up vote
2
down vote
Can this be fast solution?
int byte_to_be_reversed =
((byte_to_be_reversed>>7)&0x01)|((byte_to_be_reversed>>5)&0x02)|
((byte_to_be_reversed>>3)&0x04)|((byte_to_be_reversed>>1)&0x08)|
((byte_to_be_reversed<<7)&0x80)|((byte_to_be_reversed<<5)&0x40)|
((byte_to_be_reversed<<3)&0x20)|((byte_to_be_reversed<<1)&0x10);
Gets rid of the hustle of using a for loop! but experts please tell me if this is efficient and faster?
add a comment |
up vote
2
down vote
This simple function uses a mask to test each bit in the input byte and transfer it into a shifting output:
char Reverse_Bits(char input)
{
char output = 0;
for (unsigned char mask = 1; mask > 0; mask <<= 1)
{
output <<= 1;
if (input & mask)
output |= 1;
}
return output;
}
Mask should be unsigned sorry.
– luci88filter
Feb 17 at 8:45
add a comment |
up vote
1
down vote
This one is based on the one BobStein-VisiBone provided
#define reverse_1byte(b) ( ((uint8_t)b & 0b00000001) ? 0b10000000 : 0 ) |
( ((uint8_t)b & 0b00000010) ? 0b01000000 : 0 ) |
( ((uint8_t)b & 0b00000100) ? 0b00100000 : 0 ) |
( ((uint8_t)b & 0b00001000) ? 0b00010000 : 0 ) |
( ((uint8_t)b & 0b00010000) ? 0b00001000 : 0 ) |
( ((uint8_t)b & 0b00100000) ? 0b00000100 : 0 ) |
( ((uint8_t)b & 0b01000000) ? 0b00000010 : 0 ) |
( ((uint8_t)b & 0b10000000) ? 0b00000001 : 0 )
I really like this one a lot because the compiler automatically handle the work for you, thus require no further resources.
this can also be extended to 16-Bits...
#define reverse_2byte(b) ( ((uint16_t)b & 0b0000000000000001) ? 0b1000000000000000 : 0 ) |
( ((uint16_t)b & 0b0000000000000010) ? 0b0100000000000000 : 0 ) |
( ((uint16_t)b & 0b0000000000000100) ? 0b0010000000000000 : 0 ) |
( ((uint16_t)b & 0b0000000000001000) ? 0b0001000000000000 : 0 ) |
( ((uint16_t)b & 0b0000000000010000) ? 0b0000100000000000 : 0 ) |
( ((uint16_t)b & 0b0000000000100000) ? 0b0000010000000000 : 0 ) |
( ((uint16_t)b & 0b0000000001000000) ? 0b0000001000000000 : 0 ) |
( ((uint16_t)b & 0b0000000010000000) ? 0b0000000100000000 : 0 ) |
( ((uint16_t)b & 0b0000000100000000) ? 0b0000000010000000 : 0 ) |
( ((uint16_t)b & 0b0000001000000000) ? 0b0000000001000000 : 0 ) |
( ((uint16_t)b & 0b0000010000000000) ? 0b0000000000100000 : 0 ) |
( ((uint16_t)b & 0b0000100000000000) ? 0b0000000000010000 : 0 ) |
( ((uint16_t)b & 0b0001000000000000) ? 0b0000000000001000 : 0 ) |
( ((uint16_t)b & 0b0010000000000000) ? 0b0000000000000100 : 0 ) |
( ((uint16_t)b & 0b0100000000000000) ? 0b0000000000000010 : 0 ) |
( ((uint16_t)b & 0b1000000000000000) ? 0b0000000000000001 : 0 )
I would put theb
in parentheses in case it is a more complex expression than a single number, and perhaps also rename the macro toREVERSE_BYTE
as a hint that you probably don't want to have a more complex (runtime) expression there. Or make it an inline function. (But overall I like this as being simple enough that you could do it from memory easily with very little chance of error.)
– Arkku
Aug 8 at 14:55
add a comment |
up vote
0
down vote
typedef struct
{
uint8_t b0:1;
uint8_t b1:1;
uint8_t b2:1;
uint8_t b3:1;
uint8_t b4:1;
uint8_t b5:1;
uint8_t b6:1;
uint8_t b7:1;
} bits_t;
uint8_t reverse_bits(uint8_t src)
{
uint8_t dst = 0x0;
bits_t *src_bits = (bits_t *)&src;
bits_t *dst_bits = (bits_t *)&dst;
dst_bits->b0 = src_bits->b7;
dst_bits->b1 = src_bits->b6;
dst_bits->b2 = src_bits->b5;
dst_bits->b3 = src_bits->b4;
dst_bits->b4 = src_bits->b3;
dst_bits->b5 = src_bits->b2;
dst_bits->b6 = src_bits->b1;
dst_bits->b7 = src_bits->b0;
return dst;
}
As a stylistic note, I find the use ofuint8_t
for the 1-bit fields a bit ugly, since it seems to first say that it will take 8 bits but then at the end of the line defines it as only a single bit. I would useunsigned b0:1
etc.
– Arkku
Aug 8 at 14:44
add a comment |
up vote
0
down vote
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i;
unsigned char rev = 0x70 ; // 0b01110000
unsigned char tmp = 0;
for(i=0;i<8;i++)
{
tmp |= ( ((rev & (1<<i))?1:0) << (7-i));
}
rev = tmp;
printf("%x", rev); //0b00001110 binary value of given number
return 0;
}
Please add some explanation.
– zcui93
Apr 5 '16 at 12:33
add a comment |
up vote
0
down vote
I think this is simple enough
uint8_t reverse(uint8_t a)
{
unsigned w = ((a << 7) & 0x0880) | ((a << 5) & 0x0440) | ((a << 3) & 0x0220) | ((a << 1) & 0x0110);
return static_cast<uint8_t>(w | (w>>8));
}
or
uint8_t reverse(uint8_t a)
{
unsigned w = ((a & 0x11) << 7) | ((a & 0x22) << 5) | ((a & 0x44) << 3) | ((a & 0x88) << 1);
return static_cast<uint8_t>(w | (w>>8));
}
add a comment |
up vote
0
down vote
unsigned char c ; // the original
unsigned char u = // the reversed
c>>7&0b00000001 |
c<<7&0b10000000 |
c>>5&0b00000010 |
c<<5&0b01000000 |
c>>3&0b00000100 |
c<<3&0b00100000 |
c>>1&0b00001000 |
c<<1&0b00010000 ;
Explanation: exchanged bits as per the arrows below.
01234567
<------>
#<---->#
##<-->##
###<>###
add a comment |
up vote
-1
down vote
#define BITS_SIZE 8
int
reverseBits ( int a )
{
int rev = 0;
int i;
/* scans each bit of the input number*/
for ( i = 0; i < BITS_SIZE - 1; i++ )
{
/* checks if the bit is 1 */
if ( a & ( 1 << i ) )
{
/* shifts the bit 1, starting from the MSB to LSB
* to build the reverse number
*/
rev |= 1 << ( BITS_SIZE - 1 ) - i;
}
}
return rev;
}
add a comment |
up vote
-1
down vote
xor ax,ax
xor bx,bx
mov cx,8
mov al,original_byte!
cycle: shr al,1
jnc not_inc
inc bl
not_inc: test cx,cx
jz,end_cycle
shl bl,1
loop cycle
end_cycle:
reversed byte will be at bl register
3
In an other context that may be a fair answer but the question was about C or C++, not asm ...
– jadsq
May 31 '17 at 16:35
add a comment |
up vote
-2
down vote
How about this one...
int value = 0xFACE;
value = ((0xFF & value << 8) | (val >> 8);
4
This reverses the bytes in a (16-bit) word, but doesn't alter the order of the bits within the byte, so not really a solution.
– Eric Brown
Sep 25 '13 at 16:38
1
Ah, thank you Eric. My mistake.
– Valdo
Sep 25 '13 at 18:29
add a comment |
up vote
-2
down vote
This is an old question, but nobody seems to have shown the clear easy way (the closest was edW). I used C# (and the wonderful LinqPad to test this) but there's nothing in this example that couldn't be done easily in C.
Paste the following into the wonderful LinqPad (https://www.linqpad.net/), (which is where I tested this):
void PrintBinary(string prompt, int num, int pad = 8)
{
Debug.WriteLine($"{prompt}: {Convert.ToString(num, 2).PadLeft(pad, '0')}");
}
int ReverseBits(int num)
{
int result = 0;
int saveBits = num;
for (int i = 1; i <= 8; i++)
{
// Move the result one bit to the left
result = result << 1;
//PrintBinary("saveBits", saveBits);
// Extract the right-most bit
var nextBit = saveBits & 1;
//PrintBinary("nextBit", nextBit, 1);
// Add our extracted bit to the result
result = result | nextBit;
//PrintBinary("result", result);
// We're done with that bit, rotate it off the right
saveBits = saveBits >> 1;
//Debug.WriteLine("");
}
return result;
}
void PrintTest(int nextNumber)
{
var result = ReverseBits(nextNumber);
Debug.WriteLine("---------------------------------------");
PrintBinary("Original", nextNumber);
PrintBinary("Reverse", result);
}
void Main()
{
// Calculate the reverse for each number between 1 and 255
for (int x = 250; x < 256; x++)
PrintTest(x);
}
There are a couple of other answers (in C, no less) that implement the simple approach of iterating over the bits. I guess the point here was to advertise the online service to run C# code, but as an answer to this question this fails by being in a different language and including too much irrelevant stuff. (Even your test loop doesn't match the comment: the comment says "between 1 and 255" but your loop goes 250 to 255.)
– Arkku
Aug 8 at 15:01
add a comment |
up vote
-4
down vote
How about just XOR the byte with 0xFF.
unsigned char reverse(unsigned char b) {
b ^= 0xFF;
return b;
}
2
what about 00111100? u get 11000011 what is wrong answer.
– lord.didger
Apr 6 '13 at 13:45
add a comment |
27 Answers
27
active
oldest
votes
27 Answers
27
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
87
down vote
accepted
If you are talking about a single byte, a table-lookup is probably the best bet, unless for some reason you don't have 256 bytes available.
9
If we're talking about something that's simple to implement without copying a ready-made solution, creating the lookup table does still require another solution. (Of course one might do it by hand, but that's error-prone and time-consuming…)
– Arkku
Apr 8 '10 at 19:52
7
You can squeeze the array into somewhat fewer than 256 bytes if you ignore palindromes.
– wilhelmtell
Apr 8 '10 at 19:56
7
@wilhelmtell - you'd need a table to know which ones are the palindromes.
– Mark Ransom
Apr 8 '10 at 20:01
6
@wilhelmtell: Well, to write the script one still needs another solution, which was my point – a lookup table is simple to use but not simple to create. (Except by copying a ready-made lookup table, but then one might just as well copy any solution.) For example, if the “simplest” solution is considered one that could be written on paper in an exam or interview, I would not start making a lookup table by hand and making the program to do it would already include a different solution (which would be simpler alone than the one including both it and the table).
– Arkku
Apr 8 '10 at 20:18
4
@Arkku what I meant is write a script which outputs the table of the first 256 bytes and their reverse mapping. Yes, you're back to writing the reverse function, but now in your favourite scripting language, and it can be as nasty as you want -- you're going to throw it away as soon as it's done and you ran it once. Have the script's output as C code, even:unsigned int rtable = {0x800, 0x4000, ...};
. Then throw away the script and forget you ever had it. It's much faster to write than the equivalent C++ code, and it will only ever run once, so you get O(1) runtime in your C++ code.
– wilhelmtell
Apr 8 '10 at 21:32
|
show 11 more comments
up vote
87
down vote
accepted
If you are talking about a single byte, a table-lookup is probably the best bet, unless for some reason you don't have 256 bytes available.
9
If we're talking about something that's simple to implement without copying a ready-made solution, creating the lookup table does still require another solution. (Of course one might do it by hand, but that's error-prone and time-consuming…)
– Arkku
Apr 8 '10 at 19:52
7
You can squeeze the array into somewhat fewer than 256 bytes if you ignore palindromes.
– wilhelmtell
Apr 8 '10 at 19:56
7
@wilhelmtell - you'd need a table to know which ones are the palindromes.
– Mark Ransom
Apr 8 '10 at 20:01
6
@wilhelmtell: Well, to write the script one still needs another solution, which was my point – a lookup table is simple to use but not simple to create. (Except by copying a ready-made lookup table, but then one might just as well copy any solution.) For example, if the “simplest” solution is considered one that could be written on paper in an exam or interview, I would not start making a lookup table by hand and making the program to do it would already include a different solution (which would be simpler alone than the one including both it and the table).
– Arkku
Apr 8 '10 at 20:18
4
@Arkku what I meant is write a script which outputs the table of the first 256 bytes and their reverse mapping. Yes, you're back to writing the reverse function, but now in your favourite scripting language, and it can be as nasty as you want -- you're going to throw it away as soon as it's done and you ran it once. Have the script's output as C code, even:unsigned int rtable = {0x800, 0x4000, ...};
. Then throw away the script and forget you ever had it. It's much faster to write than the equivalent C++ code, and it will only ever run once, so you get O(1) runtime in your C++ code.
– wilhelmtell
Apr 8 '10 at 21:32
|
show 11 more comments
up vote
87
down vote
accepted
up vote
87
down vote
accepted
If you are talking about a single byte, a table-lookup is probably the best bet, unless for some reason you don't have 256 bytes available.
If you are talking about a single byte, a table-lookup is probably the best bet, unless for some reason you don't have 256 bytes available.
answered Apr 8 '10 at 19:34
e.James
81k31159203
81k31159203
9
If we're talking about something that's simple to implement without copying a ready-made solution, creating the lookup table does still require another solution. (Of course one might do it by hand, but that's error-prone and time-consuming…)
– Arkku
Apr 8 '10 at 19:52
7
You can squeeze the array into somewhat fewer than 256 bytes if you ignore palindromes.
– wilhelmtell
Apr 8 '10 at 19:56
7
@wilhelmtell - you'd need a table to know which ones are the palindromes.
– Mark Ransom
Apr 8 '10 at 20:01
6
@wilhelmtell: Well, to write the script one still needs another solution, which was my point – a lookup table is simple to use but not simple to create. (Except by copying a ready-made lookup table, but then one might just as well copy any solution.) For example, if the “simplest” solution is considered one that could be written on paper in an exam or interview, I would not start making a lookup table by hand and making the program to do it would already include a different solution (which would be simpler alone than the one including both it and the table).
– Arkku
Apr 8 '10 at 20:18
4
@Arkku what I meant is write a script which outputs the table of the first 256 bytes and their reverse mapping. Yes, you're back to writing the reverse function, but now in your favourite scripting language, and it can be as nasty as you want -- you're going to throw it away as soon as it's done and you ran it once. Have the script's output as C code, even:unsigned int rtable = {0x800, 0x4000, ...};
. Then throw away the script and forget you ever had it. It's much faster to write than the equivalent C++ code, and it will only ever run once, so you get O(1) runtime in your C++ code.
– wilhelmtell
Apr 8 '10 at 21:32
|
show 11 more comments
9
If we're talking about something that's simple to implement without copying a ready-made solution, creating the lookup table does still require another solution. (Of course one might do it by hand, but that's error-prone and time-consuming…)
– Arkku
Apr 8 '10 at 19:52
7
You can squeeze the array into somewhat fewer than 256 bytes if you ignore palindromes.
– wilhelmtell
Apr 8 '10 at 19:56
7
@wilhelmtell - you'd need a table to know which ones are the palindromes.
– Mark Ransom
Apr 8 '10 at 20:01
6
@wilhelmtell: Well, to write the script one still needs another solution, which was my point – a lookup table is simple to use but not simple to create. (Except by copying a ready-made lookup table, but then one might just as well copy any solution.) For example, if the “simplest” solution is considered one that could be written on paper in an exam or interview, I would not start making a lookup table by hand and making the program to do it would already include a different solution (which would be simpler alone than the one including both it and the table).
– Arkku
Apr 8 '10 at 20:18
4
@Arkku what I meant is write a script which outputs the table of the first 256 bytes and their reverse mapping. Yes, you're back to writing the reverse function, but now in your favourite scripting language, and it can be as nasty as you want -- you're going to throw it away as soon as it's done and you ran it once. Have the script's output as C code, even:unsigned int rtable = {0x800, 0x4000, ...};
. Then throw away the script and forget you ever had it. It's much faster to write than the equivalent C++ code, and it will only ever run once, so you get O(1) runtime in your C++ code.
– wilhelmtell
Apr 8 '10 at 21:32
9
9
If we're talking about something that's simple to implement without copying a ready-made solution, creating the lookup table does still require another solution. (Of course one might do it by hand, but that's error-prone and time-consuming…)
– Arkku
Apr 8 '10 at 19:52
If we're talking about something that's simple to implement without copying a ready-made solution, creating the lookup table does still require another solution. (Of course one might do it by hand, but that's error-prone and time-consuming…)
– Arkku
Apr 8 '10 at 19:52
7
7
You can squeeze the array into somewhat fewer than 256 bytes if you ignore palindromes.
– wilhelmtell
Apr 8 '10 at 19:56
You can squeeze the array into somewhat fewer than 256 bytes if you ignore palindromes.
– wilhelmtell
Apr 8 '10 at 19:56
7
7
@wilhelmtell - you'd need a table to know which ones are the palindromes.
– Mark Ransom
Apr 8 '10 at 20:01
@wilhelmtell - you'd need a table to know which ones are the palindromes.
– Mark Ransom
Apr 8 '10 at 20:01
6
6
@wilhelmtell: Well, to write the script one still needs another solution, which was my point – a lookup table is simple to use but not simple to create. (Except by copying a ready-made lookup table, but then one might just as well copy any solution.) For example, if the “simplest” solution is considered one that could be written on paper in an exam or interview, I would not start making a lookup table by hand and making the program to do it would already include a different solution (which would be simpler alone than the one including both it and the table).
– Arkku
Apr 8 '10 at 20:18
@wilhelmtell: Well, to write the script one still needs another solution, which was my point – a lookup table is simple to use but not simple to create. (Except by copying a ready-made lookup table, but then one might just as well copy any solution.) For example, if the “simplest” solution is considered one that could be written on paper in an exam or interview, I would not start making a lookup table by hand and making the program to do it would already include a different solution (which would be simpler alone than the one including both it and the table).
– Arkku
Apr 8 '10 at 20:18
4
4
@Arkku what I meant is write a script which outputs the table of the first 256 bytes and their reverse mapping. Yes, you're back to writing the reverse function, but now in your favourite scripting language, and it can be as nasty as you want -- you're going to throw it away as soon as it's done and you ran it once. Have the script's output as C code, even:
unsigned int rtable = {0x800, 0x4000, ...};
. Then throw away the script and forget you ever had it. It's much faster to write than the equivalent C++ code, and it will only ever run once, so you get O(1) runtime in your C++ code.– wilhelmtell
Apr 8 '10 at 21:32
@Arkku what I meant is write a script which outputs the table of the first 256 bytes and their reverse mapping. Yes, you're back to writing the reverse function, but now in your favourite scripting language, and it can be as nasty as you want -- you're going to throw it away as soon as it's done and you ran it once. Have the script's output as C code, even:
unsigned int rtable = {0x800, 0x4000, ...};
. Then throw away the script and forget you ever had it. It's much faster to write than the equivalent C++ code, and it will only ever run once, so you get O(1) runtime in your C++ code.– wilhelmtell
Apr 8 '10 at 21:32
|
show 11 more comments
up vote
192
down vote
This should work:
unsigned char reverse(unsigned char b) {
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
return b;
}
First the left four bits are swapped with the right four bits. Then all adjacent pairs are swapped and then all adjacent single bits. This results in a reversed order.
23
Reasonably short and quick, but not simple.
– Mark Ransom
Apr 8 '10 at 19:58
1
This approach also cleanly generalizes to perform byte swapping for endianness.
– Boojum
Apr 8 '10 at 20:25
9
+1 for some truly brazen bit twisting!
– JustJeff
Apr 9 '10 at 1:11
1
Not the simplest approach, but I like it +1.
– nathan
Apr 9 '10 at 14:10
4
Yes, it is simple. It's a kind of divide and conquer algorithm. Excellent!
– kiewic
May 11 '10 at 4:25
|
show 3 more comments
up vote
192
down vote
This should work:
unsigned char reverse(unsigned char b) {
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
return b;
}
First the left four bits are swapped with the right four bits. Then all adjacent pairs are swapped and then all adjacent single bits. This results in a reversed order.
23
Reasonably short and quick, but not simple.
– Mark Ransom
Apr 8 '10 at 19:58
1
This approach also cleanly generalizes to perform byte swapping for endianness.
– Boojum
Apr 8 '10 at 20:25
9
+1 for some truly brazen bit twisting!
– JustJeff
Apr 9 '10 at 1:11
1
Not the simplest approach, but I like it +1.
– nathan
Apr 9 '10 at 14:10
4
Yes, it is simple. It's a kind of divide and conquer algorithm. Excellent!
– kiewic
May 11 '10 at 4:25
|
show 3 more comments
up vote
192
down vote
up vote
192
down vote
This should work:
unsigned char reverse(unsigned char b) {
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
return b;
}
First the left four bits are swapped with the right four bits. Then all adjacent pairs are swapped and then all adjacent single bits. This results in a reversed order.
This should work:
unsigned char reverse(unsigned char b) {
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
return b;
}
First the left four bits are swapped with the right four bits. Then all adjacent pairs are swapped and then all adjacent single bits. This results in a reversed order.
answered Apr 8 '10 at 19:40
sth
163k40240331
163k40240331
23
Reasonably short and quick, but not simple.
– Mark Ransom
Apr 8 '10 at 19:58
1
This approach also cleanly generalizes to perform byte swapping for endianness.
– Boojum
Apr 8 '10 at 20:25
9
+1 for some truly brazen bit twisting!
– JustJeff
Apr 9 '10 at 1:11
1
Not the simplest approach, but I like it +1.
– nathan
Apr 9 '10 at 14:10
4
Yes, it is simple. It's a kind of divide and conquer algorithm. Excellent!
– kiewic
May 11 '10 at 4:25
|
show 3 more comments
23
Reasonably short and quick, but not simple.
– Mark Ransom
Apr 8 '10 at 19:58
1
This approach also cleanly generalizes to perform byte swapping for endianness.
– Boojum
Apr 8 '10 at 20:25
9
+1 for some truly brazen bit twisting!
– JustJeff
Apr 9 '10 at 1:11
1
Not the simplest approach, but I like it +1.
– nathan
Apr 9 '10 at 14:10
4
Yes, it is simple. It's a kind of divide and conquer algorithm. Excellent!
– kiewic
May 11 '10 at 4:25
23
23
Reasonably short and quick, but not simple.
– Mark Ransom
Apr 8 '10 at 19:58
Reasonably short and quick, but not simple.
– Mark Ransom
Apr 8 '10 at 19:58
1
1
This approach also cleanly generalizes to perform byte swapping for endianness.
– Boojum
Apr 8 '10 at 20:25
This approach also cleanly generalizes to perform byte swapping for endianness.
– Boojum
Apr 8 '10 at 20:25
9
9
+1 for some truly brazen bit twisting!
– JustJeff
Apr 9 '10 at 1:11
+1 for some truly brazen bit twisting!
– JustJeff
Apr 9 '10 at 1:11
1
1
Not the simplest approach, but I like it +1.
– nathan
Apr 9 '10 at 14:10
Not the simplest approach, but I like it +1.
– nathan
Apr 9 '10 at 14:10
4
4
Yes, it is simple. It's a kind of divide and conquer algorithm. Excellent!
– kiewic
May 11 '10 at 4:25
Yes, it is simple. It's a kind of divide and conquer algorithm. Excellent!
– kiewic
May 11 '10 at 4:25
|
show 3 more comments
up vote
105
down vote
I think a lookup table has to be one of the simplest methods. However, you don't need a full lookup table.
//Index 1==0b0001 => 0b1000
//Index 7==0b0111 => 0b1110
//etc
static unsigned char lookup[16] = {
0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf, };
uint8_t reverse(uint8_t n) {
// Reverse the top and bottom nibble then swap them.
return (lookup[n&0b1111] << 4) | lookup[n>>4];
}
// Detailed breakdown of the math
// + lookup reverse of bottom nibble
// | + grab bottom nibble
// | | + move bottom result into top nibble
// | | | + combine the bottom and top results
// | | | | + lookup reverse of top nibble
// | | | | | + grab top nibble
// V V V V V V
// (lookup[n&0b1111] << 4) | lookup[n>>4]
This fairly simple to code and verify visually.
Ultimately this might even be faster than a full table. The bit arith is cheap and the table easily fits on a cache line.
7
That is an excellent way to reduce the complexity of the table solution. +1
– e.James
Apr 8 '10 at 23:55
1
Nice, but will give you a cache miss.
– Johan Kotlinski
Nov 3 '10 at 17:42
6
@kotlinski: what will cause a cache miss? I think the small table version may be more cache efficient than the large one. On my Core2 a cache line is 64 bytes wide, the full table would span multiple lines, whereas the smaller table easily fits one a single line.
– deft_code
Oct 1 '11 at 14:20
4
@kotlinski: Temporal locality is more important for cache hits or replacement strategies, than address locality
– cfi
Sep 25 '13 at 16:39
4
@Harshdeep: Consider the binary encoded indexes of the table entries. index b0000(0) -> b0000(0x0) boring;b0001(1) -> b1000(0x8)
,b0010(2) -> b0100(0x4)
,b1010(10) -> b0101(0x5)
. See the pattern? It is simple enough that you can calculate it in your head (if you can read binary, otherwise you'll need paper to work it out). As for the leap that reversing an 8 bit integer is the same as reversing 4 bit parts then swapping them; I claim experience and intuition (or magic).
– deft_code
Jan 2 '14 at 20:48
|
show 9 more comments
up vote
105
down vote
I think a lookup table has to be one of the simplest methods. However, you don't need a full lookup table.
//Index 1==0b0001 => 0b1000
//Index 7==0b0111 => 0b1110
//etc
static unsigned char lookup[16] = {
0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf, };
uint8_t reverse(uint8_t n) {
// Reverse the top and bottom nibble then swap them.
return (lookup[n&0b1111] << 4) | lookup[n>>4];
}
// Detailed breakdown of the math
// + lookup reverse of bottom nibble
// | + grab bottom nibble
// | | + move bottom result into top nibble
// | | | + combine the bottom and top results
// | | | | + lookup reverse of top nibble
// | | | | | + grab top nibble
// V V V V V V
// (lookup[n&0b1111] << 4) | lookup[n>>4]
This fairly simple to code and verify visually.
Ultimately this might even be faster than a full table. The bit arith is cheap and the table easily fits on a cache line.
7
That is an excellent way to reduce the complexity of the table solution. +1
– e.James
Apr 8 '10 at 23:55
1
Nice, but will give you a cache miss.
– Johan Kotlinski
Nov 3 '10 at 17:42
6
@kotlinski: what will cause a cache miss? I think the small table version may be more cache efficient than the large one. On my Core2 a cache line is 64 bytes wide, the full table would span multiple lines, whereas the smaller table easily fits one a single line.
– deft_code
Oct 1 '11 at 14:20
4
@kotlinski: Temporal locality is more important for cache hits or replacement strategies, than address locality
– cfi
Sep 25 '13 at 16:39
4
@Harshdeep: Consider the binary encoded indexes of the table entries. index b0000(0) -> b0000(0x0) boring;b0001(1) -> b1000(0x8)
,b0010(2) -> b0100(0x4)
,b1010(10) -> b0101(0x5)
. See the pattern? It is simple enough that you can calculate it in your head (if you can read binary, otherwise you'll need paper to work it out). As for the leap that reversing an 8 bit integer is the same as reversing 4 bit parts then swapping them; I claim experience and intuition (or magic).
– deft_code
Jan 2 '14 at 20:48
|
show 9 more comments
up vote
105
down vote
up vote
105
down vote
I think a lookup table has to be one of the simplest methods. However, you don't need a full lookup table.
//Index 1==0b0001 => 0b1000
//Index 7==0b0111 => 0b1110
//etc
static unsigned char lookup[16] = {
0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf, };
uint8_t reverse(uint8_t n) {
// Reverse the top and bottom nibble then swap them.
return (lookup[n&0b1111] << 4) | lookup[n>>4];
}
// Detailed breakdown of the math
// + lookup reverse of bottom nibble
// | + grab bottom nibble
// | | + move bottom result into top nibble
// | | | + combine the bottom and top results
// | | | | + lookup reverse of top nibble
// | | | | | + grab top nibble
// V V V V V V
// (lookup[n&0b1111] << 4) | lookup[n>>4]
This fairly simple to code and verify visually.
Ultimately this might even be faster than a full table. The bit arith is cheap and the table easily fits on a cache line.
I think a lookup table has to be one of the simplest methods. However, you don't need a full lookup table.
//Index 1==0b0001 => 0b1000
//Index 7==0b0111 => 0b1110
//etc
static unsigned char lookup[16] = {
0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf, };
uint8_t reverse(uint8_t n) {
// Reverse the top and bottom nibble then swap them.
return (lookup[n&0b1111] << 4) | lookup[n>>4];
}
// Detailed breakdown of the math
// + lookup reverse of bottom nibble
// | + grab bottom nibble
// | | + move bottom result into top nibble
// | | | + combine the bottom and top results
// | | | | + lookup reverse of top nibble
// | | | | | + grab top nibble
// V V V V V V
// (lookup[n&0b1111] << 4) | lookup[n>>4]
This fairly simple to code and verify visually.
Ultimately this might even be faster than a full table. The bit arith is cheap and the table easily fits on a cache line.
edited Mar 21 '15 at 18:35
Gordon Bailey
3,3841426
3,3841426
answered Apr 8 '10 at 20:33
deft_code
33.8k21120200
33.8k21120200
7
That is an excellent way to reduce the complexity of the table solution. +1
– e.James
Apr 8 '10 at 23:55
1
Nice, but will give you a cache miss.
– Johan Kotlinski
Nov 3 '10 at 17:42
6
@kotlinski: what will cause a cache miss? I think the small table version may be more cache efficient than the large one. On my Core2 a cache line is 64 bytes wide, the full table would span multiple lines, whereas the smaller table easily fits one a single line.
– deft_code
Oct 1 '11 at 14:20
4
@kotlinski: Temporal locality is more important for cache hits or replacement strategies, than address locality
– cfi
Sep 25 '13 at 16:39
4
@Harshdeep: Consider the binary encoded indexes of the table entries. index b0000(0) -> b0000(0x0) boring;b0001(1) -> b1000(0x8)
,b0010(2) -> b0100(0x4)
,b1010(10) -> b0101(0x5)
. See the pattern? It is simple enough that you can calculate it in your head (if you can read binary, otherwise you'll need paper to work it out). As for the leap that reversing an 8 bit integer is the same as reversing 4 bit parts then swapping them; I claim experience and intuition (or magic).
– deft_code
Jan 2 '14 at 20:48
|
show 9 more comments
7
That is an excellent way to reduce the complexity of the table solution. +1
– e.James
Apr 8 '10 at 23:55
1
Nice, but will give you a cache miss.
– Johan Kotlinski
Nov 3 '10 at 17:42
6
@kotlinski: what will cause a cache miss? I think the small table version may be more cache efficient than the large one. On my Core2 a cache line is 64 bytes wide, the full table would span multiple lines, whereas the smaller table easily fits one a single line.
– deft_code
Oct 1 '11 at 14:20
4
@kotlinski: Temporal locality is more important for cache hits or replacement strategies, than address locality
– cfi
Sep 25 '13 at 16:39
4
@Harshdeep: Consider the binary encoded indexes of the table entries. index b0000(0) -> b0000(0x0) boring;b0001(1) -> b1000(0x8)
,b0010(2) -> b0100(0x4)
,b1010(10) -> b0101(0x5)
. See the pattern? It is simple enough that you can calculate it in your head (if you can read binary, otherwise you'll need paper to work it out). As for the leap that reversing an 8 bit integer is the same as reversing 4 bit parts then swapping them; I claim experience and intuition (or magic).
– deft_code
Jan 2 '14 at 20:48
7
7
That is an excellent way to reduce the complexity of the table solution. +1
– e.James
Apr 8 '10 at 23:55
That is an excellent way to reduce the complexity of the table solution. +1
– e.James
Apr 8 '10 at 23:55
1
1
Nice, but will give you a cache miss.
– Johan Kotlinski
Nov 3 '10 at 17:42
Nice, but will give you a cache miss.
– Johan Kotlinski
Nov 3 '10 at 17:42
6
6
@kotlinski: what will cause a cache miss? I think the small table version may be more cache efficient than the large one. On my Core2 a cache line is 64 bytes wide, the full table would span multiple lines, whereas the smaller table easily fits one a single line.
– deft_code
Oct 1 '11 at 14:20
@kotlinski: what will cause a cache miss? I think the small table version may be more cache efficient than the large one. On my Core2 a cache line is 64 bytes wide, the full table would span multiple lines, whereas the smaller table easily fits one a single line.
– deft_code
Oct 1 '11 at 14:20
4
4
@kotlinski: Temporal locality is more important for cache hits or replacement strategies, than address locality
– cfi
Sep 25 '13 at 16:39
@kotlinski: Temporal locality is more important for cache hits or replacement strategies, than address locality
– cfi
Sep 25 '13 at 16:39
4
4
@Harshdeep: Consider the binary encoded indexes of the table entries. index b0000(0) -> b0000(0x0) boring;
b0001(1) -> b1000(0x8)
, b0010(2) -> b0100(0x4)
, b1010(10) -> b0101(0x5)
. See the pattern? It is simple enough that you can calculate it in your head (if you can read binary, otherwise you'll need paper to work it out). As for the leap that reversing an 8 bit integer is the same as reversing 4 bit parts then swapping them; I claim experience and intuition (or magic).– deft_code
Jan 2 '14 at 20:48
@Harshdeep: Consider the binary encoded indexes of the table entries. index b0000(0) -> b0000(0x0) boring;
b0001(1) -> b1000(0x8)
, b0010(2) -> b0100(0x4)
, b1010(10) -> b0101(0x5)
. See the pattern? It is simple enough that you can calculate it in your head (if you can read binary, otherwise you'll need paper to work it out). As for the leap that reversing an 8 bit integer is the same as reversing 4 bit parts then swapping them; I claim experience and intuition (or magic).– deft_code
Jan 2 '14 at 20:48
|
show 9 more comments
up vote
38
down vote
See the bit twiddling hacks for many solutions. Copypasting from there is obviously simple to implement. =)
For example (on a 32-bit CPU):
uint8_t b = byte_to_reverse;
b = ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
If by “simple to implement” one means something that can be done without a reference in an exam or job interview, then the safest bet is probably the inefficient copying of bits one by one into another variable in reverse order (already shown in other answers).
1
From your URL: 32 bit CPU: b = ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
– Joshua
Apr 8 '10 at 20:13
1
@Joshua: That's my personal favourite as well. The caveat (as stated on the linked page) is that it needs to be assigned or cast into an uint8_t or there will be garbage in the upper bits.
– Arkku
Apr 8 '10 at 20:20
add a comment |
up vote
38
down vote
See the bit twiddling hacks for many solutions. Copypasting from there is obviously simple to implement. =)
For example (on a 32-bit CPU):
uint8_t b = byte_to_reverse;
b = ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
If by “simple to implement” one means something that can be done without a reference in an exam or job interview, then the safest bet is probably the inefficient copying of bits one by one into another variable in reverse order (already shown in other answers).
1
From your URL: 32 bit CPU: b = ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
– Joshua
Apr 8 '10 at 20:13
1
@Joshua: That's my personal favourite as well. The caveat (as stated on the linked page) is that it needs to be assigned or cast into an uint8_t or there will be garbage in the upper bits.
– Arkku
Apr 8 '10 at 20:20
add a comment |
up vote
38
down vote
up vote
38
down vote
See the bit twiddling hacks for many solutions. Copypasting from there is obviously simple to implement. =)
For example (on a 32-bit CPU):
uint8_t b = byte_to_reverse;
b = ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
If by “simple to implement” one means something that can be done without a reference in an exam or job interview, then the safest bet is probably the inefficient copying of bits one by one into another variable in reverse order (already shown in other answers).
See the bit twiddling hacks for many solutions. Copypasting from there is obviously simple to implement. =)
For example (on a 32-bit CPU):
uint8_t b = byte_to_reverse;
b = ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
If by “simple to implement” one means something that can be done without a reference in an exam or job interview, then the safest bet is probably the inefficient copying of bits one by one into another variable in reverse order (already shown in other answers).
edited Feb 27 '14 at 1:33
answered Apr 8 '10 at 19:37
Arkku
28.9k44764
28.9k44764
1
From your URL: 32 bit CPU: b = ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
– Joshua
Apr 8 '10 at 20:13
1
@Joshua: That's my personal favourite as well. The caveat (as stated on the linked page) is that it needs to be assigned or cast into an uint8_t or there will be garbage in the upper bits.
– Arkku
Apr 8 '10 at 20:20
add a comment |
1
From your URL: 32 bit CPU: b = ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
– Joshua
Apr 8 '10 at 20:13
1
@Joshua: That's my personal favourite as well. The caveat (as stated on the linked page) is that it needs to be assigned or cast into an uint8_t or there will be garbage in the upper bits.
– Arkku
Apr 8 '10 at 20:20
1
1
From your URL: 32 bit CPU: b = ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
– Joshua
Apr 8 '10 at 20:13
From your URL: 32 bit CPU: b = ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;
– Joshua
Apr 8 '10 at 20:13
1
1
@Joshua: That's my personal favourite as well. The caveat (as stated on the linked page) is that it needs to be assigned or cast into an uint8_t or there will be garbage in the upper bits.
– Arkku
Apr 8 '10 at 20:20
@Joshua: That's my personal favourite as well. The caveat (as stated on the linked page) is that it needs to be assigned or cast into an uint8_t or there will be garbage in the upper bits.
– Arkku
Apr 8 '10 at 20:20
add a comment |
up vote
34
down vote
Since nobody posted a complete table lookup solution, here is mine:
unsigned char reverse_byte(unsigned char x)
{
static const unsigned char table = {
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
};
return table[x];
}
1
Useful, thanks. Seems that my slower shifting method was limiting performance in an embedded app. Placed table in ROM on a PIC (with addition of rom keyword).
– flend
Apr 23 '12 at 10:02
1
A simpler method: graphics.stanford.edu/~seander/bithacks.html#BitReverseTable
– sleepsort
Jun 14 '14 at 1:30
add a comment |
up vote
34
down vote
Since nobody posted a complete table lookup solution, here is mine:
unsigned char reverse_byte(unsigned char x)
{
static const unsigned char table = {
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
};
return table[x];
}
1
Useful, thanks. Seems that my slower shifting method was limiting performance in an embedded app. Placed table in ROM on a PIC (with addition of rom keyword).
– flend
Apr 23 '12 at 10:02
1
A simpler method: graphics.stanford.edu/~seander/bithacks.html#BitReverseTable
– sleepsort
Jun 14 '14 at 1:30
add a comment |
up vote
34
down vote
up vote
34
down vote
Since nobody posted a complete table lookup solution, here is mine:
unsigned char reverse_byte(unsigned char x)
{
static const unsigned char table = {
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
};
return table[x];
}
Since nobody posted a complete table lookup solution, here is mine:
unsigned char reverse_byte(unsigned char x)
{
static const unsigned char table = {
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
};
return table[x];
}
answered Apr 9 '10 at 9:27
fredoverflow
162k65313593
162k65313593
1
Useful, thanks. Seems that my slower shifting method was limiting performance in an embedded app. Placed table in ROM on a PIC (with addition of rom keyword).
– flend
Apr 23 '12 at 10:02
1
A simpler method: graphics.stanford.edu/~seander/bithacks.html#BitReverseTable
– sleepsort
Jun 14 '14 at 1:30
add a comment |
1
Useful, thanks. Seems that my slower shifting method was limiting performance in an embedded app. Placed table in ROM on a PIC (with addition of rom keyword).
– flend
Apr 23 '12 at 10:02
1
A simpler method: graphics.stanford.edu/~seander/bithacks.html#BitReverseTable
– sleepsort
Jun 14 '14 at 1:30
1
1
Useful, thanks. Seems that my slower shifting method was limiting performance in an embedded app. Placed table in ROM on a PIC (with addition of rom keyword).
– flend
Apr 23 '12 at 10:02
Useful, thanks. Seems that my slower shifting method was limiting performance in an embedded app. Placed table in ROM on a PIC (with addition of rom keyword).
– flend
Apr 23 '12 at 10:02
1
1
A simpler method: graphics.stanford.edu/~seander/bithacks.html#BitReverseTable
– sleepsort
Jun 14 '14 at 1:30
A simpler method: graphics.stanford.edu/~seander/bithacks.html#BitReverseTable
– sleepsort
Jun 14 '14 at 1:30
add a comment |
up vote
24
down vote
template <typename T>
T reverse(T n, size_t b = sizeof(T) * CHAR_BIT)
{
assert(b <= std::numeric_limits<T>::digits);
T rv = 0;
for (size_t i = 0; i < b; ++i, n >>= 1) {
rv = (rv << 1) | (n & 0x01);
}
return rv;
}
EDIT:
Converted it to a template with the optional bitcount
sizeof(T) ....?
– N 1.1
Apr 8 '10 at 19:40
@nvl - fixed. I started building it as a template but decided halfway through to not do so... too many > <
– andand
Apr 8 '10 at 19:42
5
@andand For extra extra pendantry, replacesizeof(T)*CHAR_BIT
bystd::numeric_limits<T>::digits
(almost 4 years of pedantry later).
– Morwenn
Feb 25 '14 at 22:09
1
It should beCHAR_BIT
, notCHAR_BITS
.
– Xunie
Nov 8 '16 at 20:36
1
it should be rv = (rv << 1) | (n & 0x01);
– Vignesh
Mar 13 '17 at 23:20
|
show 3 more comments
up vote
24
down vote
template <typename T>
T reverse(T n, size_t b = sizeof(T) * CHAR_BIT)
{
assert(b <= std::numeric_limits<T>::digits);
T rv = 0;
for (size_t i = 0; i < b; ++i, n >>= 1) {
rv = (rv << 1) | (n & 0x01);
}
return rv;
}
EDIT:
Converted it to a template with the optional bitcount
sizeof(T) ....?
– N 1.1
Apr 8 '10 at 19:40
@nvl - fixed. I started building it as a template but decided halfway through to not do so... too many > <
– andand
Apr 8 '10 at 19:42
5
@andand For extra extra pendantry, replacesizeof(T)*CHAR_BIT
bystd::numeric_limits<T>::digits
(almost 4 years of pedantry later).
– Morwenn
Feb 25 '14 at 22:09
1
It should beCHAR_BIT
, notCHAR_BITS
.
– Xunie
Nov 8 '16 at 20:36
1
it should be rv = (rv << 1) | (n & 0x01);
– Vignesh
Mar 13 '17 at 23:20
|
show 3 more comments
up vote
24
down vote
up vote
24
down vote
template <typename T>
T reverse(T n, size_t b = sizeof(T) * CHAR_BIT)
{
assert(b <= std::numeric_limits<T>::digits);
T rv = 0;
for (size_t i = 0; i < b; ++i, n >>= 1) {
rv = (rv << 1) | (n & 0x01);
}
return rv;
}
EDIT:
Converted it to a template with the optional bitcount
template <typename T>
T reverse(T n, size_t b = sizeof(T) * CHAR_BIT)
{
assert(b <= std::numeric_limits<T>::digits);
T rv = 0;
for (size_t i = 0; i < b; ++i, n >>= 1) {
rv = (rv << 1) | (n & 0x01);
}
return rv;
}
EDIT:
Converted it to a template with the optional bitcount
edited May 31 '17 at 16:27
Toby Speight
16.1k133965
16.1k133965
answered Apr 8 '10 at 19:38
andand
11.2k93669
11.2k93669
sizeof(T) ....?
– N 1.1
Apr 8 '10 at 19:40
@nvl - fixed. I started building it as a template but decided halfway through to not do so... too many > <
– andand
Apr 8 '10 at 19:42
5
@andand For extra extra pendantry, replacesizeof(T)*CHAR_BIT
bystd::numeric_limits<T>::digits
(almost 4 years of pedantry later).
– Morwenn
Feb 25 '14 at 22:09
1
It should beCHAR_BIT
, notCHAR_BITS
.
– Xunie
Nov 8 '16 at 20:36
1
it should be rv = (rv << 1) | (n & 0x01);
– Vignesh
Mar 13 '17 at 23:20
|
show 3 more comments
sizeof(T) ....?
– N 1.1
Apr 8 '10 at 19:40
@nvl - fixed. I started building it as a template but decided halfway through to not do so... too many > <
– andand
Apr 8 '10 at 19:42
5
@andand For extra extra pendantry, replacesizeof(T)*CHAR_BIT
bystd::numeric_limits<T>::digits
(almost 4 years of pedantry later).
– Morwenn
Feb 25 '14 at 22:09
1
It should beCHAR_BIT
, notCHAR_BITS
.
– Xunie
Nov 8 '16 at 20:36
1
it should be rv = (rv << 1) | (n & 0x01);
– Vignesh
Mar 13 '17 at 23:20
sizeof(T) ....?
– N 1.1
Apr 8 '10 at 19:40
sizeof(T) ....?
– N 1.1
Apr 8 '10 at 19:40
@nvl - fixed. I started building it as a template but decided halfway through to not do so... too many > <
– andand
Apr 8 '10 at 19:42
@nvl - fixed. I started building it as a template but decided halfway through to not do so... too many > <
– andand
Apr 8 '10 at 19:42
5
5
@andand For extra extra pendantry, replace
sizeof(T)*CHAR_BIT
by std::numeric_limits<T>::digits
(almost 4 years of pedantry later).– Morwenn
Feb 25 '14 at 22:09
@andand For extra extra pendantry, replace
sizeof(T)*CHAR_BIT
by std::numeric_limits<T>::digits
(almost 4 years of pedantry later).– Morwenn
Feb 25 '14 at 22:09
1
1
It should be
CHAR_BIT
, not CHAR_BITS
.– Xunie
Nov 8 '16 at 20:36
It should be
CHAR_BIT
, not CHAR_BITS
.– Xunie
Nov 8 '16 at 20:36
1
1
it should be rv = (rv << 1) | (n & 0x01);
– Vignesh
Mar 13 '17 at 23:20
it should be rv = (rv << 1) | (n & 0x01);
– Vignesh
Mar 13 '17 at 23:20
|
show 3 more comments
up vote
14
down vote
Two lines:
for(i=0;i<8;i++)
reversed |= ((original>>i) & 0b1)<<(7-i);
or in case you have issues with the "0b1" part:
for(i=0;i<8;i++)
reversed |= ((original>>i) & 1)<<(7-i);
"original" is the byte you want to reverse.
"reversed" is the result, initialized to 0.
add a comment |
up vote
14
down vote
Two lines:
for(i=0;i<8;i++)
reversed |= ((original>>i) & 0b1)<<(7-i);
or in case you have issues with the "0b1" part:
for(i=0;i<8;i++)
reversed |= ((original>>i) & 1)<<(7-i);
"original" is the byte you want to reverse.
"reversed" is the result, initialized to 0.
add a comment |
up vote
14
down vote
up vote
14
down vote
Two lines:
for(i=0;i<8;i++)
reversed |= ((original>>i) & 0b1)<<(7-i);
or in case you have issues with the "0b1" part:
for(i=0;i<8;i++)
reversed |= ((original>>i) & 1)<<(7-i);
"original" is the byte you want to reverse.
"reversed" is the result, initialized to 0.
Two lines:
for(i=0;i<8;i++)
reversed |= ((original>>i) & 0b1)<<(7-i);
or in case you have issues with the "0b1" part:
for(i=0;i<8;i++)
reversed |= ((original>>i) & 1)<<(7-i);
"original" is the byte you want to reverse.
"reversed" is the result, initialized to 0.
edited Aug 7 '13 at 7:13
answered Jan 28 '13 at 15:40
Daniel
358321
358321
add a comment |
add a comment |
up vote
12
down vote
Although probably not portable, I would use assembly language.
Many assembly languages have instructions to rotate a bit into the carry flag and to rotate the carry flag into the word (or byte).
The algorithm is:
for each bit in the data type:
rotate bit into carry flag
rotate carry flag into destination.
end-for
The high level language code for this is much more complicated, because C and C++ do not support rotating to carry and rotating from carry. The carry flag has to modeled.
Edit: Assembly language for example
; Enter with value to reverse in R0.
; Assume 8 bits per byte and byte is the native processor type.
LODI, R2 8 ; Set up the bit counter
Loop:
RRC, R0 ; Rotate R0 right into the carry bit.
RLC, R1 ; Rotate R1 left, then append carry bit.
DJNZ, R2 Loop ; Decrement R2 and jump if non-zero to "loop"
LODR, R0 R1 ; Move result into R0.
6
I think this answer is the opposite of simple. Non-portable, assembly, and complex enough to be written in pseudo-code instead of the actual assembly.
– deft_code
Apr 8 '10 at 20:59
3
It is quite simple. I put it into pseudo-code because assembly mnemonics are specific to a breed of processor and there are a lot of breeds out there. If you would like, I can edit this to show the simple assembly language.
– Thomas Matthews
Apr 9 '10 at 16:53
add a comment |
up vote
12
down vote
Although probably not portable, I would use assembly language.
Many assembly languages have instructions to rotate a bit into the carry flag and to rotate the carry flag into the word (or byte).
The algorithm is:
for each bit in the data type:
rotate bit into carry flag
rotate carry flag into destination.
end-for
The high level language code for this is much more complicated, because C and C++ do not support rotating to carry and rotating from carry. The carry flag has to modeled.
Edit: Assembly language for example
; Enter with value to reverse in R0.
; Assume 8 bits per byte and byte is the native processor type.
LODI, R2 8 ; Set up the bit counter
Loop:
RRC, R0 ; Rotate R0 right into the carry bit.
RLC, R1 ; Rotate R1 left, then append carry bit.
DJNZ, R2 Loop ; Decrement R2 and jump if non-zero to "loop"
LODR, R0 R1 ; Move result into R0.
6
I think this answer is the opposite of simple. Non-portable, assembly, and complex enough to be written in pseudo-code instead of the actual assembly.
– deft_code
Apr 8 '10 at 20:59
3
It is quite simple. I put it into pseudo-code because assembly mnemonics are specific to a breed of processor and there are a lot of breeds out there. If you would like, I can edit this to show the simple assembly language.
– Thomas Matthews
Apr 9 '10 at 16:53
add a comment |
up vote
12
down vote
up vote
12
down vote
Although probably not portable, I would use assembly language.
Many assembly languages have instructions to rotate a bit into the carry flag and to rotate the carry flag into the word (or byte).
The algorithm is:
for each bit in the data type:
rotate bit into carry flag
rotate carry flag into destination.
end-for
The high level language code for this is much more complicated, because C and C++ do not support rotating to carry and rotating from carry. The carry flag has to modeled.
Edit: Assembly language for example
; Enter with value to reverse in R0.
; Assume 8 bits per byte and byte is the native processor type.
LODI, R2 8 ; Set up the bit counter
Loop:
RRC, R0 ; Rotate R0 right into the carry bit.
RLC, R1 ; Rotate R1 left, then append carry bit.
DJNZ, R2 Loop ; Decrement R2 and jump if non-zero to "loop"
LODR, R0 R1 ; Move result into R0.
Although probably not portable, I would use assembly language.
Many assembly languages have instructions to rotate a bit into the carry flag and to rotate the carry flag into the word (or byte).
The algorithm is:
for each bit in the data type:
rotate bit into carry flag
rotate carry flag into destination.
end-for
The high level language code for this is much more complicated, because C and C++ do not support rotating to carry and rotating from carry. The carry flag has to modeled.
Edit: Assembly language for example
; Enter with value to reverse in R0.
; Assume 8 bits per byte and byte is the native processor type.
LODI, R2 8 ; Set up the bit counter
Loop:
RRC, R0 ; Rotate R0 right into the carry bit.
RLC, R1 ; Rotate R1 left, then append carry bit.
DJNZ, R2 Loop ; Decrement R2 and jump if non-zero to "loop"
LODR, R0 R1 ; Move result into R0.
edited Apr 9 '10 at 16:59
answered Apr 8 '10 at 19:46
Thomas Matthews
44k1169120
44k1169120
6
I think this answer is the opposite of simple. Non-portable, assembly, and complex enough to be written in pseudo-code instead of the actual assembly.
– deft_code
Apr 8 '10 at 20:59
3
It is quite simple. I put it into pseudo-code because assembly mnemonics are specific to a breed of processor and there are a lot of breeds out there. If you would like, I can edit this to show the simple assembly language.
– Thomas Matthews
Apr 9 '10 at 16:53
add a comment |
6
I think this answer is the opposite of simple. Non-portable, assembly, and complex enough to be written in pseudo-code instead of the actual assembly.
– deft_code
Apr 8 '10 at 20:59
3
It is quite simple. I put it into pseudo-code because assembly mnemonics are specific to a breed of processor and there are a lot of breeds out there. If you would like, I can edit this to show the simple assembly language.
– Thomas Matthews
Apr 9 '10 at 16:53
6
6
I think this answer is the opposite of simple. Non-portable, assembly, and complex enough to be written in pseudo-code instead of the actual assembly.
– deft_code
Apr 8 '10 at 20:59
I think this answer is the opposite of simple. Non-portable, assembly, and complex enough to be written in pseudo-code instead of the actual assembly.
– deft_code
Apr 8 '10 at 20:59
3
3
It is quite simple. I put it into pseudo-code because assembly mnemonics are specific to a breed of processor and there are a lot of breeds out there. If you would like, I can edit this to show the simple assembly language.
– Thomas Matthews
Apr 9 '10 at 16:53
It is quite simple. I put it into pseudo-code because assembly mnemonics are specific to a breed of processor and there are a lot of breeds out there. If you would like, I can edit this to show the simple assembly language.
– Thomas Matthews
Apr 9 '10 at 16:53
add a comment |
up vote
10
down vote
The simplest way is probably to iterate over the bit positions in a loop:
unsigned char reverse(unsigned char c) {
int shift;
unsigned char result = 0;
for (shift = 0; shift < CHAR_BIT; shift++) {
if (c & (0x01 << shift))
result |= (0x80 >> shift);
}
return result;
}
it's CHAR_BIT, without an 's'
– larkey
Jun 22 at 12:25
@larkey: you're right, thanks
– sth
Jun 22 at 18:43
add a comment |
up vote
10
down vote
The simplest way is probably to iterate over the bit positions in a loop:
unsigned char reverse(unsigned char c) {
int shift;
unsigned char result = 0;
for (shift = 0; shift < CHAR_BIT; shift++) {
if (c & (0x01 << shift))
result |= (0x80 >> shift);
}
return result;
}
it's CHAR_BIT, without an 's'
– larkey
Jun 22 at 12:25
@larkey: you're right, thanks
– sth
Jun 22 at 18:43
add a comment |
up vote
10
down vote
up vote
10
down vote
The simplest way is probably to iterate over the bit positions in a loop:
unsigned char reverse(unsigned char c) {
int shift;
unsigned char result = 0;
for (shift = 0; shift < CHAR_BIT; shift++) {
if (c & (0x01 << shift))
result |= (0x80 >> shift);
}
return result;
}
The simplest way is probably to iterate over the bit positions in a loop:
unsigned char reverse(unsigned char c) {
int shift;
unsigned char result = 0;
for (shift = 0; shift < CHAR_BIT; shift++) {
if (c & (0x01 << shift))
result |= (0x80 >> shift);
}
return result;
}
edited Jun 22 at 18:42
answered Apr 9 '10 at 1:13
sth
163k40240331
163k40240331
it's CHAR_BIT, without an 's'
– larkey
Jun 22 at 12:25
@larkey: you're right, thanks
– sth
Jun 22 at 18:43
add a comment |
it's CHAR_BIT, without an 's'
– larkey
Jun 22 at 12:25
@larkey: you're right, thanks
– sth
Jun 22 at 18:43
it's CHAR_BIT, without an 's'
– larkey
Jun 22 at 12:25
it's CHAR_BIT, without an 's'
– larkey
Jun 22 at 12:25
@larkey: you're right, thanks
– sth
Jun 22 at 18:43
@larkey: you're right, thanks
– sth
Jun 22 at 18:43
add a comment |
up vote
8
down vote
I find the following solution simpler than the other bit fiddling algorithms I've seen in here.
unsigned char reverse_byte(char a)
{
return ((a & 0x1) << 7) | ((a & 0x2) << 5) |
((a & 0x4) << 3) | ((a & 0x8) << 1) |
((a & 0x10) >> 1) | ((a & 0x20) >> 3) |
((a & 0x40) >> 5) | ((a & 0x80) >> 7);
}
It gets every bit in the byte, and shifts it accordingly, starting from the first to the last.
Explanation:
((a & 0x1) << 7) //get first bit on the right and shift it into the first left position
| ((a & 0x2) << 5) //add it to the second bit and shift it into the second left position
//and so on
Beautiful! My favorite so far.
– Nick Rameau
Nov 22 '16 at 8:15
1
thanks! I think simplicity is key in these scenario
– dau_sama
Nov 22 '16 at 9:11
add a comment |
up vote
8
down vote
I find the following solution simpler than the other bit fiddling algorithms I've seen in here.
unsigned char reverse_byte(char a)
{
return ((a & 0x1) << 7) | ((a & 0x2) << 5) |
((a & 0x4) << 3) | ((a & 0x8) << 1) |
((a & 0x10) >> 1) | ((a & 0x20) >> 3) |
((a & 0x40) >> 5) | ((a & 0x80) >> 7);
}
It gets every bit in the byte, and shifts it accordingly, starting from the first to the last.
Explanation:
((a & 0x1) << 7) //get first bit on the right and shift it into the first left position
| ((a & 0x2) << 5) //add it to the second bit and shift it into the second left position
//and so on
Beautiful! My favorite so far.
– Nick Rameau
Nov 22 '16 at 8:15
1
thanks! I think simplicity is key in these scenario
– dau_sama
Nov 22 '16 at 9:11
add a comment |
up vote
8
down vote
up vote
8
down vote
I find the following solution simpler than the other bit fiddling algorithms I've seen in here.
unsigned char reverse_byte(char a)
{
return ((a & 0x1) << 7) | ((a & 0x2) << 5) |
((a & 0x4) << 3) | ((a & 0x8) << 1) |
((a & 0x10) >> 1) | ((a & 0x20) >> 3) |
((a & 0x40) >> 5) | ((a & 0x80) >> 7);
}
It gets every bit in the byte, and shifts it accordingly, starting from the first to the last.
Explanation:
((a & 0x1) << 7) //get first bit on the right and shift it into the first left position
| ((a & 0x2) << 5) //add it to the second bit and shift it into the second left position
//and so on
I find the following solution simpler than the other bit fiddling algorithms I've seen in here.
unsigned char reverse_byte(char a)
{
return ((a & 0x1) << 7) | ((a & 0x2) << 5) |
((a & 0x4) << 3) | ((a & 0x8) << 1) |
((a & 0x10) >> 1) | ((a & 0x20) >> 3) |
((a & 0x40) >> 5) | ((a & 0x80) >> 7);
}
It gets every bit in the byte, and shifts it accordingly, starting from the first to the last.
Explanation:
((a & 0x1) << 7) //get first bit on the right and shift it into the first left position
| ((a & 0x2) << 5) //add it to the second bit and shift it into the second left position
//and so on
edited Jan 26 at 6:34
sallaben
93
93
answered May 2 '15 at 12:57
dau_sama
2,81211424
2,81211424
Beautiful! My favorite so far.
– Nick Rameau
Nov 22 '16 at 8:15
1
thanks! I think simplicity is key in these scenario
– dau_sama
Nov 22 '16 at 9:11
add a comment |
Beautiful! My favorite so far.
– Nick Rameau
Nov 22 '16 at 8:15
1
thanks! I think simplicity is key in these scenario
– dau_sama
Nov 22 '16 at 9:11
Beautiful! My favorite so far.
– Nick Rameau
Nov 22 '16 at 8:15
Beautiful! My favorite so far.
– Nick Rameau
Nov 22 '16 at 8:15
1
1
thanks! I think simplicity is key in these scenario
– dau_sama
Nov 22 '16 at 9:11
thanks! I think simplicity is key in these scenario
– dau_sama
Nov 22 '16 at 9:11
add a comment |
up vote
7
down vote
For constant, 8-bit input, this costs no memory or CPU at run-time:
#define MSB2LSB(b) (((b)&1?128:0)|((b)&2?64:0)|((b)&4?32:0)|((b)&8?16:0)|((b)&16?8:0)|((b)&32?4:0)|((b)&64?2:0)|((b)&128?1:0))
I used this for ARINC-429 where the bit order (endianness) of the label is opposite the rest of the word. The label is often a constant, and conventionally in octal. For example:
#define LABEL_HF_COMM MSB2LSB(0205)
add a comment |
up vote
7
down vote
For constant, 8-bit input, this costs no memory or CPU at run-time:
#define MSB2LSB(b) (((b)&1?128:0)|((b)&2?64:0)|((b)&4?32:0)|((b)&8?16:0)|((b)&16?8:0)|((b)&32?4:0)|((b)&64?2:0)|((b)&128?1:0))
I used this for ARINC-429 where the bit order (endianness) of the label is opposite the rest of the word. The label is often a constant, and conventionally in octal. For example:
#define LABEL_HF_COMM MSB2LSB(0205)
add a comment |
up vote
7
down vote
up vote
7
down vote
For constant, 8-bit input, this costs no memory or CPU at run-time:
#define MSB2LSB(b) (((b)&1?128:0)|((b)&2?64:0)|((b)&4?32:0)|((b)&8?16:0)|((b)&16?8:0)|((b)&32?4:0)|((b)&64?2:0)|((b)&128?1:0))
I used this for ARINC-429 where the bit order (endianness) of the label is opposite the rest of the word. The label is often a constant, and conventionally in octal. For example:
#define LABEL_HF_COMM MSB2LSB(0205)
For constant, 8-bit input, this costs no memory or CPU at run-time:
#define MSB2LSB(b) (((b)&1?128:0)|((b)&2?64:0)|((b)&4?32:0)|((b)&8?16:0)|((b)&16?8:0)|((b)&32?4:0)|((b)&64?2:0)|((b)&128?1:0))
I used this for ARINC-429 where the bit order (endianness) of the label is opposite the rest of the word. The label is often a constant, and conventionally in octal. For example:
#define LABEL_HF_COMM MSB2LSB(0205)
edited Dec 7 '16 at 17:38
answered Jun 18 '14 at 0:43
Bob Stein
6,66334971
6,66334971
add a comment |
add a comment |
up vote
6
down vote
You may be interested in std::vector<bool>
(that is bit-packed) and std::bitset
It should be the simplest as requested.
#include <iostream>
#include <bitset>
using namespace std;
int main() {
bitset<8> bs = 5;
bitset<8> rev;
for(int ii=0; ii!= bs.size(); ++ii)
rev[bs.size()-ii-1] = bs[ii];
cerr << bs << " " << rev << endl;
}
Other options may be faster.
EDIT: I owe you a solution using std::vector<bool>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<bool> b{0,0,0,0,0,1,0,1};
reverse(b.begin(), b.end());
copy(b.begin(), b.end(), ostream_iterator<int>(cerr));
cerr << endl;
}
The second example requires c++0x extension (to initialize the array with {...}
). The advantage of using a bitset
or a std::vector<bool>
(or a boost::dynamic_bitset
) is that you are not limited to bytes or words but can reverse an arbitrary number of bits.
HTH
How is bitset any simpler than a pod here? Show the code, or it isn't.
– wilhelmtell
Apr 8 '10 at 19:53
Actu ally, I think that code will reverse the bitset, and then reverse it back to its original. Change ii != size(); to ii < size()/2; and it'll do a better job =)
– Viktor Sehr
Apr 8 '10 at 19:58
(@viktor-sehr no, it will not, rev is different from bs). Anyway I don't like the answer myself: I think this is a case where binary arithmetic and shift operators are better suited. It still remains the simplest to understand.
– baol
Apr 8 '10 at 20:07
ah, youre right, sorry
– Viktor Sehr
Apr 9 '10 at 7:26
How aboutstd::vector<bool> b = { ... }; std::vector<bool> rb ( b.rbegin(), b.rend());
- using reverse iterators directly?
– MSalters
Aug 30 '17 at 21:19
|
show 1 more comment
up vote
6
down vote
You may be interested in std::vector<bool>
(that is bit-packed) and std::bitset
It should be the simplest as requested.
#include <iostream>
#include <bitset>
using namespace std;
int main() {
bitset<8> bs = 5;
bitset<8> rev;
for(int ii=0; ii!= bs.size(); ++ii)
rev[bs.size()-ii-1] = bs[ii];
cerr << bs << " " << rev << endl;
}
Other options may be faster.
EDIT: I owe you a solution using std::vector<bool>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<bool> b{0,0,0,0,0,1,0,1};
reverse(b.begin(), b.end());
copy(b.begin(), b.end(), ostream_iterator<int>(cerr));
cerr << endl;
}
The second example requires c++0x extension (to initialize the array with {...}
). The advantage of using a bitset
or a std::vector<bool>
(or a boost::dynamic_bitset
) is that you are not limited to bytes or words but can reverse an arbitrary number of bits.
HTH
How is bitset any simpler than a pod here? Show the code, or it isn't.
– wilhelmtell
Apr 8 '10 at 19:53
Actu ally, I think that code will reverse the bitset, and then reverse it back to its original. Change ii != size(); to ii < size()/2; and it'll do a better job =)
– Viktor Sehr
Apr 8 '10 at 19:58
(@viktor-sehr no, it will not, rev is different from bs). Anyway I don't like the answer myself: I think this is a case where binary arithmetic and shift operators are better suited. It still remains the simplest to understand.
– baol
Apr 8 '10 at 20:07
ah, youre right, sorry
– Viktor Sehr
Apr 9 '10 at 7:26
How aboutstd::vector<bool> b = { ... }; std::vector<bool> rb ( b.rbegin(), b.rend());
- using reverse iterators directly?
– MSalters
Aug 30 '17 at 21:19
|
show 1 more comment
up vote
6
down vote
up vote
6
down vote
You may be interested in std::vector<bool>
(that is bit-packed) and std::bitset
It should be the simplest as requested.
#include <iostream>
#include <bitset>
using namespace std;
int main() {
bitset<8> bs = 5;
bitset<8> rev;
for(int ii=0; ii!= bs.size(); ++ii)
rev[bs.size()-ii-1] = bs[ii];
cerr << bs << " " << rev << endl;
}
Other options may be faster.
EDIT: I owe you a solution using std::vector<bool>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<bool> b{0,0,0,0,0,1,0,1};
reverse(b.begin(), b.end());
copy(b.begin(), b.end(), ostream_iterator<int>(cerr));
cerr << endl;
}
The second example requires c++0x extension (to initialize the array with {...}
). The advantage of using a bitset
or a std::vector<bool>
(or a boost::dynamic_bitset
) is that you are not limited to bytes or words but can reverse an arbitrary number of bits.
HTH
You may be interested in std::vector<bool>
(that is bit-packed) and std::bitset
It should be the simplest as requested.
#include <iostream>
#include <bitset>
using namespace std;
int main() {
bitset<8> bs = 5;
bitset<8> rev;
for(int ii=0; ii!= bs.size(); ++ii)
rev[bs.size()-ii-1] = bs[ii];
cerr << bs << " " << rev << endl;
}
Other options may be faster.
EDIT: I owe you a solution using std::vector<bool>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<bool> b{0,0,0,0,0,1,0,1};
reverse(b.begin(), b.end());
copy(b.begin(), b.end(), ostream_iterator<int>(cerr));
cerr << endl;
}
The second example requires c++0x extension (to initialize the array with {...}
). The advantage of using a bitset
or a std::vector<bool>
(or a boost::dynamic_bitset
) is that you are not limited to bytes or words but can reverse an arbitrary number of bits.
HTH
edited Apr 8 '10 at 20:29
answered Apr 8 '10 at 19:37
baol
3,5222442
3,5222442
How is bitset any simpler than a pod here? Show the code, or it isn't.
– wilhelmtell
Apr 8 '10 at 19:53
Actu ally, I think that code will reverse the bitset, and then reverse it back to its original. Change ii != size(); to ii < size()/2; and it'll do a better job =)
– Viktor Sehr
Apr 8 '10 at 19:58
(@viktor-sehr no, it will not, rev is different from bs). Anyway I don't like the answer myself: I think this is a case where binary arithmetic and shift operators are better suited. It still remains the simplest to understand.
– baol
Apr 8 '10 at 20:07
ah, youre right, sorry
– Viktor Sehr
Apr 9 '10 at 7:26
How aboutstd::vector<bool> b = { ... }; std::vector<bool> rb ( b.rbegin(), b.rend());
- using reverse iterators directly?
– MSalters
Aug 30 '17 at 21:19
|
show 1 more comment
How is bitset any simpler than a pod here? Show the code, or it isn't.
– wilhelmtell
Apr 8 '10 at 19:53
Actu ally, I think that code will reverse the bitset, and then reverse it back to its original. Change ii != size(); to ii < size()/2; and it'll do a better job =)
– Viktor Sehr
Apr 8 '10 at 19:58
(@viktor-sehr no, it will not, rev is different from bs). Anyway I don't like the answer myself: I think this is a case where binary arithmetic and shift operators are better suited. It still remains the simplest to understand.
– baol
Apr 8 '10 at 20:07
ah, youre right, sorry
– Viktor Sehr
Apr 9 '10 at 7:26
How aboutstd::vector<bool> b = { ... }; std::vector<bool> rb ( b.rbegin(), b.rend());
- using reverse iterators directly?
– MSalters
Aug 30 '17 at 21:19
How is bitset any simpler than a pod here? Show the code, or it isn't.
– wilhelmtell
Apr 8 '10 at 19:53
How is bitset any simpler than a pod here? Show the code, or it isn't.
– wilhelmtell
Apr 8 '10 at 19:53
Actu ally, I think that code will reverse the bitset, and then reverse it back to its original. Change ii != size(); to ii < size()/2; and it'll do a better job =)
– Viktor Sehr
Apr 8 '10 at 19:58
Actu ally, I think that code will reverse the bitset, and then reverse it back to its original. Change ii != size(); to ii < size()/2; and it'll do a better job =)
– Viktor Sehr
Apr 8 '10 at 19:58
(@viktor-sehr no, it will not, rev is different from bs). Anyway I don't like the answer myself: I think this is a case where binary arithmetic and shift operators are better suited. It still remains the simplest to understand.
– baol
Apr 8 '10 at 20:07
(@viktor-sehr no, it will not, rev is different from bs). Anyway I don't like the answer myself: I think this is a case where binary arithmetic and shift operators are better suited. It still remains the simplest to understand.
– baol
Apr 8 '10 at 20:07
ah, youre right, sorry
– Viktor Sehr
Apr 9 '10 at 7:26
ah, youre right, sorry
– Viktor Sehr
Apr 9 '10 at 7:26
How about
std::vector<bool> b = { ... }; std::vector<bool> rb ( b.rbegin(), b.rend());
- using reverse iterators directly?– MSalters
Aug 30 '17 at 21:19
How about
std::vector<bool> b = { ... }; std::vector<bool> rb ( b.rbegin(), b.rend());
- using reverse iterators directly?– MSalters
Aug 30 '17 at 21:19
|
show 1 more comment
up vote
3
down vote
Table lookup or
uint8_t rev_byte(uint8_t x) {
uint8_t y;
uint8_t m = 1;
while (m) {
y >>= 1;
if (m&x) {
y |= 0x80;
}
m <<=1;
}
return y;
}
edit
Look here for other solutions that might work better for you
add a comment |
up vote
3
down vote
Table lookup or
uint8_t rev_byte(uint8_t x) {
uint8_t y;
uint8_t m = 1;
while (m) {
y >>= 1;
if (m&x) {
y |= 0x80;
}
m <<=1;
}
return y;
}
edit
Look here for other solutions that might work better for you
add a comment |
up vote
3
down vote
up vote
3
down vote
Table lookup or
uint8_t rev_byte(uint8_t x) {
uint8_t y;
uint8_t m = 1;
while (m) {
y >>= 1;
if (m&x) {
y |= 0x80;
}
m <<=1;
}
return y;
}
edit
Look here for other solutions that might work better for you
Table lookup or
uint8_t rev_byte(uint8_t x) {
uint8_t y;
uint8_t m = 1;
while (m) {
y >>= 1;
if (m&x) {
y |= 0x80;
}
m <<=1;
}
return y;
}
edit
Look here for other solutions that might work better for you
answered Apr 8 '10 at 19:39
nategoose
10.5k2134
10.5k2134
add a comment |
add a comment |
up vote
2
down vote
Before implementing any algorithmic solution, check the assembly language for whatever CPU architecture you are using. Your architecture may include instructions which handle bitwise manipulations like this (and what could be simpler than a single assembly instruction?).
If such an instruction is not available, then I would suggest going with the lookup table route. You can write a script/program to generate the table for you, and the lookup operations would be faster than any of the bit-reversing algorithms here (at the cost of having to store the lookup table somewhere).
add a comment |
up vote
2
down vote
Before implementing any algorithmic solution, check the assembly language for whatever CPU architecture you are using. Your architecture may include instructions which handle bitwise manipulations like this (and what could be simpler than a single assembly instruction?).
If such an instruction is not available, then I would suggest going with the lookup table route. You can write a script/program to generate the table for you, and the lookup operations would be faster than any of the bit-reversing algorithms here (at the cost of having to store the lookup table somewhere).
add a comment |
up vote
2
down vote
up vote
2
down vote
Before implementing any algorithmic solution, check the assembly language for whatever CPU architecture you are using. Your architecture may include instructions which handle bitwise manipulations like this (and what could be simpler than a single assembly instruction?).
If such an instruction is not available, then I would suggest going with the lookup table route. You can write a script/program to generate the table for you, and the lookup operations would be faster than any of the bit-reversing algorithms here (at the cost of having to store the lookup table somewhere).
Before implementing any algorithmic solution, check the assembly language for whatever CPU architecture you are using. Your architecture may include instructions which handle bitwise manipulations like this (and what could be simpler than a single assembly instruction?).
If such an instruction is not available, then I would suggest going with the lookup table route. You can write a script/program to generate the table for you, and the lookup operations would be faster than any of the bit-reversing algorithms here (at the cost of having to store the lookup table somewhere).
answered Apr 8 '10 at 21:03
bta
34.6k45484
34.6k45484
add a comment |
add a comment |
up vote
2
down vote
a slower but simpler implementation:
static int swap_bit(unsigned char unit)
{
/*
* swap bit[7] and bit[0]
*/
unit = (((((unit & 0x80) >> 7) ^ (unit & 0x01)) << 7) | (unit & 0x7f));
unit = (((((unit & 0x80) >> 7) ^ (unit & 0x01))) | (unit & 0xfe));
unit = (((((unit & 0x80) >> 7) ^ (unit & 0x01)) << 7) | (unit & 0x7f));
/*
* swap bit[6] and bit[1]
*/
unit = (((((unit & 0x40) >> 5) ^ (unit & 0x02)) << 5) | (unit & 0xbf));
unit = (((((unit & 0x40) >> 5) ^ (unit & 0x02))) | (unit & 0xfd));
unit = (((((unit & 0x40) >> 5) ^ (unit & 0x02)) << 5) | (unit & 0xbf));
/*
* swap bit[5] and bit[2]
*/
unit = (((((unit & 0x20) >> 3) ^ (unit & 0x04)) << 3) | (unit & 0xdf));
unit = (((((unit & 0x20) >> 3) ^ (unit & 0x04))) | (unit & 0xfb));
unit = (((((unit & 0x20) >> 3) ^ (unit & 0x04)) << 3) | (unit & 0xdf));
/*
* swap bit[4] and bit[3]
*/
unit = (((((unit & 0x10) >> 1) ^ (unit & 0x08)) << 1) | (unit & 0xef));
unit = (((((unit & 0x10) >> 1) ^ (unit & 0x08))) | (unit & 0xf7));
unit = (((((unit & 0x10) >> 1) ^ (unit & 0x08)) << 1) | (unit & 0xef));
return unit;
}
add a comment |
up vote
2
down vote
a slower but simpler implementation:
static int swap_bit(unsigned char unit)
{
/*
* swap bit[7] and bit[0]
*/
unit = (((((unit & 0x80) >> 7) ^ (unit & 0x01)) << 7) | (unit & 0x7f));
unit = (((((unit & 0x80) >> 7) ^ (unit & 0x01))) | (unit & 0xfe));
unit = (((((unit & 0x80) >> 7) ^ (unit & 0x01)) << 7) | (unit & 0x7f));
/*
* swap bit[6] and bit[1]
*/
unit = (((((unit & 0x40) >> 5) ^ (unit & 0x02)) << 5) | (unit & 0xbf));
unit = (((((unit & 0x40) >> 5) ^ (unit & 0x02))) | (unit & 0xfd));
unit = (((((unit & 0x40) >> 5) ^ (unit & 0x02)) << 5) | (unit & 0xbf));
/*
* swap bit[5] and bit[2]
*/
unit = (((((unit & 0x20) >> 3) ^ (unit & 0x04)) << 3) | (unit & 0xdf));
unit = (((((unit & 0x20) >> 3) ^ (unit & 0x04))) | (unit & 0xfb));
unit = (((((unit & 0x20) >> 3) ^ (unit & 0x04)) << 3) | (unit & 0xdf));
/*
* swap bit[4] and bit[3]
*/
unit = (((((unit & 0x10) >> 1) ^ (unit & 0x08)) << 1) | (unit & 0xef));
unit = (((((unit & 0x10) >> 1) ^ (unit & 0x08))) | (unit & 0xf7));
unit = (((((unit & 0x10) >> 1) ^ (unit & 0x08)) << 1) | (unit & 0xef));
return unit;
}
add a comment |
up vote
2
down vote
up vote
2
down vote
a slower but simpler implementation:
static int swap_bit(unsigned char unit)
{
/*
* swap bit[7] and bit[0]
*/
unit = (((((unit & 0x80) >> 7) ^ (unit & 0x01)) << 7) | (unit & 0x7f));
unit = (((((unit & 0x80) >> 7) ^ (unit & 0x01))) | (unit & 0xfe));
unit = (((((unit & 0x80) >> 7) ^ (unit & 0x01)) << 7) | (unit & 0x7f));
/*
* swap bit[6] and bit[1]
*/
unit = (((((unit & 0x40) >> 5) ^ (unit & 0x02)) << 5) | (unit & 0xbf));
unit = (((((unit & 0x40) >> 5) ^ (unit & 0x02))) | (unit & 0xfd));
unit = (((((unit & 0x40) >> 5) ^ (unit & 0x02)) << 5) | (unit & 0xbf));
/*
* swap bit[5] and bit[2]
*/
unit = (((((unit & 0x20) >> 3) ^ (unit & 0x04)) << 3) | (unit & 0xdf));
unit = (((((unit & 0x20) >> 3) ^ (unit & 0x04))) | (unit & 0xfb));
unit = (((((unit & 0x20) >> 3) ^ (unit & 0x04)) << 3) | (unit & 0xdf));
/*
* swap bit[4] and bit[3]
*/
unit = (((((unit & 0x10) >> 1) ^ (unit & 0x08)) << 1) | (unit & 0xef));
unit = (((((unit & 0x10) >> 1) ^ (unit & 0x08))) | (unit & 0xf7));
unit = (((((unit & 0x10) >> 1) ^ (unit & 0x08)) << 1) | (unit & 0xef));
return unit;
}
a slower but simpler implementation:
static int swap_bit(unsigned char unit)
{
/*
* swap bit[7] and bit[0]
*/
unit = (((((unit & 0x80) >> 7) ^ (unit & 0x01)) << 7) | (unit & 0x7f));
unit = (((((unit & 0x80) >> 7) ^ (unit & 0x01))) | (unit & 0xfe));
unit = (((((unit & 0x80) >> 7) ^ (unit & 0x01)) << 7) | (unit & 0x7f));
/*
* swap bit[6] and bit[1]
*/
unit = (((((unit & 0x40) >> 5) ^ (unit & 0x02)) << 5) | (unit & 0xbf));
unit = (((((unit & 0x40) >> 5) ^ (unit & 0x02))) | (unit & 0xfd));
unit = (((((unit & 0x40) >> 5) ^ (unit & 0x02)) << 5) | (unit & 0xbf));
/*
* swap bit[5] and bit[2]
*/
unit = (((((unit & 0x20) >> 3) ^ (unit & 0x04)) << 3) | (unit & 0xdf));
unit = (((((unit & 0x20) >> 3) ^ (unit & 0x04))) | (unit & 0xfb));
unit = (((((unit & 0x20) >> 3) ^ (unit & 0x04)) << 3) | (unit & 0xdf));
/*
* swap bit[4] and bit[3]
*/
unit = (((((unit & 0x10) >> 1) ^ (unit & 0x08)) << 1) | (unit & 0xef));
unit = (((((unit & 0x10) >> 1) ^ (unit & 0x08))) | (unit & 0xf7));
unit = (((((unit & 0x10) >> 1) ^ (unit & 0x08)) << 1) | (unit & 0xef));
return unit;
}
answered Apr 9 '10 at 7:03
wenlujon
425516
425516
add a comment |
add a comment |
up vote
2
down vote
Can this be fast solution?
int byte_to_be_reversed =
((byte_to_be_reversed>>7)&0x01)|((byte_to_be_reversed>>5)&0x02)|
((byte_to_be_reversed>>3)&0x04)|((byte_to_be_reversed>>1)&0x08)|
((byte_to_be_reversed<<7)&0x80)|((byte_to_be_reversed<<5)&0x40)|
((byte_to_be_reversed<<3)&0x20)|((byte_to_be_reversed<<1)&0x10);
Gets rid of the hustle of using a for loop! but experts please tell me if this is efficient and faster?
add a comment |
up vote
2
down vote
Can this be fast solution?
int byte_to_be_reversed =
((byte_to_be_reversed>>7)&0x01)|((byte_to_be_reversed>>5)&0x02)|
((byte_to_be_reversed>>3)&0x04)|((byte_to_be_reversed>>1)&0x08)|
((byte_to_be_reversed<<7)&0x80)|((byte_to_be_reversed<<5)&0x40)|
((byte_to_be_reversed<<3)&0x20)|((byte_to_be_reversed<<1)&0x10);
Gets rid of the hustle of using a for loop! but experts please tell me if this is efficient and faster?
add a comment |
up vote
2
down vote
up vote
2
down vote
Can this be fast solution?
int byte_to_be_reversed =
((byte_to_be_reversed>>7)&0x01)|((byte_to_be_reversed>>5)&0x02)|
((byte_to_be_reversed>>3)&0x04)|((byte_to_be_reversed>>1)&0x08)|
((byte_to_be_reversed<<7)&0x80)|((byte_to_be_reversed<<5)&0x40)|
((byte_to_be_reversed<<3)&0x20)|((byte_to_be_reversed<<1)&0x10);
Gets rid of the hustle of using a for loop! but experts please tell me if this is efficient and faster?
Can this be fast solution?
int byte_to_be_reversed =
((byte_to_be_reversed>>7)&0x01)|((byte_to_be_reversed>>5)&0x02)|
((byte_to_be_reversed>>3)&0x04)|((byte_to_be_reversed>>1)&0x08)|
((byte_to_be_reversed<<7)&0x80)|((byte_to_be_reversed<<5)&0x40)|
((byte_to_be_reversed<<3)&0x20)|((byte_to_be_reversed<<1)&0x10);
Gets rid of the hustle of using a for loop! but experts please tell me if this is efficient and faster?
edited Jun 17 '14 at 13:17
answered May 6 '14 at 17:18
Jamboree
212
212
add a comment |
add a comment |
up vote
2
down vote
This simple function uses a mask to test each bit in the input byte and transfer it into a shifting output:
char Reverse_Bits(char input)
{
char output = 0;
for (unsigned char mask = 1; mask > 0; mask <<= 1)
{
output <<= 1;
if (input & mask)
output |= 1;
}
return output;
}
Mask should be unsigned sorry.
– luci88filter
Feb 17 at 8:45
add a comment |
up vote
2
down vote
This simple function uses a mask to test each bit in the input byte and transfer it into a shifting output:
char Reverse_Bits(char input)
{
char output = 0;
for (unsigned char mask = 1; mask > 0; mask <<= 1)
{
output <<= 1;
if (input & mask)
output |= 1;
}
return output;
}
Mask should be unsigned sorry.
– luci88filter
Feb 17 at 8:45
add a comment |
up vote
2
down vote
up vote
2
down vote
This simple function uses a mask to test each bit in the input byte and transfer it into a shifting output:
char Reverse_Bits(char input)
{
char output = 0;
for (unsigned char mask = 1; mask > 0; mask <<= 1)
{
output <<= 1;
if (input & mask)
output |= 1;
}
return output;
}
This simple function uses a mask to test each bit in the input byte and transfer it into a shifting output:
char Reverse_Bits(char input)
{
char output = 0;
for (unsigned char mask = 1; mask > 0; mask <<= 1)
{
output <<= 1;
if (input & mask)
output |= 1;
}
return output;
}
edited Feb 17 at 8:44
answered Feb 17 at 5:47
luci88filter
787
787
Mask should be unsigned sorry.
– luci88filter
Feb 17 at 8:45
add a comment |
Mask should be unsigned sorry.
– luci88filter
Feb 17 at 8:45
Mask should be unsigned sorry.
– luci88filter
Feb 17 at 8:45
Mask should be unsigned sorry.
– luci88filter
Feb 17 at 8:45
add a comment |
up vote
1
down vote
This one is based on the one BobStein-VisiBone provided
#define reverse_1byte(b) ( ((uint8_t)b & 0b00000001) ? 0b10000000 : 0 ) |
( ((uint8_t)b & 0b00000010) ? 0b01000000 : 0 ) |
( ((uint8_t)b & 0b00000100) ? 0b00100000 : 0 ) |
( ((uint8_t)b & 0b00001000) ? 0b00010000 : 0 ) |
( ((uint8_t)b & 0b00010000) ? 0b00001000 : 0 ) |
( ((uint8_t)b & 0b00100000) ? 0b00000100 : 0 ) |
( ((uint8_t)b & 0b01000000) ? 0b00000010 : 0 ) |
( ((uint8_t)b & 0b10000000) ? 0b00000001 : 0 )
I really like this one a lot because the compiler automatically handle the work for you, thus require no further resources.
this can also be extended to 16-Bits...
#define reverse_2byte(b) ( ((uint16_t)b & 0b0000000000000001) ? 0b1000000000000000 : 0 ) |
( ((uint16_t)b & 0b0000000000000010) ? 0b0100000000000000 : 0 ) |
( ((uint16_t)b & 0b0000000000000100) ? 0b0010000000000000 : 0 ) |
( ((uint16_t)b & 0b0000000000001000) ? 0b0001000000000000 : 0 ) |
( ((uint16_t)b & 0b0000000000010000) ? 0b0000100000000000 : 0 ) |
( ((uint16_t)b & 0b0000000000100000) ? 0b0000010000000000 : 0 ) |
( ((uint16_t)b & 0b0000000001000000) ? 0b0000001000000000 : 0 ) |
( ((uint16_t)b & 0b0000000010000000) ? 0b0000000100000000 : 0 ) |
( ((uint16_t)b & 0b0000000100000000) ? 0b0000000010000000 : 0 ) |
( ((uint16_t)b & 0b0000001000000000) ? 0b0000000001000000 : 0 ) |
( ((uint16_t)b & 0b0000010000000000) ? 0b0000000000100000 : 0 ) |
( ((uint16_t)b & 0b0000100000000000) ? 0b0000000000010000 : 0 ) |
( ((uint16_t)b & 0b0001000000000000) ? 0b0000000000001000 : 0 ) |
( ((uint16_t)b & 0b0010000000000000) ? 0b0000000000000100 : 0 ) |
( ((uint16_t)b & 0b0100000000000000) ? 0b0000000000000010 : 0 ) |
( ((uint16_t)b & 0b1000000000000000) ? 0b0000000000000001 : 0 )
I would put theb
in parentheses in case it is a more complex expression than a single number, and perhaps also rename the macro toREVERSE_BYTE
as a hint that you probably don't want to have a more complex (runtime) expression there. Or make it an inline function. (But overall I like this as being simple enough that you could do it from memory easily with very little chance of error.)
– Arkku
Aug 8 at 14:55
add a comment |
up vote
1
down vote
This one is based on the one BobStein-VisiBone provided
#define reverse_1byte(b) ( ((uint8_t)b & 0b00000001) ? 0b10000000 : 0 ) |
( ((uint8_t)b & 0b00000010) ? 0b01000000 : 0 ) |
( ((uint8_t)b & 0b00000100) ? 0b00100000 : 0 ) |
( ((uint8_t)b & 0b00001000) ? 0b00010000 : 0 ) |
( ((uint8_t)b & 0b00010000) ? 0b00001000 : 0 ) |
( ((uint8_t)b & 0b00100000) ? 0b00000100 : 0 ) |
( ((uint8_t)b & 0b01000000) ? 0b00000010 : 0 ) |
( ((uint8_t)b & 0b10000000) ? 0b00000001 : 0 )
I really like this one a lot because the compiler automatically handle the work for you, thus require no further resources.
this can also be extended to 16-Bits...
#define reverse_2byte(b) ( ((uint16_t)b & 0b0000000000000001) ? 0b1000000000000000 : 0 ) |
( ((uint16_t)b & 0b0000000000000010) ? 0b0100000000000000 : 0 ) |
( ((uint16_t)b & 0b0000000000000100) ? 0b0010000000000000 : 0 ) |
( ((uint16_t)b & 0b0000000000001000) ? 0b0001000000000000 : 0 ) |
( ((uint16_t)b & 0b0000000000010000) ? 0b0000100000000000 : 0 ) |
( ((uint16_t)b & 0b0000000000100000) ? 0b0000010000000000 : 0 ) |
( ((uint16_t)b & 0b0000000001000000) ? 0b0000001000000000 : 0 ) |
( ((uint16_t)b & 0b0000000010000000) ? 0b0000000100000000 : 0 ) |
( ((uint16_t)b & 0b0000000100000000) ? 0b0000000010000000 : 0 ) |
( ((uint16_t)b & 0b0000001000000000) ? 0b0000000001000000 : 0 ) |
( ((uint16_t)b & 0b0000010000000000) ? 0b0000000000100000 : 0 ) |
( ((uint16_t)b & 0b0000100000000000) ? 0b0000000000010000 : 0 ) |
( ((uint16_t)b & 0b0001000000000000) ? 0b0000000000001000 : 0 ) |
( ((uint16_t)b & 0b0010000000000000) ? 0b0000000000000100 : 0 ) |
( ((uint16_t)b & 0b0100000000000000) ? 0b0000000000000010 : 0 ) |
( ((uint16_t)b & 0b1000000000000000) ? 0b0000000000000001 : 0 )
I would put theb
in parentheses in case it is a more complex expression than a single number, and perhaps also rename the macro toREVERSE_BYTE
as a hint that you probably don't want to have a more complex (runtime) expression there. Or make it an inline function. (But overall I like this as being simple enough that you could do it from memory easily with very little chance of error.)
– Arkku
Aug 8 at 14:55
add a comment |
up vote
1
down vote
up vote
1
down vote
This one is based on the one BobStein-VisiBone provided
#define reverse_1byte(b) ( ((uint8_t)b & 0b00000001) ? 0b10000000 : 0 ) |
( ((uint8_t)b & 0b00000010) ? 0b01000000 : 0 ) |
( ((uint8_t)b & 0b00000100) ? 0b00100000 : 0 ) |
( ((uint8_t)b & 0b00001000) ? 0b00010000 : 0 ) |
( ((uint8_t)b & 0b00010000) ? 0b00001000 : 0 ) |
( ((uint8_t)b & 0b00100000) ? 0b00000100 : 0 ) |
( ((uint8_t)b & 0b01000000) ? 0b00000010 : 0 ) |
( ((uint8_t)b & 0b10000000) ? 0b00000001 : 0 )
I really like this one a lot because the compiler automatically handle the work for you, thus require no further resources.
this can also be extended to 16-Bits...
#define reverse_2byte(b) ( ((uint16_t)b & 0b0000000000000001) ? 0b1000000000000000 : 0 ) |
( ((uint16_t)b & 0b0000000000000010) ? 0b0100000000000000 : 0 ) |
( ((uint16_t)b & 0b0000000000000100) ? 0b0010000000000000 : 0 ) |
( ((uint16_t)b & 0b0000000000001000) ? 0b0001000000000000 : 0 ) |
( ((uint16_t)b & 0b0000000000010000) ? 0b0000100000000000 : 0 ) |
( ((uint16_t)b & 0b0000000000100000) ? 0b0000010000000000 : 0 ) |
( ((uint16_t)b & 0b0000000001000000) ? 0b0000001000000000 : 0 ) |
( ((uint16_t)b & 0b0000000010000000) ? 0b0000000100000000 : 0 ) |
( ((uint16_t)b & 0b0000000100000000) ? 0b0000000010000000 : 0 ) |
( ((uint16_t)b & 0b0000001000000000) ? 0b0000000001000000 : 0 ) |
( ((uint16_t)b & 0b0000010000000000) ? 0b0000000000100000 : 0 ) |
( ((uint16_t)b & 0b0000100000000000) ? 0b0000000000010000 : 0 ) |
( ((uint16_t)b & 0b0001000000000000) ? 0b0000000000001000 : 0 ) |
( ((uint16_t)b & 0b0010000000000000) ? 0b0000000000000100 : 0 ) |
( ((uint16_t)b & 0b0100000000000000) ? 0b0000000000000010 : 0 ) |
( ((uint16_t)b & 0b1000000000000000) ? 0b0000000000000001 : 0 )
This one is based on the one BobStein-VisiBone provided
#define reverse_1byte(b) ( ((uint8_t)b & 0b00000001) ? 0b10000000 : 0 ) |
( ((uint8_t)b & 0b00000010) ? 0b01000000 : 0 ) |
( ((uint8_t)b & 0b00000100) ? 0b00100000 : 0 ) |
( ((uint8_t)b & 0b00001000) ? 0b00010000 : 0 ) |
( ((uint8_t)b & 0b00010000) ? 0b00001000 : 0 ) |
( ((uint8_t)b & 0b00100000) ? 0b00000100 : 0 ) |
( ((uint8_t)b & 0b01000000) ? 0b00000010 : 0 ) |
( ((uint8_t)b & 0b10000000) ? 0b00000001 : 0 )
I really like this one a lot because the compiler automatically handle the work for you, thus require no further resources.
this can also be extended to 16-Bits...
#define reverse_2byte(b) ( ((uint16_t)b & 0b0000000000000001) ? 0b1000000000000000 : 0 ) |
( ((uint16_t)b & 0b0000000000000010) ? 0b0100000000000000 : 0 ) |
( ((uint16_t)b & 0b0000000000000100) ? 0b0010000000000000 : 0 ) |
( ((uint16_t)b & 0b0000000000001000) ? 0b0001000000000000 : 0 ) |
( ((uint16_t)b & 0b0000000000010000) ? 0b0000100000000000 : 0 ) |
( ((uint16_t)b & 0b0000000000100000) ? 0b0000010000000000 : 0 ) |
( ((uint16_t)b & 0b0000000001000000) ? 0b0000001000000000 : 0 ) |
( ((uint16_t)b & 0b0000000010000000) ? 0b0000000100000000 : 0 ) |
( ((uint16_t)b & 0b0000000100000000) ? 0b0000000010000000 : 0 ) |
( ((uint16_t)b & 0b0000001000000000) ? 0b0000000001000000 : 0 ) |
( ((uint16_t)b & 0b0000010000000000) ? 0b0000000000100000 : 0 ) |
( ((uint16_t)b & 0b0000100000000000) ? 0b0000000000010000 : 0 ) |
( ((uint16_t)b & 0b0001000000000000) ? 0b0000000000001000 : 0 ) |
( ((uint16_t)b & 0b0010000000000000) ? 0b0000000000000100 : 0 ) |
( ((uint16_t)b & 0b0100000000000000) ? 0b0000000000000010 : 0 ) |
( ((uint16_t)b & 0b1000000000000000) ? 0b0000000000000001 : 0 )
edited May 23 '17 at 12:02
Community♦
11
11
answered Feb 28 '17 at 22:31
Natthapol Vanasrivilai
6318
6318
I would put theb
in parentheses in case it is a more complex expression than a single number, and perhaps also rename the macro toREVERSE_BYTE
as a hint that you probably don't want to have a more complex (runtime) expression there. Or make it an inline function. (But overall I like this as being simple enough that you could do it from memory easily with very little chance of error.)
– Arkku
Aug 8 at 14:55
add a comment |
I would put theb
in parentheses in case it is a more complex expression than a single number, and perhaps also rename the macro toREVERSE_BYTE
as a hint that you probably don't want to have a more complex (runtime) expression there. Or make it an inline function. (But overall I like this as being simple enough that you could do it from memory easily with very little chance of error.)
– Arkku
Aug 8 at 14:55
I would put the
b
in parentheses in case it is a more complex expression than a single number, and perhaps also rename the macro to REVERSE_BYTE
as a hint that you probably don't want to have a more complex (runtime) expression there. Or make it an inline function. (But overall I like this as being simple enough that you could do it from memory easily with very little chance of error.)– Arkku
Aug 8 at 14:55
I would put the
b
in parentheses in case it is a more complex expression than a single number, and perhaps also rename the macro to REVERSE_BYTE
as a hint that you probably don't want to have a more complex (runtime) expression there. Or make it an inline function. (But overall I like this as being simple enough that you could do it from memory easily with very little chance of error.)– Arkku
Aug 8 at 14:55
add a comment |
up vote
0
down vote
typedef struct
{
uint8_t b0:1;
uint8_t b1:1;
uint8_t b2:1;
uint8_t b3:1;
uint8_t b4:1;
uint8_t b5:1;
uint8_t b6:1;
uint8_t b7:1;
} bits_t;
uint8_t reverse_bits(uint8_t src)
{
uint8_t dst = 0x0;
bits_t *src_bits = (bits_t *)&src;
bits_t *dst_bits = (bits_t *)&dst;
dst_bits->b0 = src_bits->b7;
dst_bits->b1 = src_bits->b6;
dst_bits->b2 = src_bits->b5;
dst_bits->b3 = src_bits->b4;
dst_bits->b4 = src_bits->b3;
dst_bits->b5 = src_bits->b2;
dst_bits->b6 = src_bits->b1;
dst_bits->b7 = src_bits->b0;
return dst;
}
As a stylistic note, I find the use ofuint8_t
for the 1-bit fields a bit ugly, since it seems to first say that it will take 8 bits but then at the end of the line defines it as only a single bit. I would useunsigned b0:1
etc.
– Arkku
Aug 8 at 14:44
add a comment |
up vote
0
down vote
typedef struct
{
uint8_t b0:1;
uint8_t b1:1;
uint8_t b2:1;
uint8_t b3:1;
uint8_t b4:1;
uint8_t b5:1;
uint8_t b6:1;
uint8_t b7:1;
} bits_t;
uint8_t reverse_bits(uint8_t src)
{
uint8_t dst = 0x0;
bits_t *src_bits = (bits_t *)&src;
bits_t *dst_bits = (bits_t *)&dst;
dst_bits->b0 = src_bits->b7;
dst_bits->b1 = src_bits->b6;
dst_bits->b2 = src_bits->b5;
dst_bits->b3 = src_bits->b4;
dst_bits->b4 = src_bits->b3;
dst_bits->b5 = src_bits->b2;
dst_bits->b6 = src_bits->b1;
dst_bits->b7 = src_bits->b0;
return dst;
}
As a stylistic note, I find the use ofuint8_t
for the 1-bit fields a bit ugly, since it seems to first say that it will take 8 bits but then at the end of the line defines it as only a single bit. I would useunsigned b0:1
etc.
– Arkku
Aug 8 at 14:44
add a comment |
up vote
0
down vote
up vote
0
down vote
typedef struct
{
uint8_t b0:1;
uint8_t b1:1;
uint8_t b2:1;
uint8_t b3:1;
uint8_t b4:1;
uint8_t b5:1;
uint8_t b6:1;
uint8_t b7:1;
} bits_t;
uint8_t reverse_bits(uint8_t src)
{
uint8_t dst = 0x0;
bits_t *src_bits = (bits_t *)&src;
bits_t *dst_bits = (bits_t *)&dst;
dst_bits->b0 = src_bits->b7;
dst_bits->b1 = src_bits->b6;
dst_bits->b2 = src_bits->b5;
dst_bits->b3 = src_bits->b4;
dst_bits->b4 = src_bits->b3;
dst_bits->b5 = src_bits->b2;
dst_bits->b6 = src_bits->b1;
dst_bits->b7 = src_bits->b0;
return dst;
}
typedef struct
{
uint8_t b0:1;
uint8_t b1:1;
uint8_t b2:1;
uint8_t b3:1;
uint8_t b4:1;
uint8_t b5:1;
uint8_t b6:1;
uint8_t b7:1;
} bits_t;
uint8_t reverse_bits(uint8_t src)
{
uint8_t dst = 0x0;
bits_t *src_bits = (bits_t *)&src;
bits_t *dst_bits = (bits_t *)&dst;
dst_bits->b0 = src_bits->b7;
dst_bits->b1 = src_bits->b6;
dst_bits->b2 = src_bits->b5;
dst_bits->b3 = src_bits->b4;
dst_bits->b4 = src_bits->b3;
dst_bits->b5 = src_bits->b2;
dst_bits->b6 = src_bits->b1;
dst_bits->b7 = src_bits->b0;
return dst;
}
answered Jun 23 '17 at 19:12
Tai-Yuan Fang
111
111
As a stylistic note, I find the use ofuint8_t
for the 1-bit fields a bit ugly, since it seems to first say that it will take 8 bits but then at the end of the line defines it as only a single bit. I would useunsigned b0:1
etc.
– Arkku
Aug 8 at 14:44
add a comment |
As a stylistic note, I find the use ofuint8_t
for the 1-bit fields a bit ugly, since it seems to first say that it will take 8 bits but then at the end of the line defines it as only a single bit. I would useunsigned b0:1
etc.
– Arkku
Aug 8 at 14:44
As a stylistic note, I find the use of
uint8_t
for the 1-bit fields a bit ugly, since it seems to first say that it will take 8 bits but then at the end of the line defines it as only a single bit. I would use unsigned b0:1
etc.– Arkku
Aug 8 at 14:44
As a stylistic note, I find the use of
uint8_t
for the 1-bit fields a bit ugly, since it seems to first say that it will take 8 bits but then at the end of the line defines it as only a single bit. I would use unsigned b0:1
etc.– Arkku
Aug 8 at 14:44
add a comment |
up vote
0
down vote
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i;
unsigned char rev = 0x70 ; // 0b01110000
unsigned char tmp = 0;
for(i=0;i<8;i++)
{
tmp |= ( ((rev & (1<<i))?1:0) << (7-i));
}
rev = tmp;
printf("%x", rev); //0b00001110 binary value of given number
return 0;
}
Please add some explanation.
– zcui93
Apr 5 '16 at 12:33
add a comment |
up vote
0
down vote
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i;
unsigned char rev = 0x70 ; // 0b01110000
unsigned char tmp = 0;
for(i=0;i<8;i++)
{
tmp |= ( ((rev & (1<<i))?1:0) << (7-i));
}
rev = tmp;
printf("%x", rev); //0b00001110 binary value of given number
return 0;
}
Please add some explanation.
– zcui93
Apr 5 '16 at 12:33
add a comment |
up vote
0
down vote
up vote
0
down vote
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i;
unsigned char rev = 0x70 ; // 0b01110000
unsigned char tmp = 0;
for(i=0;i<8;i++)
{
tmp |= ( ((rev & (1<<i))?1:0) << (7-i));
}
rev = tmp;
printf("%x", rev); //0b00001110 binary value of given number
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i;
unsigned char rev = 0x70 ; // 0b01110000
unsigned char tmp = 0;
for(i=0;i<8;i++)
{
tmp |= ( ((rev & (1<<i))?1:0) << (7-i));
}
rev = tmp;
printf("%x", rev); //0b00001110 binary value of given number
return 0;
}
edited Nov 14 '17 at 7:02
Moorthi Muthu
193212
193212
answered Apr 5 '16 at 12:28
AHMED ANWAR
11
11
Please add some explanation.
– zcui93
Apr 5 '16 at 12:33
add a comment |
Please add some explanation.
– zcui93
Apr 5 '16 at 12:33
Please add some explanation.
– zcui93
Apr 5 '16 at 12:33
Please add some explanation.
– zcui93
Apr 5 '16 at 12:33
add a comment |
up vote
0
down vote
I think this is simple enough
uint8_t reverse(uint8_t a)
{
unsigned w = ((a << 7) & 0x0880) | ((a << 5) & 0x0440) | ((a << 3) & 0x0220) | ((a << 1) & 0x0110);
return static_cast<uint8_t>(w | (w>>8));
}
or
uint8_t reverse(uint8_t a)
{
unsigned w = ((a & 0x11) << 7) | ((a & 0x22) << 5) | ((a & 0x44) << 3) | ((a & 0x88) << 1);
return static_cast<uint8_t>(w | (w>>8));
}
add a comment |
up vote
0
down vote
I think this is simple enough
uint8_t reverse(uint8_t a)
{
unsigned w = ((a << 7) & 0x0880) | ((a << 5) & 0x0440) | ((a << 3) & 0x0220) | ((a << 1) & 0x0110);
return static_cast<uint8_t>(w | (w>>8));
}
or
uint8_t reverse(uint8_t a)
{
unsigned w = ((a & 0x11) << 7) | ((a & 0x22) << 5) | ((a & 0x44) << 3) | ((a & 0x88) << 1);
return static_cast<uint8_t>(w | (w>>8));
}
add a comment |
up vote
0
down vote
up vote
0
down vote
I think this is simple enough
uint8_t reverse(uint8_t a)
{
unsigned w = ((a << 7) & 0x0880) | ((a << 5) & 0x0440) | ((a << 3) & 0x0220) | ((a << 1) & 0x0110);
return static_cast<uint8_t>(w | (w>>8));
}
or
uint8_t reverse(uint8_t a)
{
unsigned w = ((a & 0x11) << 7) | ((a & 0x22) << 5) | ((a & 0x44) << 3) | ((a & 0x88) << 1);
return static_cast<uint8_t>(w | (w>>8));
}
I think this is simple enough
uint8_t reverse(uint8_t a)
{
unsigned w = ((a << 7) & 0x0880) | ((a << 5) & 0x0440) | ((a << 3) & 0x0220) | ((a << 1) & 0x0110);
return static_cast<uint8_t>(w | (w>>8));
}
or
uint8_t reverse(uint8_t a)
{
unsigned w = ((a & 0x11) << 7) | ((a & 0x22) << 5) | ((a & 0x44) << 3) | ((a & 0x88) << 1);
return static_cast<uint8_t>(w | (w>>8));
}
edited Oct 15 at 14:53
answered Oct 15 at 4:28
agbinfo
543210
543210
add a comment |
add a comment |
up vote
0
down vote
unsigned char c ; // the original
unsigned char u = // the reversed
c>>7&0b00000001 |
c<<7&0b10000000 |
c>>5&0b00000010 |
c<<5&0b01000000 |
c>>3&0b00000100 |
c<<3&0b00100000 |
c>>1&0b00001000 |
c<<1&0b00010000 ;
Explanation: exchanged bits as per the arrows below.
01234567
<------>
#<---->#
##<-->##
###<>###
add a comment |
up vote
0
down vote
unsigned char c ; // the original
unsigned char u = // the reversed
c>>7&0b00000001 |
c<<7&0b10000000 |
c>>5&0b00000010 |
c<<5&0b01000000 |
c>>3&0b00000100 |
c<<3&0b00100000 |
c>>1&0b00001000 |
c<<1&0b00010000 ;
Explanation: exchanged bits as per the arrows below.
01234567
<------>
#<---->#
##<-->##
###<>###
add a comment |
up vote
0
down vote
up vote
0
down vote
unsigned char c ; // the original
unsigned char u = // the reversed
c>>7&0b00000001 |
c<<7&0b10000000 |
c>>5&0b00000010 |
c<<5&0b01000000 |
c>>3&0b00000100 |
c<<3&0b00100000 |
c>>1&0b00001000 |
c<<1&0b00010000 ;
Explanation: exchanged bits as per the arrows below.
01234567
<------>
#<---->#
##<-->##
###<>###
unsigned char c ; // the original
unsigned char u = // the reversed
c>>7&0b00000001 |
c<<7&0b10000000 |
c>>5&0b00000010 |
c<<5&0b01000000 |
c>>3&0b00000100 |
c<<3&0b00100000 |
c>>1&0b00001000 |
c<<1&0b00010000 ;
Explanation: exchanged bits as per the arrows below.
01234567
<------>
#<---->#
##<-->##
###<>###
edited Nov 11 at 22:32
answered Nov 11 at 22:11
Mahen
11
11
add a comment |
add a comment |
up vote
-1
down vote
#define BITS_SIZE 8
int
reverseBits ( int a )
{
int rev = 0;
int i;
/* scans each bit of the input number*/
for ( i = 0; i < BITS_SIZE - 1; i++ )
{
/* checks if the bit is 1 */
if ( a & ( 1 << i ) )
{
/* shifts the bit 1, starting from the MSB to LSB
* to build the reverse number
*/
rev |= 1 << ( BITS_SIZE - 1 ) - i;
}
}
return rev;
}
add a comment |
up vote
-1
down vote
#define BITS_SIZE 8
int
reverseBits ( int a )
{
int rev = 0;
int i;
/* scans each bit of the input number*/
for ( i = 0; i < BITS_SIZE - 1; i++ )
{
/* checks if the bit is 1 */
if ( a & ( 1 << i ) )
{
/* shifts the bit 1, starting from the MSB to LSB
* to build the reverse number
*/
rev |= 1 << ( BITS_SIZE - 1 ) - i;
}
}
return rev;
}
add a comment |
up vote
-1
down vote
up vote
-1
down vote
#define BITS_SIZE 8
int
reverseBits ( int a )
{
int rev = 0;
int i;
/* scans each bit of the input number*/
for ( i = 0; i < BITS_SIZE - 1; i++ )
{
/* checks if the bit is 1 */
if ( a & ( 1 << i ) )
{
/* shifts the bit 1, starting from the MSB to LSB
* to build the reverse number
*/
rev |= 1 << ( BITS_SIZE - 1 ) - i;
}
}
return rev;
}
#define BITS_SIZE 8
int
reverseBits ( int a )
{
int rev = 0;
int i;
/* scans each bit of the input number*/
for ( i = 0; i < BITS_SIZE - 1; i++ )
{
/* checks if the bit is 1 */
if ( a & ( 1 << i ) )
{
/* shifts the bit 1, starting from the MSB to LSB
* to build the reverse number
*/
rev |= 1 << ( BITS_SIZE - 1 ) - i;
}
}
return rev;
}
answered Feb 2 '17 at 5:14
aldo núñez
91
91
add a comment |
add a comment |
up vote
-1
down vote
xor ax,ax
xor bx,bx
mov cx,8
mov al,original_byte!
cycle: shr al,1
jnc not_inc
inc bl
not_inc: test cx,cx
jz,end_cycle
shl bl,1
loop cycle
end_cycle:
reversed byte will be at bl register
3
In an other context that may be a fair answer but the question was about C or C++, not asm ...
– jadsq
May 31 '17 at 16:35
add a comment |
up vote
-1
down vote
xor ax,ax
xor bx,bx
mov cx,8
mov al,original_byte!
cycle: shr al,1
jnc not_inc
inc bl
not_inc: test cx,cx
jz,end_cycle
shl bl,1
loop cycle
end_cycle:
reversed byte will be at bl register
3
In an other context that may be a fair answer but the question was about C or C++, not asm ...
– jadsq
May 31 '17 at 16:35
add a comment |
up vote
-1
down vote
up vote
-1
down vote
xor ax,ax
xor bx,bx
mov cx,8
mov al,original_byte!
cycle: shr al,1
jnc not_inc
inc bl
not_inc: test cx,cx
jz,end_cycle
shl bl,1
loop cycle
end_cycle:
reversed byte will be at bl register
xor ax,ax
xor bx,bx
mov cx,8
mov al,original_byte!
cycle: shr al,1
jnc not_inc
inc bl
not_inc: test cx,cx
jz,end_cycle
shl bl,1
loop cycle
end_cycle:
reversed byte will be at bl register
edited May 31 '17 at 17:12
answered May 31 '17 at 16:09
asm_fan
72
72
3
In an other context that may be a fair answer but the question was about C or C++, not asm ...
– jadsq
May 31 '17 at 16:35
add a comment |
3
In an other context that may be a fair answer but the question was about C or C++, not asm ...
– jadsq
May 31 '17 at 16:35
3
3
In an other context that may be a fair answer but the question was about C or C++, not asm ...
– jadsq
May 31 '17 at 16:35
In an other context that may be a fair answer but the question was about C or C++, not asm ...
– jadsq
May 31 '17 at 16:35
add a comment |
up vote
-2
down vote
How about this one...
int value = 0xFACE;
value = ((0xFF & value << 8) | (val >> 8);
4
This reverses the bytes in a (16-bit) word, but doesn't alter the order of the bits within the byte, so not really a solution.
– Eric Brown
Sep 25 '13 at 16:38
1
Ah, thank you Eric. My mistake.
– Valdo
Sep 25 '13 at 18:29
add a comment |
up vote
-2
down vote
How about this one...
int value = 0xFACE;
value = ((0xFF & value << 8) | (val >> 8);
4
This reverses the bytes in a (16-bit) word, but doesn't alter the order of the bits within the byte, so not really a solution.
– Eric Brown
Sep 25 '13 at 16:38
1
Ah, thank you Eric. My mistake.
– Valdo
Sep 25 '13 at 18:29
add a comment |
up vote
-2
down vote
up vote
-2
down vote
How about this one...
int value = 0xFACE;
value = ((0xFF & value << 8) | (val >> 8);
How about this one...
int value = 0xFACE;
value = ((0xFF & value << 8) | (val >> 8);
edited Sep 25 '13 at 16:31
Lodder
18.3k74485
18.3k74485
answered Sep 25 '13 at 16:11
Valdo
133
133
4
This reverses the bytes in a (16-bit) word, but doesn't alter the order of the bits within the byte, so not really a solution.
– Eric Brown
Sep 25 '13 at 16:38
1
Ah, thank you Eric. My mistake.
– Valdo
Sep 25 '13 at 18:29
add a comment |
4
This reverses the bytes in a (16-bit) word, but doesn't alter the order of the bits within the byte, so not really a solution.
– Eric Brown
Sep 25 '13 at 16:38
1
Ah, thank you Eric. My mistake.
– Valdo
Sep 25 '13 at 18:29
4
4
This reverses the bytes in a (16-bit) word, but doesn't alter the order of the bits within the byte, so not really a solution.
– Eric Brown
Sep 25 '13 at 16:38
This reverses the bytes in a (16-bit) word, but doesn't alter the order of the bits within the byte, so not really a solution.
– Eric Brown
Sep 25 '13 at 16:38
1
1
Ah, thank you Eric. My mistake.
– Valdo
Sep 25 '13 at 18:29
Ah, thank you Eric. My mistake.
– Valdo
Sep 25 '13 at 18:29
add a comment |
up vote
-2
down vote
This is an old question, but nobody seems to have shown the clear easy way (the closest was edW). I used C# (and the wonderful LinqPad to test this) but there's nothing in this example that couldn't be done easily in C.
Paste the following into the wonderful LinqPad (https://www.linqpad.net/), (which is where I tested this):
void PrintBinary(string prompt, int num, int pad = 8)
{
Debug.WriteLine($"{prompt}: {Convert.ToString(num, 2).PadLeft(pad, '0')}");
}
int ReverseBits(int num)
{
int result = 0;
int saveBits = num;
for (int i = 1; i <= 8; i++)
{
// Move the result one bit to the left
result = result << 1;
//PrintBinary("saveBits", saveBits);
// Extract the right-most bit
var nextBit = saveBits & 1;
//PrintBinary("nextBit", nextBit, 1);
// Add our extracted bit to the result
result = result | nextBit;
//PrintBinary("result", result);
// We're done with that bit, rotate it off the right
saveBits = saveBits >> 1;
//Debug.WriteLine("");
}
return result;
}
void PrintTest(int nextNumber)
{
var result = ReverseBits(nextNumber);
Debug.WriteLine("---------------------------------------");
PrintBinary("Original", nextNumber);
PrintBinary("Reverse", result);
}
void Main()
{
// Calculate the reverse for each number between 1 and 255
for (int x = 250; x < 256; x++)
PrintTest(x);
}
There are a couple of other answers (in C, no less) that implement the simple approach of iterating over the bits. I guess the point here was to advertise the online service to run C# code, but as an answer to this question this fails by being in a different language and including too much irrelevant stuff. (Even your test loop doesn't match the comment: the comment says "between 1 and 255" but your loop goes 250 to 255.)
– Arkku
Aug 8 at 15:01
add a comment |
up vote
-2
down vote
This is an old question, but nobody seems to have shown the clear easy way (the closest was edW). I used C# (and the wonderful LinqPad to test this) but there's nothing in this example that couldn't be done easily in C.
Paste the following into the wonderful LinqPad (https://www.linqpad.net/), (which is where I tested this):
void PrintBinary(string prompt, int num, int pad = 8)
{
Debug.WriteLine($"{prompt}: {Convert.ToString(num, 2).PadLeft(pad, '0')}");
}
int ReverseBits(int num)
{
int result = 0;
int saveBits = num;
for (int i = 1; i <= 8; i++)
{
// Move the result one bit to the left
result = result << 1;
//PrintBinary("saveBits", saveBits);
// Extract the right-most bit
var nextBit = saveBits & 1;
//PrintBinary("nextBit", nextBit, 1);
// Add our extracted bit to the result
result = result | nextBit;
//PrintBinary("result", result);
// We're done with that bit, rotate it off the right
saveBits = saveBits >> 1;
//Debug.WriteLine("");
}
return result;
}
void PrintTest(int nextNumber)
{
var result = ReverseBits(nextNumber);
Debug.WriteLine("---------------------------------------");
PrintBinary("Original", nextNumber);
PrintBinary("Reverse", result);
}
void Main()
{
// Calculate the reverse for each number between 1 and 255
for (int x = 250; x < 256; x++)
PrintTest(x);
}
There are a couple of other answers (in C, no less) that implement the simple approach of iterating over the bits. I guess the point here was to advertise the online service to run C# code, but as an answer to this question this fails by being in a different language and including too much irrelevant stuff. (Even your test loop doesn't match the comment: the comment says "between 1 and 255" but your loop goes 250 to 255.)
– Arkku
Aug 8 at 15:01
add a comment |
up vote
-2
down vote
up vote
-2
down vote
This is an old question, but nobody seems to have shown the clear easy way (the closest was edW). I used C# (and the wonderful LinqPad to test this) but there's nothing in this example that couldn't be done easily in C.
Paste the following into the wonderful LinqPad (https://www.linqpad.net/), (which is where I tested this):
void PrintBinary(string prompt, int num, int pad = 8)
{
Debug.WriteLine($"{prompt}: {Convert.ToString(num, 2).PadLeft(pad, '0')}");
}
int ReverseBits(int num)
{
int result = 0;
int saveBits = num;
for (int i = 1; i <= 8; i++)
{
// Move the result one bit to the left
result = result << 1;
//PrintBinary("saveBits", saveBits);
// Extract the right-most bit
var nextBit = saveBits & 1;
//PrintBinary("nextBit", nextBit, 1);
// Add our extracted bit to the result
result = result | nextBit;
//PrintBinary("result", result);
// We're done with that bit, rotate it off the right
saveBits = saveBits >> 1;
//Debug.WriteLine("");
}
return result;
}
void PrintTest(int nextNumber)
{
var result = ReverseBits(nextNumber);
Debug.WriteLine("---------------------------------------");
PrintBinary("Original", nextNumber);
PrintBinary("Reverse", result);
}
void Main()
{
// Calculate the reverse for each number between 1 and 255
for (int x = 250; x < 256; x++)
PrintTest(x);
}
This is an old question, but nobody seems to have shown the clear easy way (the closest was edW). I used C# (and the wonderful LinqPad to test this) but there's nothing in this example that couldn't be done easily in C.
Paste the following into the wonderful LinqPad (https://www.linqpad.net/), (which is where I tested this):
void PrintBinary(string prompt, int num, int pad = 8)
{
Debug.WriteLine($"{prompt}: {Convert.ToString(num, 2).PadLeft(pad, '0')}");
}
int ReverseBits(int num)
{
int result = 0;
int saveBits = num;
for (int i = 1; i <= 8; i++)
{
// Move the result one bit to the left
result = result << 1;
//PrintBinary("saveBits", saveBits);
// Extract the right-most bit
var nextBit = saveBits & 1;
//PrintBinary("nextBit", nextBit, 1);
// Add our extracted bit to the result
result = result | nextBit;
//PrintBinary("result", result);
// We're done with that bit, rotate it off the right
saveBits = saveBits >> 1;
//Debug.WriteLine("");
}
return result;
}
void PrintTest(int nextNumber)
{
var result = ReverseBits(nextNumber);
Debug.WriteLine("---------------------------------------");
PrintBinary("Original", nextNumber);
PrintBinary("Reverse", result);
}
void Main()
{
// Calculate the reverse for each number between 1 and 255
for (int x = 250; x < 256; x++)
PrintTest(x);
}
edited Feb 1 '17 at 10:04
answered Feb 1 '17 at 9:39
Scott Gartner
511715
511715
There are a couple of other answers (in C, no less) that implement the simple approach of iterating over the bits. I guess the point here was to advertise the online service to run C# code, but as an answer to this question this fails by being in a different language and including too much irrelevant stuff. (Even your test loop doesn't match the comment: the comment says "between 1 and 255" but your loop goes 250 to 255.)
– Arkku
Aug 8 at 15:01
add a comment |
There are a couple of other answers (in C, no less) that implement the simple approach of iterating over the bits. I guess the point here was to advertise the online service to run C# code, but as an answer to this question this fails by being in a different language and including too much irrelevant stuff. (Even your test loop doesn't match the comment: the comment says "between 1 and 255" but your loop goes 250 to 255.)
– Arkku
Aug 8 at 15:01
There are a couple of other answers (in C, no less) that implement the simple approach of iterating over the bits. I guess the point here was to advertise the online service to run C# code, but as an answer to this question this fails by being in a different language and including too much irrelevant stuff. (Even your test loop doesn't match the comment: the comment says "between 1 and 255" but your loop goes 250 to 255.)
– Arkku
Aug 8 at 15:01
There are a couple of other answers (in C, no less) that implement the simple approach of iterating over the bits. I guess the point here was to advertise the online service to run C# code, but as an answer to this question this fails by being in a different language and including too much irrelevant stuff. (Even your test loop doesn't match the comment: the comment says "between 1 and 255" but your loop goes 250 to 255.)
– Arkku
Aug 8 at 15:01
add a comment |
up vote
-4
down vote
How about just XOR the byte with 0xFF.
unsigned char reverse(unsigned char b) {
b ^= 0xFF;
return b;
}
2
what about 00111100? u get 11000011 what is wrong answer.
– lord.didger
Apr 6 '13 at 13:45
add a comment |
up vote
-4
down vote
How about just XOR the byte with 0xFF.
unsigned char reverse(unsigned char b) {
b ^= 0xFF;
return b;
}
2
what about 00111100? u get 11000011 what is wrong answer.
– lord.didger
Apr 6 '13 at 13:45
add a comment |
up vote
-4
down vote
up vote
-4
down vote
How about just XOR the byte with 0xFF.
unsigned char reverse(unsigned char b) {
b ^= 0xFF;
return b;
}
How about just XOR the byte with 0xFF.
unsigned char reverse(unsigned char b) {
b ^= 0xFF;
return b;
}
answered Mar 7 '13 at 22:22
JC9162
171
171
2
what about 00111100? u get 11000011 what is wrong answer.
– lord.didger
Apr 6 '13 at 13:45
add a comment |
2
what about 00111100? u get 11000011 what is wrong answer.
– lord.didger
Apr 6 '13 at 13:45
2
2
what about 00111100? u get 11000011 what is wrong answer.
– lord.didger
Apr 6 '13 at 13:45
what about 00111100? u get 11000011 what is wrong answer.
– lord.didger
Apr 6 '13 at 13:45
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f2602823%2fin-c-c-whats-the-simplest-way-to-reverse-the-order-of-bits-in-a-byte%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
5
Simple or fast?
– Andreas Rejbrand
Apr 8 '10 at 19:38
Use inline assembly. Better, put the function into a separate translation unit. Have one assembly language module for each target platform. Let build process choose the modules.
– Thomas Matthews
Apr 8 '10 at 19:47
@Andreas Simplest implementation
– nathan
Apr 8 '10 at 20:12
1
then do it in hardware ;)
– Hamish Grubijan
Apr 8 '10 at 21:10