Macro for counting the bits in odd positions

Z

zets

I need a macro for counting the bits in the odd positions of a given
input (of any type, char, pointer, int, struct, whatever).
Is there any clever way I could not think of, to do it efficiently?

#define COUNT(num, count) \

do { \

unsigned char *safe ## num ## count = (unsigned
char *)(&(num)); \

size_t safe ## size = sizeof(num); \

count=0; \

while (safe ## size--) { \

count+=(((*safe ## num ## count &
0x2)!=0)+((*safe ## num ## count & 0x8)!=0)+((*safe ## num ## count &
0x20)!=0)+((*safe ## num ## count & 0x80)!=0)); \

safe ## num ## count++; \

} \

} while (0)

Thanks
 
W

Walter Roberson

I need a macro for counting the bits in the odd positions of a given
input (of any type, char, pointer, int, struct, whatever).
Is there any clever way I could not think of, to do it efficiently?

How do you deal with the padding in structures?

Is it meaningful to look at the bit level of pointers? Pointers
are somewhat defined as opaque tokens, and casting a pointer
is not certain to give you the same bitwise representation even if
the same location in memory is being represented.

Does your application take into account 1's complement, separate
sign bits, differing representations for floats, and all the other ways
that numbers might be stored differently in different versions of C?
For example when CHAR_BIT is odd, then "odd" and "even" bits
is contextual and dependant on byte ordering. Your code does not
take that into account: it resets the notion of odd vs even on
each character boundary.
 
E

Eric Sosman

zets said:
I need a macro for counting the bits in the odd positions of a given
input (of any type, char, pointer, int, struct, whatever).

Out of curiosity, why do you need such a thing? That's
two questions, really: Why do you need this silly-seeming
operation, and why do you need it in the form of a macro?
 
Z

zeus

A student of mine sent me a question given in an exam. the question was
to write this macro, it is not useful for any real application. This
was my solution, just wanted to check out if there's any trick I was
missing here.
 
W

Walter Roberson

I need a macro for counting the bits in the odd positions of a given
input (of any type, char, pointer, int, struct, whatever).
Is there any clever way I could not think of, to do it efficiently?

#define COUNT(num, count) \

do { \

unsigned char *safe ## num ## count = (unsigned
char *)(&(num)); \

If num is a numeric constant (including a character literal) then
you will not be able to take its address.

If num is a string constant (double quoted string) then the macro
would attempt to count over the pointer to the string -- but the
pointer to a string constant is not (if I recall properly) certain
to be the same for all copies of the string, so examining the bits
is not necessarily going to give you a consistant answer.
 
K

Keith Thompson

zeus said:
A student of mine sent me a question given in an exam. the question was
to write this macro, it is not useful for any real application. This
was my solution, just wanted to check out if there's any trick I was
missing here.

Please don't assume that your readers have easy access to the article
to which you're replying. You need to provide some context, including
appropriate quoted text from the previous article and proper
attributions.

Google makes this needlessly difficult, but not impossible. If you
had been following this newsgroup, you would have seen the following
many many times:

If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.
 
N

Netocrat

I need a macro for counting the bits in the odd positions of a given
input (of any type, char, pointer, int, struct, whatever).
Is there any clever way I could not think of, to do it efficiently?

I don't know of a better way than two loops, without having some
hardware-specific knowledge/help.
#define COUNT(num, count) \

do { \

unsigned char *safe ## num ## count = (unsigned
char *)(&(num)); \

size_t safe ## size = sizeof(num); \

count=0; \

while (safe ## size--) { \

count+=(((*safe ## num ## count &
0x2)!=0)+((*safe ## num ## count & 0x8)!=0)+((*safe ## num ## count &
0x20)!=0)+((*safe ## num ## count & 0x80)!=0)); \

safe ## num ## count++; \

} \

} while (0)

It's more intuitive to me to count the bits from the leftmost bit. You
are counting from the rightmost bit.

You are also missing the inner loop because your code assumes that
CHAR_BIT == 8. This modification of your macro will work for any value of
CHAR_BIT - odd or even - assuming that bits are counted from the leftmost
bit of the object represented by "num".

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

#define COUNT(num, count) \
do { \
unsigned char *safe##num##count = (unsigned char *)(&(num)); \
size_t safe##size = sizeof(num); \
unsigned char bit = 1; \
count = 0; \
while (safe##size--) { \
bit <<= (CHAR_BIT - 2); \
do { \
count += (*safe##num##count & bit) > 0; \
if (bit <= 2) \
break; \
bit >>= 2; \
} while (1); \
safe##num##count++; \
} \
} while (0)
 
N

Netocrat

It's more intuitive to me to count the bits from the leftmost bit. You
are counting from the rightmost bit.

My mistake - you are counting from the leftmost bit after all.
You are also missing the inner loop because your code assumes that
CHAR_BIT == 8. This modification of your macro will work for any value of
CHAR_BIT - odd or even - assuming that bits are counted from the leftmost
bit of the object represented by "num".

And I am counting even bits not odd bits... the initialisation of bit
should be 2 not 1.
 

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,768
Messages
2,569,575
Members
45,053
Latest member
billing-software

Latest Threads

Top