#include #include #include #include #include static unsigned short log2_table[17]; void generate_log2_table (void) { int i; for(i=0;i<16;i++) log2_table[i]=(unsigned short)(4096.0*log(1.0+(((double)i)/16.0))/log(2)); } /* fflog2 works. IN : 16-bit integer OUT: 16-bit integer as a fixedpoint 4.12-bit integer now */ unsigned short fflog2 (unsigned short x) { unsigned i = 15; /* integer part */ unsigned j; /* fractional part */ if (!x) return 0; if (x < (1<<8)) { x <<= 8; i -= 8; } if (x < (1<<12)) { x <<= 4; i -= 4; } if (x < (1<<14)) { x <<= 2; i -= 2; } if (x < (1<<15)) { x <<= 1; i -= 1; } x <<= 1; j = x >> 12; return /* integer part */ (i<<12) | /* fractional part */ (log2_table[j] + (((x & 0xfff) << 12) * (log2_table[j+1] - log2_table[j]))); } /* fflog10 works */ unsigned short fflog10 (unsigned short x) { return (fflog2(x) * (unsigned)(4096.0*(0.30102999566398119521373889472449/*log10(2)*/))) >> 12; } int main (int argc, char *argv[]) { generate_log2_table(); short test1 = (unsigned short)((1<<15)-1); short test2 = (unsigned short)((1<<14)+(1<<12)-1); short test3 = (unsigned short)((1<<14)+(1<<10)); short test4 = (unsigned short)((1<<10)+(1<<8)-1); short test5 = (unsigned short)((1<<8)+(1<<3)); short test6 = (unsigned short)((1<<6)+(1<<3)); short test7 = (unsigned short)((1<<4)+(1<<1)); short test8 = (unsigned short)((1<<4)-1); cout << "fflog10(" << test1 << ") = " << double(fflog10(test1)) / 4096.0 << endl; cout << "fflog10(" << test2 << ") = " << double(fflog10(test2)) / 4096.0 << endl; cout << "fflog10(" << test3 << ") = " << double(fflog10(test3)) / 4096.0 << endl; cout << "fflog10(" << test4 << ") = " << double(fflog10(test4)) / 4096.0 << endl; cout << "fflog10(" << test5 << ") = " << double(fflog10(test5)) / 4096.0 << endl; cout << "fflog10(" << test6 << ") = " << double(fflog10(test6)) / 4096.0 << endl; cout << "fflog10(" << test7 << ") = " << double(fflog10(test7)) / 4096.0 << endl; cout << "fflog10(" << test8 << ") = " << double(fflog10(test8)) / 4096.0 << endl; cout << "Press ENTER to continue..." << endl; getchar (); return 0; } #if 0 static unsigned short log10_table[17]; void generate_log10_table (void) { int i; for(i=0;i<16;i++) log10_table[i]=(unsigned short)(4096.0*65536.0*log(1.0+(((double)i)/16.0))/log(10)); } #define FFLOG10_2 4096.0*(0.30102999566398119521373889472449/*log10(2)*/) unsigned short fflog10 (unsigned short x) { unsigned i = (unsigned)(4096.0*4.5154499349597179282060834208674/*log10(2^15)*/); unsigned j; if (!x) return 0; if (x < (1<<8)) { x <<= 8; i -= (unsigned)(8.0*FFLOG10_2); /* 8 * log10(2) */ } if (x < (1<<12)) { x <<= 4; i -= (unsigned)(4.0*FFLOG10_2); /* 4 * log10(2) */ } if (x < (1<<14)) { x <<= 2; i -= (unsigned)(2.0*FFLOG10_2); /* 2 * log10(2) */ } if (x < (1<<15)) { x <<= 1; i -= (unsigned)(1.0*FFLOG10_2); /* 1 * log10(2) */ } x <<= 1; j = x >> 12; return /* integer part */ (i >> 16) | /* fractional part */ (log10_table[j] + (((x & 0xfff) << 12) * (log10_table[j+1] - log10_table[j]))); } #endif