From 798b2b1435fd2e6f4b51c55af219ff01c685db1d Mon Sep 17 00:00:00 2001 From: erdgeist Date: Mon, 6 Oct 2014 17:25:51 +0200 Subject: Clean up table generator --- generate_table.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 67 insertions(+), 9 deletions(-) diff --git a/generate_table.c b/generate_table.c index c7a9d0c..9fd05bc 100644 --- a/generate_table.c +++ b/generate_table.c @@ -6,6 +6,59 @@ // s( 1) n(-4) off( 0) x = ( x << 4 ) // s( 1) n( 8) off(-1) x = - x + ( x << 8 ) +typedef enum { use_2pn, use_1_2pn, use_2pm_2pn, use_1_2pm_2pn } tr_flag; +typedef struct { + double factor; + int n; + int m; + int nsign; + tr_flag flag; +} table_record; + +static int g_records; +static table_record g_tr[8192]; + +static int compare_record( const void *a, const void *b ) { + if( ((table_record*)a)->factor > ((table_record*)b)->factor ) + return 1; + if( ((table_record*)a)->factor < ((table_record*)b)->factor ) + return -1; + return 0; +} + +static void add_record( double v, int n, int nsign, int m, tr_flag flag ) +{ + g_tr[g_records].factor = v; + g_tr[g_records].n = n; + g_tr[g_records].m = m; + g_tr[g_records].nsign = nsign; + g_tr[g_records].flag = flag; + ++g_records; +} + +static void dump_record( int record ) +{ + if( record >= g_records ) return; // should warn? + double factor = g_tr[record].factor; + int n = g_tr[record].n; + int m = g_tr[record].m; + int nsign = g_tr[record].nsign; + tr_flag flag = g_tr[record].flag; + + switch( flag ) { + case use_2pn: + printf( "%0+25.21lf x = x %s %2d\n", factor, n>=0?"<<":">>", (int)abs(n) ); + break; + case use_1_2pn: + printf( "%0+25.21lf x%s= x %s %2d\n", factor, nsign==-1?"-":"+", n>=0?"<<":">>", (int)abs(n) ); + break; + case use_2pm_2pn: + case use_1_2pm_2pn: + printf( "%0+25.21lf x%s= ( x %s %2d ) %s ( x %s %2d )\n", factor, flag==use_2pm_2pn?" ":"-", m>=0?"<<":">>", (int)abs(m), nsign==-1?"-":"+", n>=0?"<<":">>", (int)abs(n)); + break; + } +} + int main() { int n, m, nsign; @@ -14,21 +67,26 @@ int main() { for ( nsign=-1; nsign<=1; nsign+=2 ) { // The one term only case - double v = (double)nsign * pow( 2.f, (double)n ); - if( v > 0.f ) - printf( "%0+25.21lf %08X x = %s ( x %s %2d )%s\n", log(v), abs((int)(67108864.f*log(v))), nsign==-1?"-":" ", n>=0?"<<":">>", (int)abs(n), " !RECOMMENDED!" ); + double v = (double)nsign * pow( 2., (double)n ); + if( v > 0.0 ) + add_record( log(v), n, nsign, m, use_2pn ); // Loop over second term for (m=-31; m<=31; ++m ) { - double v = pow( 2.f, (double)m ) + (double)nsign * pow( 2.f, (double)n ); - if( v > 0.f ) { - printf( "%0+25.21lf %08X x = ( x %s %2d ) %s ( x %s %2d )%s\n", log(v), abs((int)(67108864.f*log(v))), m>=0?"<<":">>", (int)abs(m), nsign==-1?"-":"+", n>=0?"<<":">>", (int)abs(n), n*m?"":" !RECOMMENDED!" ); - if( v < 1.f ) - printf( "%0+25.21lf %08X x-= ( x %s %2d ) %s ( x %s %2d )\n", log(1.0f - v), abs((int)(67108864.f*log(1.0f - v))), m>=0?"<<":">>", (int)abs(m), nsign==-1?"-":"+", n>=0?"<<":">>", (int)abs(n) ); - } + double v = pow( 2.0, (double)m ) + (double)nsign * pow( 2., (double)n ); + if( v <= 0.0 ) + continue; + add_record( log(v), n, nsign, m, m ? use_2pm_2pn : use_1_2pn ); + if( v < 1.0 ) + add_record( log(1.0 - v), n, nsign, m, use_1_2pm_2pn ); } } + qsort( g_tr, g_records, sizeof(*g_tr), compare_record ); + + for (n=0; n