001    
002    package ibxm;
003    
004    /*
005        Base-2 Log and Exp functions, using linear-interpolated tables.
006    */
007    public class LogTable {
008        private static final int TABLE_SHIFT = 7; // 128 points (+1 for interp)
009        private static final int INTERP_SHIFT = IBXM.FP_SHIFT - TABLE_SHIFT;
010        private static final int INTERP_MASK = ( 1 << INTERP_SHIFT ) - 1;
011    
012        private static final int[] exp_2_table = {
013            32768, 32945, 33124, 33304, 33485, 33667, 33850, 34033,
014            34218, 34404, 34591, 34779, 34968, 35157, 35348, 35540,
015            35733, 35927, 36122, 36319, 36516, 36714, 36913, 37114,
016            37315, 37518, 37722, 37926, 38132, 38339, 38548, 38757,
017            38967, 39179, 39392, 39606, 39821, 40037, 40254, 40473,
018            40693, 40914, 41136, 41359, 41584, 41810, 42037, 42265,
019            42494, 42725, 42957, 43190, 43425, 43661, 43898, 44136,
020            44376, 44617, 44859, 45103, 45347, 45594, 45841, 46090,
021            46340, 46592, 46845, 47099, 47355, 47612, 47871, 48131,
022            48392, 48655, 48919, 49185, 49452, 49720, 49990, 50262,
023            50535, 50809, 51085, 51362, 51641, 51922, 52204, 52487,
024            52772, 53059, 53347, 53636, 53928, 54220, 54515, 54811,
025            55108, 55408, 55709, 56011, 56315, 56621, 56928, 57238,
026            57548, 57861, 58175, 58491, 58809, 59128, 59449, 59772,
027            60096, 60423, 60751, 61081, 61412, 61746, 62081, 62418,
028            62757, 63098, 63440, 63785, 64131, 64479, 64830, 65182,
029            65536
030        };
031    
032        private static final int[] log_2_table = {
033                0,   367,   732,  1095,  1454,  1811,  2165,  2517,
034             2865,  3212,  3556,  3897,  4236,  4572,  4906,  5238,
035             5568,  5895,  6220,  6542,  6863,  7181,  7497,  7812,
036             8124,  8434,  8742,  9048,  9352,  9654,  9954, 10252,
037            10548, 10843, 11136, 11427, 11716, 12003, 12289, 12573,
038            12855, 13136, 13414, 13692, 13967, 14241, 14514, 14785,
039            15054, 15322, 15588, 15853, 16117, 16378, 16639, 16898,
040            17156, 17412, 17667, 17920, 18172, 18423, 18673, 18921,
041            19168, 19413, 19657, 19900, 20142, 20383, 20622, 20860,
042            21097, 21333, 21568, 21801, 22034, 22265, 22495, 22724,
043            22952, 23178, 23404, 23628, 23852, 24074, 24296, 24516,
044            24736, 24954, 25171, 25388, 25603, 25817, 26031, 26243,
045            26455, 26665, 26875, 27084, 27292, 27499, 27705, 27910,
046            28114, 28317, 28520, 28721, 28922, 29122, 29321, 29519,
047            29716, 29913, 30109, 30304, 30498, 30691, 30884, 31076,
048            31267, 31457, 31646, 31835, 32023, 32210, 32397, 32582,
049            32768
050        };
051    
052        /*
053            Calculate log-base-2 of x (non-fixed-point).
054            A fixed point value is returned.
055        */
056        public static int log_2( int x ) {
057            int shift;
058            /* Scale x to range 1.0 <= x < 2.0 */
059            shift = IBXM.FP_SHIFT;
060            while( x < IBXM.FP_ONE ) {
061                x <<= 1;
062                shift--;
063            }
064            while( x >= ( IBXM.FP_ONE << 1 ) ) {
065                x >>= 1;
066                shift++;
067            }
068            return ( IBXM.FP_ONE * shift ) + eval_table( log_2_table, x - IBXM.FP_ONE );
069        }
070    
071        /*
072            Raise 2 to the power x (fixed point).
073            A fixed point value is returned.
074        */
075        public static int raise_2( int x ) {
076            int y;
077            y = eval_table( exp_2_table, x & IBXM.FP_MASK ) << IBXM.FP_SHIFT;
078            return y >> IBXM.FP_SHIFT - ( x >> IBXM.FP_SHIFT );
079        }
080    
081        private static int eval_table( int[] table, int x ) {
082            int table_idx, table_frac, c, m, y;
083            table_idx = x >> INTERP_SHIFT;
084            table_frac = x & INTERP_MASK;
085            c = table[ table_idx ];
086            m = table[ table_idx + 1 ] - c;
087            y = ( m * table_frac >> INTERP_SHIFT ) + c;
088            return y >> 15 - IBXM.FP_SHIFT;
089        }
090    }
091