#include #include #include // s(-1) n(14) off(+1) x = x - ( x >> 14 ) // 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; // loop over all constructs in the form +-1*x^+-2n, n=-31..+31 for (n=-31; n<= 31; ++n ) for ( nsign=-1; nsign<=1; nsign+=2 ) { // The one term only case 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.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