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