#if 0 These are instructions for making a hexadecimal slide rule. This can be very handy when you need to do math in base 16, but don't need exact results. For example, when you need to know about where in memory a variable is stored. To make it more usefull for binary math, rather than doing the scales in natural logs, or log base 10, they are done in log base two. By adding a linear scale to one of the rules, it will be possible to use it calculate base two logs and exponents. Usefull when converting numbers to floating point. The output of the program below is a number in decimal, it's log base 2 and it's position on the scale. GRAIN is the granularity of the numbers. A GRAIN of 64 will compute the log for 64 numbers between each integer. Fine is the fineness of the scale used to mark the logs. If FINE is 32, then the postion will be printed out in 32nds of an inch. LENGTH is the length of the scale. If the LENGTH is 12, then with 1 at positon 0 then 16 (or 10 hex) will be at positon 12. #endif #include #include #define GRAIN 64 #define FINE 32 #define LENGTH 12.0 #define SCALE LENGTH/4.0 void main (void) { float n; /* number */ float lnof2; /* natural log of 2 */ float l2; /* log base 2 */ float ln; /* natural log */ float dist; /* distance or position */ float rmdr; /* remainder */ double wholef; /* whole portion of log2 */ double frac10; /* fraction base 10 */ int dig1,dig2; /* Hex digits to rt of radix */ int i,j; int whole; /* whole portion of log2 */ int m2; /* whole portion of n */ int frac; /* fraction portion of log2 */ lnof2 = log(2); /* Compute once */ /* Print Header */ printf(" decimal hex log2 position\n"); for (i = GRAIN; i <= GRAIN * 16; i++) { n = (float)i/GRAIN; /* split each number into */ m2 = (int) n; /* integer and fraction parts */ frac10 = n - m2; j = (int) (frac10 * 16 * 16); /* Compute fraction in hex */ dig1 = j / 16; dig2 = j - (dig1*16); l2 = log(n)/lnof2; /* Compute log base 2 and */ dist = l2 * SCALE; /* position */ rmdr = modf(dist, &wholef); whole= (int)wholef; frac = (int)(rmdr*FINE); printf("%8.4f ", n); /* print table entry */ printf(" %02x.%0x%0x ",m2, dig1, dig2); printf("%6.4f %3i %02i/%02i\n", l2, whole, frac, FINE); } }