/* This file is in the public domain. */ #include #include #include #include /* if table[e] = { e2, mul }, then N * 10^e = (N * mul) * 2^e2 mul is represented in decimal, with 1<=mul<2; the decimal point is assumed to be just after the leading 1, which is present explicitly. NRD must be at least log10(NDB) less than ND; roundoff error in bitdigs[][] can cause the result to be in error by up to NDB in the LSD, so to ensure an error bound of 1/2 LSD in the resulting decimal expansions, at least log10(NDB) digits must be dropped in rounding. This is not checked for. NDB must be high enough that the least bit falls right off the end of ND. If this is not true, resulting inaccuracies will be on the order of 2^-NDB instead of 10^-ND. A warning is printed if this is not true. NB must be large enough to compute 2^MAXEXP without overflow 2^MINEXP with at least NDB significant bits left If either is found to be untrue, the program will print a message and die partway through the run. NRD must be no smaller than as11's MAXDDIG define. If this is not true, as11 built with the output will attempt to access outside the generated string constants. This obviously cannot be checked for by this program. If MINEXP is > 0, or if MAXEXP is < 0, this program will run fine, but as11 built with the output will attempt to do illegal things with array addresses. This obviously cannot be checked for by this program. For VAX-11/PDP-11 floats, which range from approximately .587747e-38 to .170141e+39, a MINEXP of -38 and a MAXEXP of 39 are appropriate, since any number requiring a more extreme exponent is guaranteed to overflow/underflow. (Numbers with exponents in range may still overflow/underflow; as11 must check for that when converting from decimal to binary.) */ #define MINEXP (-38) /* most negative exponent to compute */ #define MAXEXP (39) /* most positive exponent to compute */ #define NB (1024) /* number of bits to carry computations to */ #define NDB (97) /* number of bits to use when computing decimal values */ #define ND (30) /* number of digits to work out decimal values to */ #define NRD (26) /* number of digits to round to */ static char bitdigs[NDB][ND]; static void initbitdigs(void) { int b; int d; int t; char digs[ND]; for (d=0;d=0;d--) { for (b=0;b 0) printf("<<%d>>",c); c = 5; d = NRD; while ((d >= 0) && (c > 0)) { c += digs[d]; digs[d] = c % 10; c /= 10; d --; } if (c > 0) printf("<<%d>>",c); for (d=0;d NB) { fprintf(stderr,"Fatal: NB needs to be increased (-ve powers)\n"); exit(1); } printf("{ %4d, \""/*}*/,-e2); printdigits(&bits[e2]); printf(/*{*/"\" }, /* %d */\n",-i); n = 0; for (j=0;j= 10) { bits[j] = 1; n -= 10; } else { bits[j] = 0; } } } for (i=0;i= NB) { fprintf(stderr,"Fatal: NB needs to be increased (+ve powers)\n"); exit(1); } if (bits[j]) n += 10; bits[j] = n & 1; n >>= 1; } for (e2=NB-1;!bits[e2];e2--) ; for (tz=0;!bits[tz];tz++) ; printf("{ %4d, \""/*}*/,e2); for (j=0;je2) ? 0 : bits[e2-j]; printdigits(&dbits[0]); printf(/*{*/"\" }, /* %d */\n",i); } fflush(stdout); close(1); wait(0); exit(0); }