tomwalters@0: /* tomwalters@0: imb.c tomwalters@0: ===== tomwalters@0: tomwalters@0: integer version of logarithms using units of milliBells. tomwalters@0: tomwalters@0: */ tomwalters@0: tomwalters@0: #include tomwalters@0: tomwalters@0: #include "stitch.h" tomwalters@0: tomwalters@0: #define LOG_ZERO (-10) tomwalters@0: tomwalters@0: int imB( number ) tomwalters@0: long number ; tomwalters@0: { tomwalters@0: register int i, out ; tomwalters@0: register long in ; tomwalters@0: static int precision = 12 ; tomwalters@0: static int *table = { ( int * ) 0 } ; tomwalters@0: static unsigned table_size ; tomwalters@0: static int inc ; tomwalters@0: double k ; tomwalters@0: tomwalters@0: if( table == ( int * ) 0 ) { tomwalters@0: tomwalters@0: table_size = 1 << precision ; tomwalters@0: tomwalters@0: k = 2000. / log( 10. ) ; tomwalters@0: inc = k * log( 2. ) + 0.5 ; tomwalters@0: tomwalters@0: table = (int *) stitch_malloc( table_size * sizeof( *table ), "imb.c for log table" ) ; tomwalters@0: tomwalters@0: for( i=0 ; i < table_size ; i++ ) tomwalters@0: table[ i ] = log( (double) ( table_size + i ) / table_size ) * k + 0.5 ; tomwalters@0: } tomwalters@0: tomwalters@0: if( number > 0 ) { tomwalters@0: tomwalters@0: in = number ; tomwalters@0: tomwalters@0: out = precision * inc ; tomwalters@0: tomwalters@0: if( number < table_size ) tomwalters@0: do { tomwalters@0: in <<= 1 ; tomwalters@0: out -= inc ; tomwalters@0: } tomwalters@0: while( in < table_size ) ; tomwalters@0: else tomwalters@0: while( in - table_size >= table_size ) { tomwalters@0: in >>= 1 ; tomwalters@0: out += inc ; tomwalters@0: } tomwalters@0: tomwalters@0: return( out + table[ in - table_size ] ) ; tomwalters@0: } tomwalters@0: else tomwalters@0: return ( LOG_ZERO ) ; tomwalters@0: } tomwalters@0: