#include #include #define MORT 24 #define mult16(x,k) \ ((x>>16)*k+((((x&0xFFFF)*k)+(1<<15))>>16)) static int val[65]; void init_amortize_tab() { unsigned int i,v; v=1<<16; val[0]=v; for(i=1;i<=32;++i) { v=((v*(MORT-1))+(MORT/2))/MORT; val[i]=v; printf("tab %d %d\n",i,v); } for(i=33;i<=64;++i) { v=((v*(val[32]))+(1<<15))>>16; val[i]=v; printf("tab %d %d\n",i,v); } } int amortize(int b, int d) /* returns b*((MORT-1)/MORT)**d, that is, b depreciated for d turns at 1/MORT per turn. Requires val[] to have been set up by init_amortize_tab() MORT must be >0 and < 2**15. (given 32-bit int) d must be >= 0 four or five times faster than static double MULTIPLIER = ((double)MORT - 1) / MORT; return (int)(0.5 + ( b * pow( MULTIPLIER, d ))); at minor cost in accuracy */ { int s=1; int rough; assert(d>=0); if ( b < 0 ) { s=-1; b *= s; } if ( d <= 32 ) return s*mult16(b,val[d]); while (( d > 1024 ) && b ) { b=mult16(b,val[64]); d-=1024; } rough=mult16(b,val[d/32+31]); return s*mult16(rough,val[d%32]); }