Test a bit

  • Thread starter Sam \(rép. sans -no-sp-am\)
  • Start date
S

Sam \(rép. sans -no-sp-am\)

Hi all !

I am new to C, sorry for those two questions ...

First, I would like to know which command allows me to test just one bit
from a char variable.

Second, I would like to programm a code checker. My code is 36 bits long,
but I can't do a bit-array or pointer (my compiler doesn't accept it). How
could I build one ? Could you give me a few commands to help me ??

Thanks a LOT !

Sam
 
E

Eric Sosman

Sam (rép. sans -no-sp-am) said:
Hi all !

I am new to C, sorry for those two questions ...

First, I would like to know which command allows me to test just one bit
from a char variable.

Study the `&' operator. You will probably find the
`|' and `^' operators interesting, too, as well as '>>'
and `<<'.
Second, I would like to programm a code checker.

Not sure what you mean by a "code checker." Does it
have something to do with dispatching taxis?
My code is 36 bits long,
but I can't do a bit-array or pointer (my compiler doesn't accept it). How
could I build one ? Could you give me a few commands to help me ??

The smallest addressable unit of memory in C is the
byte, even if the underlying hardware is capable of finer
addressing granularity. As a consequence, C can't handle
a pointer to an individual bit. And since array element
references are defined in terms of pointers, it also turns
out that C can't make arrays of bits.

You therefore need to consider other ways to represent
and access the thirty-six bits of each of your codes. There
are lots of approaches; here are a few:

- Use an entire `char' (any flavor) to store each bit,
and just waste the other bits. You can form arrays
of these "bloated bits," form pointers to them, and
so on. The disadvantage, if you have a very large
number of codes floating around, is that it eats
a lot of memory.

- Pack the thirty-six bits into an unsigned integral
type with at least that width, and use the bitwise
operators mentioned above, along with appropriate
single-bit masks, to manipulate them individually.
This (usually) shrinks the storage requirement, at
the cost of making the code more cumbersome -- but
much of the clumsiness can be hidden behind macros;
see the FAQ.

- If you don't have a sufficiently wide integral type
available, you can use a small array of narrower
objects. Again, see the FAQ.
 
R

Richard Heathfield

Sam said:
Hi all !

I am new to C, sorry for those two questions ...

First, I would like to know which command

C has operators and functions, but not commands.
allows me to test just one bit
from a char variable.

Start with 1. Left-shift it into the correct position. Then bitwise-AND the
result with your char variable. If the result is non-zero, the bit you wish
to test is set. Otherwise, it is clear.
Second, I would like to programm a code checker. My code is 36 bits long,
but I can't do a bit-array or pointer (my compiler doesn't accept it). How
could I build one ? Could you give me a few commands to help me ??

You can use an array of unsigned char to store a bitmap (a group of bits of
arbitrary length). To guarantee 36 bits of storage, use at least a 5-char
array. Use shift and bitwise-OR to set bits, use a combination of shift,
bitwise-AND and bitwise-NOT to clear them, and the technique mentioned
above to test them.

See the FAQ for more details.
 
M

Malcolm

Sam (rép. sans -no-sp-am) said:
First, I would like to know which command allows me to test just
one bit from a char variable.
You need to write two functions

1) int getbit(unsigned char *ptr, int bitno)

2) void setbit(unsigned char *ptr, int bitno, int flag)

For the time being assume that chars are always 8 bits.
What you need to do is take bitno/8 as the offset in bytes, and bitno%8 as
the offset in bits within the byte.
Then you construct a table of 8 bit masks (0x80, 0x40, 0x20, 0x10, 0x08,
0x04, 0x02, 0x01), select the right one, and use a combination of & and |
(bitwise AND and OR) and &= and |= to get and set the bit. Hint: to clear a
bit AND with the inverse of the bitmask.
 
P

Peter Pichler

Richard Heathfield said:
To guarantee 36 bits of storage, use at least a 5-char
array.

Obviously not on DeathStation 9000. Unless you've misspelt 'at most'.
 
B

Barry Schwarz

Obviously not on DeathStation 9000. Unless you've misspelt 'at most'.
I don't think so. An array of 5 char is guaranteed to have at least
40 bits. Anything larger is obviously larger.

An array of 4 char, which satisfies the definition of at most 5 char,
could contain only 32 bits and still be compliant.


<<Remove the del for email>>
 
B

Ben Pfaff

Barry Schwarz said:
An array of 4 char, which satisfies the definition of at most 5 char,
could contain only 32 bits and still be compliant.

"Could"? I'd say that 4 char "usually" contains only 32 bits.
 
P

Peter Pichler

Barry Schwarz said:
I don't think so. An array of 5 char is guaranteed to have at least
40 bits. Anything larger is obviously larger.

An array of 4 char, which satisfies the definition of at most 5 char,
could contain only 32 bits and still be compliant.

I must've been too subtle :)

A char is at least 8 bits wide, ergo it could be more. If it *is* more,
then 4 chars is enough to store 36 bits. I'm sure on DS9k 2 chars would
be more than enough.

Richard's 'at least' clause holds for 8-bit chars and at least 36 bits.
And yes, I know that's what he meant.

Peter
 
L

Lukasz Wawrzyniak

Sam \(rép. sans -no-sp-am\) said:
Hi all !

I am new to C, sorry for those two questions ...

First, I would like to know which command allows me to test just one bit
from a char variable.

Second, I would like to programm a code checker. My code is 36 bits long,
but I can't do a bit-array or pointer (my compiler doesn't accept it). How
could I build one ? Could you give me a few commands to help me ??

Thanks a LOT !

Sam

To add to all the previous answers, there is one more method you could
explore. Enter bit fields:

struct bits {
unsigned field1 : 1; /* field1 is 1 bit long */
unsigned field2 : 7; /* field2 is 7 bits long */
unsigned field3 : 3; /* field3 is 3 bits long */
};

You can define the following structure to represent a 36-bit code:

typedef struct {
unsigned bit00:1, bit01:1, bit02:1, bit03:1, bit04:1,
bit05:1, bit06:1, bit07:1, bit08:1, bit09:1,
bit10:1, bit11:1, bit12:1, bit13:1, bit14:1,
bit15:1, bit16:1, bit17:1, bit18:1, bit19:1,
bit20:1, bit21:1, bit22:1, bit23:1, bit24:1,
bit25:1, bit26:1, bit27:1, bit28:1, bit29:1,
bit30:1, bit31:1, bit32:1, bit33:1, bit34:1,
bit35:1;
} Code;

You use a bit field as you would any other integral type, e.g.:

Code c;
/* code initialization goes here */
if (c.bit15) {
/* bit 15 was 1, do something */
} else {
/* bit 15 was zero, do something else */
}

The drawback of this approach is that since each of the bit fields
must be accessed explicitly in code (no bit field arrays are
possible,) such a representation could quickly get tedious to manage,
depending on the task at hand. To possibly speed things up a bit, you
can overlay the bit fields with a char array (let's assume that your
char is 8 bits long so that you need 5 chars to cover the 36 bits.)
Some operations (like copying the codes) can then be performed using a
loop on the char array.

typedef union {
struct {
unsigned bit00:1, bit01:1, bit02:1, bit03:1, bit04:1,
bit05:1, bit06:1, bit07:1, bit08:1, bit09:1,
bit10:1, bit11:1, bit12:1, bit13:1, bit14:1,
bit15:1, bit16:1, bit17:1, bit18:1, bit19:1,
bit20:1, bit21:1, bit22:1, bit23:1, bit24:1,
bit25:1, bit26:1, bit27:1, bit28:1, bit29:1,
bit30:1, bit31:1, bit32:1, bit33:1, bit34:1,
bit35:1;
} bits;
unsigned char chars[5];
} Code;

Look up more info on bit fields and unions to shed more light on this
approach.

Just my $0.02.

Lukasz
 

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
474,141
Messages
2,570,817
Members
47,362
Latest member
ChandaWagn

Latest Threads

Top