Getting the xth bit of an unsigned charcter

J

John.Doe.UK

Hi there,

If I have three unsigned char(8 bits) and I want to compare the xth bit
in each. So if I had.

a 00000000
b 10101010
c 00000000


If I wanted to get the third bit from (a) the 0th bit from (b) and
compare them and store the result in the 7th bit of (c) how could i go
about doing this.

a 000[0]0000
b [1]0101010
c 0000000[0]

0 | 1 = 1

c = 00000001

Would there be a nice function or macro that could do this. Brand new
to all the bitwise stuff.
 
J

Jens.Toerring

Hi there,
If I have three unsigned char(8 bits) and I want to compare the xth bit
in each. So if I had.
a 00000000
b 10101010
c 00000000

If I wanted to get the third bit from (a) the 0th bit from (b) and
compare them and store the result in the 7th bit of (c) how could i go
about doing this.
a 000[0]0000
b [1]0101010
c 0000000[0]

The nomenclature I have seen most often calls the lowest order bit
the 0th bit, i.e. just the other way round from what you are calling
them. But YMMV...
0 | 1 = 1
c = 00000001

To get the bits out of a and b in the lowest bit you could use

( a >> 4 | b >> 7 ) & 1

e.g. shifting them first to the lowest position, then ORing both
variables and finally masking out everything but the lowest bit.

And to set the lowest bit of c accordingly (but leaving all other
bits in c intact) you could use

c = ( c & 0xFE ) | ( ( a >> 4 | b >> 7 ) & 1 );

That way you set the lowest bit of c to zero and then OR with the
lowest bit of the result of the shifts, OR and AND on a and b.
Would there be a nice function or macro that could do this. Brand new
to all the bitwise stuff.

Sorry, but I don't know of any ready-made function or macro for such
a rather specialized task. But it wouldn't be too difficult to write
your own function, something like

unsigned char munge_them( unsigned char a, int bit_of_a,
unsigned char b, int bit_of b,
unsigned c )
{
return ( c & 0xFE )
| ( ( ( a >> ( 7 - bit_of_a ) )
| ( b >> ( 7 - bit_of_b ) )
)
& 1
);
}

should do the job (using your nomenclature for naming bit positions).
Admittedly you could leave out some of the parentheses but I guess
it's a bit easier (well, not too much;-) to read that way...

Regards, Jens
 
B

bjrnove

Hi.

First you could get the third bit from a and move it into bit 0:
((a & 0x8) >> 3)

Then you could tage bit 0 from b
(b & 0x1)

Then compare them.
(((a & 0x8) >> 3) & (b & 0x1)) << 7

So a macro could be:
#define movesomething(a,b) ((((a & 0x8) >> 3) & (b & 0x1)) << 7)
 
P

pete

Hi there,

If I have three unsigned char(8 bits) and I want to compare the xth bit
in each. So if I had.

a 00000000
b 10101010
c 00000000

If I wanted to get the third bit from (a) the 0th bit from (b) and
compare them and store the result in the 7th bit of (c) how could i go
about doing this.

I would call those bits 4, 7, and 0.
a 000[0]0000
b [1]0101010
c 0000000[0]

0 | 1 = 1

c = 00000001

Would there be a nice function or macro that could do this. Brand new
to all the bitwise stuff.

/* BEGIN new.c */

#include <stdio.h>
#include <limits.h>

#define READ_UBIT(U,N) ((U) >> (N) & 1)
#define SET_UBIT(U,N) ((void)((U) |= 1u << (N)))
#define CLEAR_UBIT(U,N) ((void)((U) &= ~(1u << (N))))
#define FLIP_UBIT(U,N) ((void)((U) ^= 1u << (N)))

void bit_str(char *s1, const void *s2, size_t n);

int main(void)
{
unsigned char a, b, c;
char string[CHAR_BIT + 1];

a = 0;
b = 0xaa;
c = 0;
if (READ_UBIT(a, 4) | READ_UBIT(b, 7)) {
SET_UBIT(c, 0);
} else {
CLEAR_UBIT(c, 0);
}
bit_str(string, &a, 1);
printf("a is %s\n", string);
bit_str(string, &b, 1);
printf("b is %s\n", string);
bit_str(string, &c, 1);
printf("c is %s\n", string);
return 0;
}

void bit_str(char *s1, const void *s2, size_t n)
{
unsigned mask;
const unsigned char *const byte = s2;

while (n-- != 0) {
mask = ((unsigned char)-1 >> 1) + 1;
do {
*s1++ = (char)(mask & byte[n] ? '1' : '0');
mask >>= 1;
} while (mask != 0);
}
*s1 = '\0';
}

/* END new.c */
 
C

CBFalconer

If I have three unsigned char(8 bits) and I want to compare the
xth bit in each. So if I had.

a 00000000
b 10101010
c 00000000

If I wanted to get the third bit from (a) the 0th bit from (b) and
compare them and store the result in the 7th bit of (c) how could
i go about doing this.

a 000[0]0000
b [1]0101010
c 0000000[0]

You could simply write:

putbit(7, c, (getbit(3, a) == getbit(0, b)));

which reduces the problem to writing putbit() and getbit(). After
you solve that you may decide to encapsulate getbit and putbit into
macros, but that is a separate decision. So start with the
frameworks:

void putbit(int bitno, char *byte, int bitvalue) (...}
int getbit(int bitno, char *byte) { ... }

or whatever other similar set tickles your fancy. That will
solidify your understanding of the range and purpose of bitno and
bitvalue. The latter is likely to be most useful if limited to 0
and 1, and similarly for the return values from getbit. With C99
you can use the _Bool type here (or bool after #include
<stdbool.h>). With C90 you would be advised to emulate the C99
techniques with compatible #defines.
 
C

CBFalconer

a 000[0]0000
b [1]0101010
c 0000000[0]

To get the data from a specific bit...

data = varaible & (1 << bit);

A non-0 value in Data indicates the bit was a 1.

Or, to get a result in 0..1 for compatibility with other things,
try:

int getbit(unsigned int bitnum, unsigned int value) {

if (bitnum) value >>= bitnum;
return value & 1;
} /* untested */
 
N

not

Or, to get a result in 0..1 for compatibility with other things,
try:

int getbit(unsigned int bitnum, unsigned int value) {

if (bitnum) value >>= bitnum;
return value & 1;
} /* untested */


int getbit(unsigned int Bitnum, unsigned int Value)
{ return ((Value & (1 << Bitnum)) != 0); }
 
P

Peter Nilsson

Why bother testing bitnum? A shift of 0 is well defined...

int getbit(unsigned x, int n)
{
return (x >> n) & 1;
}

int getbit(unsigned int Bitnum, unsigned int Value)
{ return ((Value & (1 << Bitnum)) != 0); }

Better to use 1u rather than 1, because unsigned int will likely
have more value bits than a signed int, so the 1 << Bitnum may
invoke undefined behaviour for a legitimate value of Bitnum.
 

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

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top