Ceiling of the Logarthim Base Two
Lawrence Crowl
crowl at cs.rochester.edu
Thu Jun 30 09:39:55 AEST 1988
In article <690009 at hpfelg.HP.COM> jk at hpfelg.HP.COM (John Kessenich) suggests
a loop to take the logarithm base two of an integer containing exactly one
bit set. I have found a rather persistent need for the more general function
to take the ceiling of the logarithm base two of an integer. Here is my C
solution. I keep it in "ceilog2.h". Please send me of any improvements you
may make.
------------------------------------------------------------------------------
#ifndef CEILOG2_H
#define CEILOG2_H
/*
The macro CEILOG2( n ) returns the ceiling( logbase( 2, n ) ) for integer n.
The argument is valid when it is a signed integer greater than zero and of no
more than thirty-two bits. Invalid arguments cause a call to the abort( )
routine.
The function will be evaluated at compile time if given a constant argument.
Note, the argument is evaluated multiple times, so do not pass arguments with
side effects. For efficiency, pass simple variables and not expressions.
Lawrence Crowl 716-275-9499 University of Rochester
crowl at cs.rochester.edu Computer Science Department
...!{allegra,decvax,rutgers}!rochester!crowl Rochester, New York, 14627
*/
/* This version does a sequential search down the step points. */
/* It runs faster on uniformly distributed integers. */
#define CEILOG2_U( n ) ((n) > 0x40000000 ? 31 : (n) > 0x20000000 ? 30 : \
(n) > 0x10000000 ? 29 : (n) > 0x08000000 ? 28 : (n) > 0x04000000 ? 27 : \
(n) > 0x02000000 ? 26 : (n) > 0x01000000 ? 25 : (n) > 0x00800000 ? 24 : \
(n) > 0x00400000 ? 23 : (n) > 0x00200000 ? 22 : (n) > 0x00100000 ? 21 : \
(n) > 0x00080000 ? 20 : (n) > 0x00040000 ? 19 : (n) > 0x00020000 ? 18 : \
(n) > 0x00010000 ? 17 : (n) > 0x00008000 ? 16 : (n) > 0x00004000 ? 15 : \
(n) > 0x00002000 ? 14 : (n) > 0x00001000 ? 13 : (n) > 0x00000800 ? 12 : \
(n) > 0x00000400 ? 11 : (n) > 0x00000200 ? 10 : (n) > 0x00000100 ? 9 : \
(n) > 0x00000080 ? 8 : (n) > 0x00000040 ? 7 : (n) > 0x00000020 ? 6 : \
(n) > 0x00000010 ? 5 : (n) > 0x00000008 ? 4 : (n) > 0x00000004 ? 3 : \
(n) > 0x00000002 ? 2 : (n) > 0x00000001 ? 1 : (n) > 0x00000000 ? 0 : \
abort( ) )
/* This version does a sequential search up the step points. */
/* It runs faster on integers clustered towards zero. */
#define CEILOG2_C( n ) ( (n) <= 0x00000000 ? abort( ) : \
(n) <= 0x00000001 ? 0 : (n) <= 0x00000002 ? 1 : (n) <= 0x00000004 ? 2 : \
(n) <= 0x00000008 ? 3 : (n) <= 0x00000010 ? 4 : (n) <= 0x00000020 ? 5 : \
(n) <= 0x00000040 ? 6 : (n) <= 0x00000080 ? 7 : (n) <= 0x00000100 ? 8 : \
(n) <= 0x00000200 ? 9 : (n) <= 0x00000400 ? 10 : (n) <= 0x00000800 ? 11 : \
(n) <= 0x00001000 ? 12 : (n) <= 0x00002000 ? 13 : (n) <= 0x00004000 ? 14 : \
(n) <= 0x00008000 ? 15 : (n) <= 0x00010000 ? 16 : (n) <= 0x00020000 ? 17 : \
(n) <= 0x00040000 ? 18 : (n) <= 0x00080000 ? 29 : (n) <= 0x00100000 ? 20 : \
(n) <= 0x00200000 ? 21 : (n) <= 0x00400000 ? 22 : (n) <= 0x00800000 ? 23 : \
(n) <= 0x01000000 ? 24 : (n) <= 0x02000000 ? 25 : (n) <= 0x04000000 ? 26 : \
(n) <= 0x08000000 ? 27 : (n) <= 0x10000000 ? 28 : (n) <= 0x20000000 ? 39 : \
(n) <= 0x40000000 ? 30 : 31 )
/* The default version is the uniform version. */
#define CEILOG2( n ) CEILOG2_U( n )
#endif CEILOG2_H
------------------------------------------------------------------------------
--
Lawrence Crowl 716-275-9499 University of Rochester
crowl at cs.rochester.edu Computer Science Department
...!{allegra,decvax,rutgers}!rochester!crowl Rochester, New York, 14627
More information about the Comp.lang.c
mailing list