# Q: Best way to do this?

Discussion in 'C Programming' started by scooby.doo@shaggy.to, Sep 10, 2007.

1. ### Guest

Hi,

I need to turn certain bits in a 8-bit word on depending on a decimal
value. For example if the decimal value is 1, turn the first bit on.
Decimal = 5 turn the first 5 bits on, and so on. Now I don't know the
correct terminology for what I'm trying to do, so that hasn't helped
me looking in reference manuals or the Internet. The only way I can
see of doing it is:-

unsigned char values[7] = {1, 3, 7, 15, 31, 63, 127};

main ()
{
unsigned char i;

for (i = 0; i < 8; i++) use_byte(values);

}

I do not need to worry about the last bit as if the byte is full (i.e.
decimal 8) that is handled differently.

Is this a sensible solution?

Thank-you.

, Sep 10, 2007

2. ### Malcolm McLeanGuest

Re: Best way to do this?

<> wrote in message
news:...
> Hi,
>
> I need to turn certain bits in a 8-bit word on depending on a decimal
> value. For example if the decimal value is 1, turn the first bit on.
> Decimal = 5 turn the first 5 bits on, and so on. Now I don't know the
> correct terminology for what I'm trying to do, so that hasn't helped
> me looking in reference manuals or the Internet. The only way I can
> see of doing it is:-
>
>
> unsigned char values[7] = {1, 3, 7, 15, 31, 63, 127};
>
> main ()
> {
> unsigned char i;
>
> for (i = 0; i < 8; i++) use_byte(values);
>
>
> }
>
> I do not need to worry about the last bit as if the byte is full (i.e.
> decimal 8) that is handled differently.
>
>
> Is this a sensible solution?
>

It is OK, but not terribly efficient.
You need to construct a variable like 00000111, and then OR, to set the last
three bits.
So
unsigned char mask = 0xFF << decimal;

will do it quite nicely. On a really simple processor the << decimal will be
a hidden loop, but it should be just one or two instructions on anything
that does any serious processing.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Malcolm McLean, Sep 10, 2007

3. ### Martin WellsGuest

scooby:

> I need to turn certain bits in a 8-bit word on depending on a decimal
> value. For example if the decimal value is 1, turn the first bit on.
> Decimal = 5 turn the first 5 bits on, and so on.

First attempt would be something like:

typedef unsigned SomeIntType;

SomeIntType TurnOnBits(unsigned quantity)
{
SomeIntType result = 0;

while(quantity--)
{
result <<= 1;
result += 1;
}

return result;
}

Martin

Martin Wells, Sep 10, 2007
4. ### peteGuest

wrote:
>
> Hi,
>
> I need to turn certain bits in a 8-bit word on depending on a decimal
> value. For example if the decimal value is 1, turn the first bit on.
> Decimal = 5 turn the first 5 bits on, and so on. Now I don't know the
> correct terminology for what I'm trying to do, so that hasn't helped
> me looking in reference manuals or the Internet. The only way I can
> see of doing it is:-
>
> unsigned char values[7] = {1, 3, 7, 15, 31, 63, 127};
>
> main ()
> {
> unsigned char i;
>
> for (i = 0; i < 8; i++) use_byte(values);
>
>
> }

You can replace (values), with (1U << i) - 1).

> I do not need to worry about the last bit as if the byte is full (i.e.
> decimal 8) that is handled differently.
>
>
> Is this a sensible solution?

Yes.

--
pete

pete, Sep 10, 2007
5. ### Charlie GordonGuest

Re: Best way to do this?

<> a écrit dans le message de news:
...
> Hi,
>
> I need to turn certain bits in a 8-bit word on depending on a decimal
> value. For example if the decimal value is 1, turn the first bit on.
> Decimal = 5 turn the first 5 bits on, and so on. Now I don't know the
> correct terminology for what I'm trying to do, so that hasn't helped
> me looking in reference manuals or the Internet. The only way I can
> see of doing it is:-
>
>
> unsigned char values[7] = {1, 3, 7, 15, 31, 63, 127};

if the index into this array is the decimal value mentioned above, you got
it wrong: C arrays are 0 based, so you should make the array at least 8
elements long (0 thru 7) or preferably 9 (0 thru 8 inclusive).

> main ()

should be: int main (void)

> {
> unsigned char i;

better make the loop index an int.

> for (i = 0; i < 8; i++) use_byte(values);

OOPS: you access 8 elements from an array of 7 ;-) see above

>
> }

should return 0.

> I do not need to worry about the last bit as if the byte is full (i.e.
> decimal 8) that is handled differently.

but it cannot hurt to have a generic solution that handles all cases.

> Is this a sensible solution?

providedyou fix the array size and contents, it works, but it is neither
efficient nor safe:
- initializing the array with the values of 2 to the n - 1 by hand is error
prone, just imagine if you needed 32 values.
- there is a much simpler solution with the bit shift operator:

the bits you want to set can be computed very efficiently as ((1 << n) - 1)
for values of n between 0 and 2 less than the size of an int, amply

you then use the bitwise or to set them into the word:

value |= ((1 << n) - 1);

--
Chqrlie.

PS: you can use ((1U << n) - 1) for an unsigned result upto 1 less than the
size of an unsigned int.

Charlie Gordon, Sep 11, 2007
6. ### PhoenixGuest

On Sep 11, 5:39 am, wrote:
> Hi,
>
> I need to turn certain bits in a 8-bit word on depending on a decimal
> value. For example if the decimal value is 1, turn the first bit on.
> Decimal = 5 turn the first 5 bits on, and so on. Now I don't know the
> correct terminology for what I'm trying to do, so that hasn't helped
> me looking in reference manuals or the Internet. The only way I can
> see of doing it is:-
>
> unsigned char values[7] = {1, 3, 7, 15, 31, 63, 127};
>
> main ()
> {
> unsigned char i;
>
> for (i = 0; i < 8; i++) use_byte(values);
>
> }
>
> I do not need to worry about the last bit as if the byte is full (i.e.
> decimal 8) that is handled differently.
>
> Is this a sensible solution?
>
> Thank-you.

yes, it is a good idea to use '|' to make this.
further more, if you want to change a certain bit to opposite, using
xor, '^'.
I hope there's something useful for you.

Phoenix, Sep 11, 2007