"Peter Nilsson" <(E-Mail Removed)> wrote in message

news:(E-Mail Removed)...

Spiros Bousbouras <(E-Mail Removed)> wrote:

> > ...

> > A bit more complicated but still (IMO) clearer is

> >

> > #define COUNT_BITS(n) ( \

> > (n) == ( (1 << CHAR_BIT) -1) ? CHAR_BIT : \

> > (n) == ( (1 << 2*CHAR_BIT) -1) ? 2*CHAR_BIT : \

> > (n) == ( (1 << 3*CHAR_BIT) -1) ? 3*CHAR_BIT : \

> There are a few problems with this:

> n may be a signed type

> n may be a padded type

> n may be wider than the left shifted 1 (int)

> [Even 1<<CHAR_BIT can potentially invoke UB.]

> <snip>

> > I have a vague recollection that a while ago someone

> > posted a macro which did what you wanted (or something

> > close) and could handle ridiculously large numbers of

> > bits.

> Hallvard B Furuseth once posted the following (which

> I've edited slightly due to line wrap issues)...

> /* Number of bits in inttype_MAX, or in any (1<<b)-1

> where 0 <= b < 3E+10 */

> #define IMAX_BITS(m) ((m) /((m)%0x3fffffffL+1) \

> /0x3fffffffL %0x3fffffffL *30 + \

> (m)%0x3fffffffL /((m)%31+1)/31%31*5 + 4 - \

> 12/((m)%31+3))
That does not seem to work at all; here is an example:

__________________________________________________ ____________________

#include <limits.h>

#include <stdio.h>

#define CHECK_BIT_X(n, b) (((n) >> (b)) == 1) ? (b) + 1

#define COUNT_BITS_CALC_X(n, b) ( \

(CHECK_BIT_X(n, (b) + 0) : (CHECK_BIT_X(n, (b) + 1) \

: (CHECK_BIT_X(n, (b) + 2) : (CHECK_BIT_X(n, (b) + 3) \

: (CHECK_BIT_X(n, (b) + 4) : (CHECK_BIT_X(n, (b) + 5) \

: (CHECK_BIT_X(n, (b) + 6) : (CHECK_BIT_X(n, (b) + 7) \

: (CHECK_BIT_X(n, (b) +

: (CHECK_BIT_X(n, (b) + 9) \

: (CHECK_BIT_X(n, (b) + 10) : (CHECK_BIT_X(n, (b) + 11) \

: (CHECK_BIT_X(n, (b) + 12) : (CHECK_BIT_X(n, (b) + 13) \

: (CHECK_BIT_X(n, (b) + 14) : (CHECK_BIT_X(n, (b) + 15) \

: (CHECK_BIT_X(n, (b) + 16) : (CHECK_BIT_X(n, (b) + 17) \

: (CHECK_BIT_X(n, (b) + 1

: (CHECK_BIT_X(n, (b) + 19) \

: (CHECK_BIT_X(n, (b) + 20) : (CHECK_BIT_X(n, (b) + 21) \

: (CHECK_BIT_X(n, (b) + 22) : (CHECK_BIT_X(n, (b) + 23) \

: (CHECK_BIT_X(n, (b) + 24) : (CHECK_BIT_X(n, (b) + 24) \

: (CHECK_BIT_X(n, (b) + 26) : (CHECK_BIT_X(n, (b) + 26) \

: (CHECK_BIT_X(n, (b) + 2

: (CHECK_BIT_X(n, (b) + 2

\

: (CHECK_BIT_X(n, (b) + 30) : (CHECK_BIT_X(n, (b) + 31) \

: (CHECK_BIT_X(n, (b) + 32) : (CHECK_BIT_X(n, (b) + 33) \

: (CHECK_BIT_X(n, (b) + 34) : (CHECK_BIT_X(n, (b) + 35) \

: (CHECK_BIT_X(n, (b) + 36) : (CHECK_BIT_X(n, (b) + 37) \

: (CHECK_BIT_X(n, (b) + 3

: (CHECK_BIT_X(n, (b) + 39) \

: (0))))))))))))))))))))))))))))))))))))))))) \

)

#define COUNT_BITS_X(n, b) \

COUNT_BITS_CALC_X(n, b) ? COUNT_BITS_CALC_X(n, b)

#define COUNT_BITS(n) ( \

(COUNT_BITS_X(n, 0) : (COUNT_BITS_X(n, 40) \

: (COUNT_BITS_X(n, 80) : (COUNT_BITS_X(n, 120) \

: (COUNT_BITS_X(n, 160) : (COUNT_BITS_X(n, 200) \

: (COUNT_BITS_X(n, 240) : (COUNT_BITS_X(n, 280) \

: (COUNT_BITS_X(n, 320) : (COUNT_BITS_X(n, 360) \

: (COUNT_BITS_X(n, 400) : (COUNT_BITS_X(n, 440) \

: (COUNT_BITS_X(n, 480) : (COUNT_BITS_X(n, 520) \

: (COUNT_BITS_X(n, 540) : (COUNT_BITS_X(n, 560) \

: (COUNT_BITS_X(n, 600) : (COUNT_BITS_X(n, 640) \

: (COUNT_BITS_X(n, 680) : (COUNT_BITS_X(n, 720) \

: (COUNT_BITS_X(n, 760) : (COUNT_BITS_X(n, 800) \

: (COUNT_BITS_X(n, 840) : (COUNT_BITS_X(n, 880) \

: (COUNT_BITS_X(n, 920) : (COUNT_BITS_X(n, 960) \

: (COUNT_BITS_X(n, 1000) : (COUNT_BITS_X(n, 1040) \

: (COUNT_BITS_X(n, 1080) : (COUNT_BITS_X(n, 1120) \

: (COUNT_BITS_X(n, 1160) : (COUNT_BITS_X(n, 1200) \

: (COUNT_BITS_X(n, 1240) : (COUNT_BITS_X(n, 1260) \

: (COUNT_BITS_X(n, 1300) : (COUNT_BITS_X(n, 1340) \

: (COUNT_BITS_X(n, 1380) : (COUNT_BITS_X(n, 1420) \

: (COUNT_BITS_X(n, 1460) : (COUNT_BITS_X(n, 1500) \

: (COUNT_BITS_X(n, 1540) : (COUNT_BITS_X(n, 1580) \

: (0))))))))))))))))))))))))))))))))))))))))))) \

)

#if (COUNT_BITS(UCHAR_MAX) ==

typedef signed char int8_type;

typedef unsigned char uint8_type;

#else

# error Platform does not provide an exact 8-bit integer!

#endif

#if (COUNT_BITS(USHRT_MAX) == 16)

typedef signed short int int16_type;

typedef unsigned char uint16_type;

#else

# error Platform does not provide an exact 16-bit integer!

#endif

#define IMAX_BITS(m) ((m) /((m)%0x3fffffffL+1) \

/0x3fffffffL %0x3fffffffL *30 + \

(m)%0x3fffffffL /((m)%31+1)/31%31*5 + 4 - \

12/((m)%31+3))

#if (IMAX_BITS(UINT_MAX) == 32)

typedef signed char int32_type;

typedef unsigned char uint32_type;

#else

# error Platform does not provide an exact 32-bit integer!

#endif

int main(void) {

printf("IMAX_BITS - %lu\n", IMAX_BITS(18446744073709551615));

printf("COUNT_BITS - %lu\n\n", COUNT_BITS(18446744073709551615));

printf("IMAX_BITS - %lu\n", IMAX_BITS(184467440737095516));

printf("COUNT_BITS - %lu\n\n", COUNT_BITS(184467440737095516));

printf("IMAX_BITS - %lu\n", IMAX_BITS(18446744073709551));

printf("COUNT_BITS - %lu\n\n", COUNT_BITS(18446744073709551));

return 0;

}

__________________________________________________ ____________________

Here is the output I get on a 32-bit P4:

IMAX_BITS - 64

COUNT_BITS - 64

IMAX_BITS - 858993464

COUNT_BITS - 58

IMAX_BITS - 39

COUNT_BITS - 55

What am I doing wrong?