reverse the bits in an interger?

U

user923005

That's inverting (1 turn into 0 and vice versa), not reverting. I understood
the OP wants the laest significant bit being the most significate, the 2nd
least being the second most and so on.

Bye, Jojo

Actually, if the O.P. had wanted the ORDER of the bits reversed, he
should have asked for that.
Richard's reply was intended to be funny, and it made me laugh.

Of course, anyone with 30 seconds worth of time can do a web search
and find plenty of integer reversal routines.
But the thing that makes them interesting is understanding how they
work.

#include <limits.h>
#include <assert.h>

#define bitset( buf, bit ) ( buf[(bit) >> 3] |= ( 1 << ( (bit) & 7 )))
#define bitclr( buf, bit ) ( buf[(bit) >> 3] &= ~( 1 << ( (bit) &
7 )))
#define bittog( buf, bit ) ( buf[(bit) >> 3] ^= ( 1 << ( (bit) & 7 )))
#define bitget( buf, bit ) ((( buf[(bit) >> 3] >> ( (bit) & 7 )) &
1 ))

/*
http://resnet.uoregon.edu/~gurney_j/jmpc/bitwise.html
*/
unsigned reversebits0(unsigned n)
{
/* The assumption is that there are 32 usable bits */
assert(UINT_MAX == 4294967295);
n = ((n >> 1) & 0x55555555) | ((n << 1) & 0xaaaaaaaa);
n = ((n >> 2) & 0x33333333) | ((n << 2) & 0xcccccccc);
n = ((n >> 4) & 0x0f0f0f0f) | ((n << 4) & 0xf0f0f0f0);
n = ((n >> 8) & 0x00ff00ff) | ((n << 8) & 0xff00ff00);
n = ((n >> 16) & 0x0000ffff) | ((n << 16) & 0xffff0000);
return n;
}
/*
http://www.cs.utk.edu/~vose/c-stuff/bithacks.html#ReverseByteWith64BitsDiv
*/
unsigned reversebits1(unsigned n)
{
unsigned char b,
tmp;
unsigned char *p = (unsigned char *) &n;
/* The assumption is that there are 32 usable bits in unsigned int */
assert(UINT_MAX == 4294967295);
/* The assumption is that there are 8 usable bits in unsigned char */
assert(UCHAR_MAX == 255);
/* The assumption is that there are 4 unsigned chars in unsigned int
*/
assert(sizeof n == 4);
b = p[3];
b = ((b * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >>
32;
tmp = p[0];
p[0] = b;
tmp = ((tmp * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL p[3] = tmp;
b = p[2];
b = ((b * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >>
32;
tmp = p[1];
p[1] = b;
tmp = ((tmp * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL p[2] = tmp;
return n;
}

unsigned reversebits2(unsigned n)
{
unsigned n_reversed = 0;
unsigned i;
unsigned char *p = (unsigned char *) &n;
unsigned char *q = (unsigned char *) &n_reversed;
/* The assumption is that there are 32 usable bits */
assert(UINT_MAX == 4294967295);
for (i = 0; i < 32; i++) {
if (bitget(p, i)) bitset(q, 31 - i);
}
return n_reversed;
}
#ifdef UNIT_TEST
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void display_bits(unsigned n)
{
unsigned char *p = (unsigned char *) &n;
unsigned i;
/* The assumption is that there are 32 usable bits */
assert(UINT_MAX == 4294967295);
for (i = 0; i < 32; i++) {
if (bitget(p, i)) putchar('1');
else
putchar('0');
}
putchar('\n');

}
int main(void)
{
char string[256];
puts("enter a number between 0 and 4294967295");
fflush(stdin);
if (fgets(string, sizeof string, stdin)) {
unsigned n = (unsigned) atof(string);
unsigned n_rev;
display_bits(n);
n_rev = reversebits0(n);
display_bits(n_rev);
n_rev = reversebits1(n);
display_bits(n_rev);
n_rev = reversebits2(n);
display_bits(n_rev);
}
return 0;
}
#endif
 
R

Richard Heathfield

user923005 said:

int main(void)
{
char string[256];
puts("enter a number between 0 and 4294967295");
fflush(stdin);

Tell me you meant stdout. Pretty please?
 
O

osmium

user923005 said:
Richard's reply was intended to be funny, and it made me laugh.

That's pretty darn sad. This is supposed to be a technical group to help
people, not a bunch of misfits trying to purposely misunderstand and twist
every little thing that comes along for their own purposes.

Since you enjoyed it, maybe you could set up an alt.hazing group?
 
C

Christopher Benson-Manica

osmium said:
That's pretty darn sad. This is supposed to be a technical group to help
people, not a bunch of misfits trying to purposely misunderstand and twist
every little thing that comes along for their own purposes.

It's also not supposed to be a group where posts consisting solely of
questions smacking of homework assignments get serious responses.
 
D

Default User

Christopher said:
It's also not supposed to be a group where posts consisting solely of
questions smacking of homework assignments get serious responses.

I agree, but I also agree with osmium. Just SAY, "we won't do your
homework". These interpretation games aren't particularly amusing to
me, and are just confusing to the newbies. Say what you mean, mean what
you say, yadda yadda.




Brian
 
U

user923005

That's pretty darn sad. This is supposed to be a technical group to help
people, not a bunch of misfits trying to purposely misunderstand and twist
every little thing that comes along for their own purposes.

The O.P.'s question did get answered, very completely. I think that
responses tend to fit the post rather well.
Richard's function reversed the bits in an integer. I also posted
code to reverse the order of bits in an integer (three different
ways).
Since you enjoyed it, maybe you could set up an alt.hazing group?

Not a bad idea. I got a pretty good hazing when I started posting
here and it was probably one of the best things that ever happened to
me. However, I think that the hazing posters get right here for
making stupid posts is probably good enough that we do not need to
create an entire separate group for it.
 
U

user923005

I agree, but I also agree with osmium. Just SAY, "we won't do your
homework". These interpretation games aren't particularly amusing to
me, and are just confusing to the newbies. Say what you mean, mean what
you say, yadda yadda.

Some of my favorite posts of all time were Peter Seebach's 'homewurk
anserz'.
 
R

Richard Heathfield

osmium said:
That's pretty darn sad. This is supposed to be a technical group to
help people, not a bunch of misfits trying to purposely misunderstand
and twist every little thing that comes along for their own purposes.

It was a joke with a purpose behind it, which I have already made plain
elsethread. If the OP is bright enough to write programs, he should be
bright enough to see not only the joke but also its purpose (especially
since it has now been telegraphed), and thus he will have learned
something that will be invaluable to him over the course of his career.
 
A

Army1987

user923005 said:
That's inverting (1 turn into 0 and vice versa), not reverting. I understood
the OP wants the laest significant bit being the most significate, the 2nd
least being the second most and so on.

Bye, Jojo

Actually, if the O.P. had wanted the ORDER of the bits reversed, he
should have asked for that.
Richard's reply was intended to be funny, and it made me laugh.

Of course, anyone with 30 seconds worth of time can do a web search
and find plenty of integer reversal routines.
But the thing that makes them interesting is understanding how they
work. [snip]
/* The assumption is that there are 32 usable bits in unsigned int */
assert(UINT_MAX == 4294967295);
At runtime?
Wouldn't it make more sense to write
#if UINT_MAX != 4294967295
#error "This program is written for machines with 32-bit ints"
#endif
 
J

Joachim Schmitz

Richard Heathfield said:
osmium said:


It was a joke with a purpose behind it, which I have already made plain
Oh well, apparently I once again managed to have missed your humour ...

Bye, Jojo
 
J

Joachim Schmitz

Joachim Schmitz said:
Oh well, apparently I once again managed to have missed your humour ...
Guess that'll teach me to never ever again take you serious :cool:

Bye, Jojo
 
R

Richard Heathfield

Joachim Schmitz said:
Guess that'll teach me to never ever again take you serious :cool:

Humour can be an extraordinarily effective teaching tool. If you don't
benefit from it yourself, take comfort in the fact that others do.
 
J

Joachim Schmitz

Richard Heathfield said:
Joachim Schmitz said:


Humour can be an extraordinarily effective teaching tool.
Agreed. If it is recognizable as such.

Bye, Jojo
 
C

CBFalconer

Joachim said:
Agreed. If it is recognizable as such.

Richard has been known to misfire. An outstanding example was his
fairly recent reply in LISPTH to an (apparent) newbie.
 
C

Christopher Benson-Manica

user923005 said:
/* The assumption is that there are 32 usable bits */
assert(UINT_MAX == 4294967295);

One, presumably that constant would be better expressed using bit
shift operators (being careful to navigate the default integer
promotions appropriately). Two, does the code you posted handle the
case where sizeof int is 2 and CHAR_BIT is 16 as well as the obvious
case?
 
U

user923005

One, presumably that constant would be better expressed using bit
shift operators (being careful to navigate the default integer
promotions appropriately). Two, does the code you posted handle the
case where sizeof int is 2 and CHAR_BIT is 16 as well as the obvious
case?

No, but in debug mode the assert will fire and the programmer will
hopefully be smart enough to fix it.
 
U

user923005

"user923005" <[email protected]> ha scritto nel messaggio

Actually, if the O.P. had wanted the ORDER of the bits reversed, he
should have asked for that.
Richard's reply was intended to be funny, and it made me laugh.
Of course, anyone with 30 seconds worth of time can do a web search
and find plenty of integer reversal routines.
But the thing that makes them interesting is understanding how they
work. [snip]
/* The assumption is that there are 32 usable bits in unsigned int */
assert(UINT_MAX == 4294967295);

At runtime?

There is no check for release mode.
Wouldn't it make more sense to write
#if UINT_MAX != 4294967295
#error "This program is written for machines with 32-bit ints"
#endif

There will be no discernable effect, even in debug mode for a single
integer comparison. I see these two as approximately equivalent.

There is one superiority to the #error method -- if the code is never
tested in debug mode, then the assert will never fire.
 
C

Christopher Benson-Manica

user923005 said:
On Jun 21, 8:22 am, Christopher Benson-Manica
No, but in debug mode the assert will fire and the programmer will
hopefully be smart enough to fix it.

Why would the assert fire? Is there any reason why UINT_MAX must
have a different value for sizeof int 2/CHAR_BIT 16 and sizeof int
4/CHAR_BIT 8?
 
A

Army1987

Christopher Benson-Manica said:
One, presumably that constant would be better expressed using bit
shift operators (being careful to navigate the default integer
promotions appropriately). Two, does the code you posted handle the
case where sizeof int is 2 and CHAR_BIT is 16 as well as the obvious
case?
There was an assert(UCHAR_MAX == 255); right below.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,281
Latest member
Pedroaciny

Latest Threads

Top