473,836 Members | 1,582 Online

# clean method to read bit position?

From a byte containing only 1 bit, I need to find the number representing
the bit position.

Example:
00010000 = 4
00000001 = 0

Is there a simpler method than looping?

Thanks,
Scott Kelley
Nov 14 '05
19 21004
On Tue, 20 Jan 2004 15:19:41 -0000, "ESOJAY" <es******@hotma il.com>
wrote:

"Scott Kelley" <sc****@iccom.c om> wrote in message
news:r5******** ************@ce nturytel.net...
From a byte containing only 1 bit, I need to find the number representing
the bit position.

Example:
00010000 = 4
00000001 = 0

Is there a simpler method than looping?

Thanks,
Scott Kelley

My preferred but CPU intensive solution is (int)( log(byte)/log (2) ) ;

Then I should definitely avoid software written by you ;-)

On my system (gcc 3.3.1 cygwin)

(int) (log(8)/log(2))

yields 2.
--
Horst

Nov 14 '05 #11
I prefer a switch statement to 'if's (cos it's easier to type):

switch(byte){
case 1: return 0;
case 2: return 1;
case 4: return 2;
...
default: return -1;
}

Sean

Were you being literal with the above statement? Cannot find any reference
to a switch statement being used to return a value. All info I find
discusses only the form I'm used to:

case 1: {x = 0; break;}
case 2: {x = 1; break;}

If it can be used as you show, that would be very useful to me.

Scott Kelley
Nov 14 '05 #12
Sean Kenwrick wrote:
I prefer a switch statement to 'if's (cos it's easier to type):

switch(byte){
case 1: return 0;
case 2: return 1;
case 4: return 2;
...
default: return -1;
}

/* BEGIN bit_pos.c */

#include <stdio.h>

int bit_pos(unsigne d char byte)
{
int pos = 7;
unsigned char mask = 1u << 7;

do {
++pos;
return pos;
}

#define bit_pos(A) \
((A) == 1u << 0 ? 0 \
: (A) == 1u << 1 ? 1 \
: (A) == 1u << 2 ? 2 \
: (A) == 1u << 3 ? 3 \
: (A) == 1u << 4 ? 4 \
: (A) == 1u << 5 ? 5 \
: (A) == 1u << 6 ? 6 \
: (A) == 1u << 7 ? 7 \
: (bit_pos)(A))

int main(void)
{
unsigned char byte;

byte = 1;
do {
printf("Bit %d is set in %d\n", bit_pos(byte), byte);
byte <<= 1;
} while (byte != 0);
return 0;
}

/* END bit_pos.c */
--
pete
Nov 14 '05 #13
"Scott Kelley" <sc****@iccom.c om> writes:
I prefer a switch statement to 'if's (cos it's easier to type):

switch(byte){
case 1: return 0;
case 2: return 1;
case 4: return 2;
...
default: return -1;
}

Sean

Were you being literal with the above statement? Cannot find any reference
to a switch statement being used to return a value. All info I find
discusses only the form I'm used to:

case 1: {x = 0; break;}
case 2: {x = 1; break;}

If it can be used as you show, that would be very useful to me.

A return statement can be used within a switch statement just as
it can be used in any other context. I hope you don't think that
it causes the switch statement itself to have a value; rather, it
returns a value from the function just as in any other context.
--
int main(void){char p[]="ABCDEFGHIJKLM NOPQRSTUVWXYZab cdefghijklmnopq rstuvwxyz.\
\n",*q="kl BIcNBFr.NKEzjwC IxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+= strchr(p,*q++)-p;if(i>=(int)si zeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}
Nov 14 '05 #14

"Ben Pfaff" <bl*@cs.stanfor d.edu> wrote in message
news:87******** ****@pfaff.stan ford.edu...
"Scott Kelley" <sc****@iccom.c om> writes:
I prefer a switch statement to 'if's (cos it's easier to type):

switch(byte){
case 1: return 0;
case 2: return 1;
case 4: return 2;
...
default: return -1;
}

Sean

Were you being literal with the above statement? Cannot find any reference to a switch statement being used to return a value. All info I find
discusses only the form I'm used to:

case 1: {x = 0; break;}
case 2: {x = 1; break;}

If it can be used as you show, that would be very useful to me.

A return statement can be used within a switch statement just as
it can be used in any other context. I hope you don't think that
it causes the switch statement itself to have a value; rather, it
returns a value from the function just as in any other context.

Do you mean that it would be used as follows?

char myfunction(char );
.. . .

bit = myfunction(x);

char myfunction(byte ) {
switch(byte){
case 1: return 0;
case 2: return 1;
case 4: return 2;
...
default: return -1;
}
}

Nov 14 '05 #15
"Scott Kelley" <sc****@iccom.c om> writes:
A return statement can be used within a switch statement just as
it can be used in any other context. I hope you don't think that
it causes the switch statement itself to have a value; rather, it
returns a value from the function just as in any other context.

Do you mean that it would be used as follows?

char myfunction(char );
. . .

bit = myfunction(x);

char myfunction(byte ) {
switch(byte){
case 1: return 0;
case 2: return 1;
case 4: return 2;
...
default: return -1;
}
}

Yes (although I probably would not use `char' as the return
type).
--
"C has its problems, but a language designed from scratch would have some too,
and we know C's problems."
--Bjarne Stroustrup
Nov 14 '05 #16
Scott Kelley <sc****@iccom.c om> wrote:
"Ben Pfaff" <bl*@cs.stanfor d.edu> wrote in message
news:87******** ****@pfaff.stan ford.edu...
"Scott Kelley" <sc****@iccom.c om> writes: Do you mean that it would be used as follows?

char myfunction(char );
. . . bit = myfunction(x); char myfunction(byte ) {
switch(byte){
case 1: return 0;
case 2: return 1;
case 4: return 2;
...
default: return -1;
}
}

Yes, definitely. There's nothing wrong with that. It's not different
from e.g. returning from within a for loop. You can even call exit()
from within a switch;-)
Regards, Jens
--
\ Jens Thoms Toerring ___ Je***********@p hysik.fu-berlin.de
\______________ ____________ http://www.physik.fu-berlin.de/~toerring
Nov 14 '05 #17
"Scott Kelley" <sc****@iccom.c om> wrote in message news:<r5******* *************@c enturytel.net>. ..
From a byte containing only 1 bit, I need to find the number representing
the bit position.

Example:
00010000 = 4
00000001 = 0

Is there a simpler method than looping?

Define simpler? ;) The following is O(1) for 8-bits...

#include <stdio.h>

int main(void)
{
static int table[8] = { 7, 0, 5, 1, 6, 4, 3, 2 };
unsigned x;

for (x = 1; x < 256; x <<= 1) /* x: 2**[0..7] */
{
printf("0x%02X: ", x);
printf("bit %d\n", table[((x * 0x3A) >> 5) & 7]);
}

return 0;
}

Of course, the (hashing) method is not likely to be practical for such
narrow integers. BTW, it's based on...

--
Peter
Nov 14 '05 #18
[Someone wrote]
switch(byte){
case 1: return 0;
...

In article <news:9s******* *************@c enturytel.net>
Scott Kelley <sc****@iccom.c om> writes:Were you being literal with the above statement? Cannot find any reference
to a switch statement being used to return a value. All info I find
discusses only the form I'm used to:

case 1: {x = 0; break;}
case 2: {x = 1; break;}

I suspect you think that switch/case constructs are quite restricted
(which is often true in other languages). C is a bit lower level
than that -- a switch is just a goto in disguise:

volatile unsigned char *dev;
unsigned char *mem;
...
i = n / 8;
switch (n % 8) {
do {
*dev = *mem++;
case 7: *dev = *mem++;
case 6: *dev = *mem++;
case 5: *dev = *mem++;
case 4: *dev = *mem++;
case 3: *dev = *mem++;
case 2: *dev = *mem++;
case 1: *dev = *mem++;
case 0: ;
} while (i-- != 0);
}

This construct, called "Duff's Device" after Tom Duff (see the
FAQ), is entirely valid Standard C. The "switch" is just a goto,
and each "case" label is just a target label. (The FAQ's version
is slightly different -- I looked it up after typing in the above.)

The only "magic" about switch/case is that a case "looks upwards"
in enclosing brace scope blocks to find the innermost enclosing
"switch" statement, and places the appropriate "if (switch_expr ==
this_case_const ant) goto here" up there. (Old non-optimizing
C compilers actually implemented this by compiling:

switch (expr) {
...
}

as if it were:

tmp = expr;
goto just_past_end_o f_switch;
...
goto around;
just_past_end_o f_switch:
if (tmp == first_value) goto first_label;
if (tmp == second_value) goto second_label;
...
if (tmp == last_value) goto last_label;
if (there was a default) goto default_label;
around:

This allows the compiler to "forget" the code in between, and
remember only the <value,label> pairings. The <value,label>
pairs can also be compared more efficiently than with a straight
sequence of "if"s; e.g., if the table is dense this turns into:

if (tmp >= first_value && tmp <= last_value)
goto label[tmp - first_value];
if (there was a default)
goto default_label;
around:

and in other cases the compiler could generate an inline
binary search.)

The fact that "case" labels are really just goto-labels is
also the (or at least "a") logical reason behind the requirement
for a "break" statement if you did not want to fall through
from one case to the next. Just as:

if (x == 1) goto label;
f();
label:
g();

executes g() even when x == 2, so does a switch/case.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #19
Ben Pfaff <bl*@cs.stanfor d.edu> wrote in message news:<87******* *****@pfaff.sta nford.edu>...
"Scott Kelley" <sc****@iccom.c om> writes:

char myfunction(byte ) {
switch(byte){
case 1: return 0;
case 2: return 1;
case 4: return 2;
...
default: return -1;
}
}

Yes (although I probably would not use `char' as the return
type).

Ben's referring to situations where plain char is unsigned and constructs like...

if (myfunction(bla h) == -1)

....may not work as expected, i.e. UCHAR_MAX is not -1.

--
Peter
Nov 14 '05 #20

This thread has been closed and replies have been disabled. Please start a new discussion.