|
|
1.1 ! root 1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ ! 2: ! 3: /* ! 4: $Header: mkconfig.c,v 1.4 85/08/26 10:41:39 timo Exp $ ! 5: */ ! 6: ! 7: /* Generate constants for configuration file */ ! 8: ! 9: /* If your C system is not unix but does have signal/setjmp, */ ! 10: /* add a #define unix */ ! 11: /* You may also need to add some calls to signal(). */ ! 12: ! 13: #ifdef unix ! 14: ! 15: #define SIGNAL ! 16: ! 17: #include <signal.h> ! 18: #include <setjmp.h> ! 19: ! 20: jmp_buf lab; ! 21: overflow(sig) int sig; { /* what to do on overflow/underflow */ ! 22: signal(sig, overflow); ! 23: longjmp(lab, 1); ! 24: } ! 25: ! 26: #else ! 27: /* Dummy routines instead */ ! 28: int lab=1; ! 29: int setjmp(lab) int lab; { return(0); } ! 30: ! 31: #endif ! 32: ! 33: #define fabs(x) (((x)<0.0)?(-x):(x)) ! 34: #define min(x,y) (((x)<(y))?(x):(y)) ! 35: ! 36: /* These routines are intended to defeat any attempt at optimisation */ ! 37: Dstore(a, b) double a, *b; { *b=a; } ! 38: double Dsum(a, b) double a, b; { double r; Dstore(a+b, &r); return (r); } ! 39: double Ddiff(a, b) double a, b; { double r; Dstore(a-b, &r); return (r); } ! 40: double Dmul(a, b) double a, b; { double r; Dstore(a*b, &r); return (r); } ! 41: double Ddiv(a, b) double a, b; { double r; Dstore(a/b, &r); return (r); } ! 42: ! 43: double power(x, n) int x, n; { ! 44: double r=1.0; ! 45: for (;n>0; n--) r*=x; ! 46: return r; ! 47: } ! 48: ! 49: int log(base, x) int base; double x; { ! 50: int r=0; ! 51: while (x>=base) { r++; x/=base; } ! 52: return r; ! 53: } ! 54: ! 55: main(argc, argv) int argc; char *argv[]; { ! 56: char c; ! 57: short newshort, maxshort, maxershort; ! 58: int newint, maxint, shortbits, bits, mantbits, ! 59: *p, shortpower, intpower, longpower; ! 60: long newlong, maxlong, count; ! 61: ! 62: int i, ibase, iexp, irnd, imant, iz, k, machep, maxexp, minexp, ! 63: mx, negeps, ngrd, normalised; ! 64: double a, b, base, basein, basem1, eps, epsneg, xmax, newxmax, ! 65: xmin, xminner, y, y1, z, z1, z2; ! 66: ! 67: double BIG, Maxreal; ! 68: int BASE, MAXNUMDIG, ipower, tenlogBASE, Maxexpo, Minexpo, Dblbits; ! 69: ! 70: #ifdef SIGNAL ! 71: signal(SIGFPE, overflow); ! 72: if (setjmp(lab)!=0) { printf("Unexpected over/underflow\n"); exit(1); } ! 73: #endif ! 74: ! 75: /****** Calculate max short *********************************************/ ! 76: /* Calculate 2**n-1 until overflow - then use the previous value */ ! 77: ! 78: newshort=1; maxshort=0; ! 79: ! 80: if (setjmp(lab)==0) ! 81: for(shortpower=0; newshort>maxshort; shortpower++) { ! 82: maxshort=newshort; ! 83: newshort=newshort*2+1; ! 84: } ! 85: ! 86: /* Now for those daft Cybers: */ ! 87: ! 88: maxershort=0; newshort=maxshort; ! 89: ! 90: if (setjmp(lab)==0) ! 91: for(shortbits=shortpower; newshort>maxershort; shortbits++) { ! 92: maxershort=newshort; ! 93: newshort=newshort+newshort+1; ! 94: } ! 95: ! 96: bits= (shortbits+1)/sizeof(short); ! 97: c= (char)(-1); ! 98: printf("/\* char=%d bits, %ssigned *\/\n", sizeof(c)*bits, ! 99: ((int)c)<0?"":"un"); ! 100: printf("/\* maxshort=%d (=2**%d-1) *\/\n", maxshort, shortpower); ! 101: ! 102: if (maxershort>maxshort) { ! 103: printf("/\* There is a larger maxshort, %d (=2**%d-1), %s *\/\n", ! 104: maxershort, shortbits, ! 105: "but only for addition, not multiplication"); ! 106: } ! 107: ! 108: /****** Calculate max int by the same method ***************************/ ! 109: ! 110: newint=1; maxint=0; ! 111: ! 112: if (setjmp(lab)==0) ! 113: for(intpower=0; newint>maxint; intpower++) { ! 114: maxint=newint; ! 115: newint=newint*2+1; ! 116: } ! 117: ! 118: printf("/\* maxint=%d (=2**%d-1) *\/\n", maxint, intpower); ! 119: ! 120: /****** Calculate max long by the same method ***************************/ ! 121: ! 122: newlong=1; maxlong=0; ! 123: ! 124: if (setjmp(lab)==0) ! 125: for(longpower=0; newlong>maxlong; longpower++) { ! 126: maxlong=newlong; ! 127: newlong=newlong*2+1; ! 128: } ! 129: ! 130: if (setjmp(lab)!=0) { printf("\nUnexpected under/overflow\n"); exit(1); } ! 131: ! 132: printf("/\* maxlong=%ld (=2**%d-1) *\/\n", maxlong, longpower); ! 133: ! 134: /****** Pointers ********************************************************/ ! 135: printf("/\* pointers=%d bits%s *\/\n", sizeof(p)*bits, ! 136: sizeof(p)>sizeof(int)?" BEWARE! larger than int!":""); ! 137: ! 138: /****** Base and size of mantissa ***************************************/ ! 139: a=1.0; ! 140: do { a=Dsum(a, a); } while (Ddiff(Ddiff(Dsum(a, 1.0), a), 1.0) == 0.0); ! 141: b=1.0; ! 142: do { b=Dsum(b, b); } while ((base=Ddiff(Dsum(a, b), a)) == 0.0); ! 143: ibase=base; ! 144: printf("/\* base=%d *\/\n", ibase); ! 145: ! 146: imant=0; b=1.0; ! 147: do { imant++; b=Dmul(b, base); } ! 148: while (Ddiff(Ddiff(Dsum(b,1.0),b),1.0) == 0.0); ! 149: printf("/\* Significant base digits=%d *\/\n", imant); ! 150: ! 151: /****** Various flavours of epsilon *************************************/ ! 152: basem1=Ddiff(base,1.0); ! 153: if (Ddiff(Dsum(a, basem1), a) != 0.0) irnd=1; ! 154: else irnd=0; ! 155: ! 156: negeps=imant+imant; ! 157: basein=1.0/base; ! 158: a=1.0; ! 159: for(i=1; i<=negeps; i++) a*=basein; ! 160: ! 161: b=a; ! 162: while (Ddiff(Ddiff(1.0, a), 1.0) == 0.0) { ! 163: a*=base; ! 164: negeps--; ! 165: } ! 166: negeps= -negeps; ! 167: printf("/\* Smallest x such that 1.0-base**x != 1.0=%d *\/\n", negeps); ! 168: ! 169: epsneg=a; ! 170: if ((ibase!=2) && (irnd==1)) { ! 171: /* a=(a*(1.0+a))/(1.0+1.0); => */ ! 172: a=Ddiv(Dmul(a, Dsum(1.0, a)), Dsum(1.0, 1.0)); ! 173: /* if ((1.0-a)-1.0 != 0.0) epsneg=a; => */ ! 174: if (Ddiff(Ddiff(1.0, a), 1.0) != 0.0) epsneg=a; ! 175: } ! 176: printf("/\* Small x such that 1.0-x != 1.0=%g *\/\n", epsneg); ! 177: /* it may not be the smallest */ ! 178: ! 179: machep= -imant-imant; ! 180: a=b; ! 181: while (Ddiff(Dsum(1.0, a), 1.0) == 0.0) { a*=base; machep++; } ! 182: printf("/\* Smallest x such that 1.0+base**x != 1.0=%d *\/\n", machep); ! 183: ! 184: eps=a; ! 185: if ((ibase!=2) && (irnd==1)) { ! 186: /* a=(a*(1.0+a))/(1.0+1.0); => */ ! 187: a=Ddiv(Dmul(a, Dsum(1.0, a)), Dsum(1.0, 1.0)); ! 188: /* if ((1.0+a)-1.0 != 0.0) eps=a; => */ ! 189: if (Ddiff(Dsum(1.0, a), 1.0) != 0.0) eps=a; ! 190: } ! 191: printf("/\* Smallest x such that 1.0+x != 1.0=%g *\/\n", eps); ! 192: ! 193: /****** Round or chop ***************************************************/ ! 194: ngrd=0; ! 195: if (irnd == 1) { printf("/\* Arithmetic rounds *\/\n"); } ! 196: else { ! 197: printf("/\* Arithmetic chops"); ! 198: if (Ddiff(Dmul(Dsum(1.0,eps),1.0),1.0) != 0.0) { ! 199: ngrd=1; ! 200: printf(" but uses guard digits"); ! 201: } ! 202: printf(" *\/\n"); ! 203: } ! 204: ! 205: /****** Size of and minimum normalised exponent ****************************/ ! 206: y=0; i=0; k=1; z=basein; z1=(1.0+eps)/base; ! 207: ! 208: /* Coarse search for the largest power of two */ ! 209: if (setjmp(lab)==0) /* in case of underflow trap */ ! 210: do { ! 211: y=z; y1=z1; ! 212: z=Dmul(y,y); z1=Dmul(z1, y); ! 213: a=Dmul(z,1.0); ! 214: z2=Ddiv(z1,y); ! 215: if (z2 != y1) break; ! 216: if ((Dsum(a,a) == 0.0) || (fabs(z) >= y)) break; ! 217: i++; ! 218: k+=k; ! 219: } while(1); ! 220: ! 221: if (ibase != 10) { ! 222: iexp=i+1; /* for the sign */ ! 223: mx=k+k; ! 224: } else { ! 225: iexp=2; ! 226: iz=ibase; ! 227: while (k >= iz) { iz*=ibase; iexp++; } ! 228: mx=iz+iz-1; ! 229: } ! 230: ! 231: /* Fine tune starting with y and y1 */ ! 232: if (setjmp(lab)==0) /* in case of underflow trap */ ! 233: do { ! 234: xmin=y; z1=y1; ! 235: y=Ddiv(y,base); y1=Ddiv(y1,base); ! 236: a=Dmul(y,1.0); ! 237: z2=Dmul(y1,base); ! 238: if (z2 != z1) break; ! 239: if ((Dsum(a,a) == 0.0) || (fabs(y) >= xmin)) break; ! 240: k++; ! 241: } while (1); ! 242: ! 243: if (setjmp(lab)!=0) { printf("Unexpected over/underflow\n"); exit(1); } ! 244: ! 245: minexp= (-k)+1; ! 246: ! 247: if ((mx <= k+k-3) && (ibase != 10)) { mx+=mx; iexp+=1; } ! 248: printf("/\* Number of bits used for exponent=%d *\/\n", iexp); ! 249: printf("/\* Minimum normalised exponent=%d *\/\n", minexp); ! 250: printf("/\* Minimum normalised positive number=%g *\/\n", xmin); ! 251: ! 252: /****** Minimum exponent ***************************************************/ ! 253: if (setjmp(lab)==0) /* in case of underflow trap */ ! 254: do { ! 255: xminner=y; ! 256: y=Ddiv(y,base); ! 257: a=Dmul(y,1.0); ! 258: if ((Dsum(a,a) == 0.0) || (fabs(y) >= xminner)) break; ! 259: } while (1); ! 260: ! 261: if (setjmp(lab)!=0) { printf("Unexpected over/underflow\n"); exit(1); } ! 262: ! 263: normalised=1; ! 264: if (xminner != 0.0 && xminner != xmin) { ! 265: normalised=0; ! 266: printf("/\* The smallest numbers are not kept normalised *\/\n"); ! 267: printf("/\* Smallest unnormalised positive number=%g *\/\n", ! 268: xminner); ! 269: } ! 270: ! 271: /****** Maximum exponent ***************************************************/ ! 272: maxexp=2; xmax=1.0; newxmax=base+1.0; ! 273: if (setjmp(lab) == 0) { ! 274: while (xmax<newxmax) { ! 275: xmax=newxmax; ! 276: newxmax=Dmul(newxmax, base); ! 277: if (Ddiv(newxmax, base) != xmax) break; /* ieee infinity */ ! 278: maxexp++; ! 279: } ! 280: } ! 281: if (setjmp(lab)!=0) { printf("Unexpected over/underflow\n"); exit(1); } ! 282: ! 283: printf("/\* Maximum exponent=%d *\/\n", maxexp); ! 284: ! 285: /****** Largest and smallest numbers ************************************/ ! 286: xmax=Ddiff(1.0, epsneg); ! 287: if (Dmul(xmax,1.0) != xmax) xmax=Ddiff(1.0, Dmul(base,epsneg)); ! 288: for (i=1; i<=maxexp; i++) xmax=Dmul(xmax, base); ! 289: printf("/\* Maximum number=%g *\/\n", xmax); ! 290: ! 291: /****** Hidden bit + sanity check ***************************************/ ! 292: if (ibase != 10) { ! 293: mantbits=log(2, (double)ibase)*imant; ! 294: if (mantbits+iexp+1 == sizeof(double)*bits+1) { ! 295: printf("/\* Double arithmetic uses a hidden bit *\/\n"); ! 296: } else if (mantbits+iexp+1 == sizeof(double)*bits) { ! 297: printf("/\* Double arithmetic doesn't use a hidden bit *\/\n"); ! 298: } else { ! 299: printf("/\* Something fishy here! %s %s *\/\n", ! 300: "Exponent size + mantissa size doesn't match", ! 301: "with the size of a double."); ! 302: } ! 303: } ! 304: ! 305: /****** The point of it all: ********************************************/ ! 306: printf("\n/\* Numeric package constants *\/\n"); ! 307: ! 308: BIG= power(ibase, imant)-1.0; ! 309: MAXNUMDIG= log(10, BIG); ! 310: ipower= log(10, (double)(maxint/2)); ! 311: Maxreal= xmax; ! 312: Maxexpo= log(2, (double)ibase)*maxexp; ! 313: Minexpo= log(2, (double)ibase)*minexp; ! 314: Dblbits= log(2, (double)ibase)*imant; ! 315: tenlogBASE= min(MAXNUMDIG/2, ipower); ! 316: BASE=1; for(i=1; i<=tenlogBASE; i++) BASE*=10; ! 317: ! 318: printf("#define BIG %1.1f /\* Maximum integral double *\/\n", BIG); ! 319: printf("#define LONG "); ! 320: for(i=1; i<=MAXNUMDIG; i++) printf("9"); ! 321: printf(".5 /\* Maximum power of ten less than BIG *\/\n"); ! 322: printf("#define MAXNUMDIG %d /\* The number of 9's in LONG *\/\n", ! 323: MAXNUMDIG); ! 324: printf("#define MINNUMDIG 6 /\* Don't change: this is here for consistency *\/\n"); ! 325: ! 326: printf("#define BASE %d /\* %s *\/\n", ! 327: BASE, "BASE**2<=BIG && BASE*2<=Maxint && -2*BASE>=Minint"); ! 328: if (((double)BASE)*BASE > BIG || ((double)BASE)+BASE > maxint) { ! 329: printf("*** BASE value wrong\n"); ! 330: exit(1); ! 331: } ! 332: printf("#define tenlogBASE %d /\* = log10(BASE) *\/\n", tenlogBASE); ! 333: printf("#define Maxreal %e /\* Maximum double *\/\n", Maxreal); ! 334: printf("#define Maxexpo %d /\* Maximum value such that 2**Maxexpo<=Maxreal *\/\n", ! 335: Maxexpo); ! 336: printf("#define Minexpo (%d) /\* Minimum value such that -2**Minexpo>=Minreal *\/\n", ! 337: Minexpo); ! 338: printf("#define Dblbits %d /\* Maximum value such that 2**Dblbits<=BIG *\/\n", ! 339: Dblbits); ! 340: ! 341: printf("#define Maxintlet %d /\* Maximum short *\/\n", maxshort); ! 342: printf("#define Maxint %d /\* Maximum int *\/\n", maxint); ! 343: ! 344: printf("#define Maxsmallint %d /\* BASE-1 *\/\n", BASE-1); ! 345: printf("#define Minsmallint (%d) /\* -BASE *\/\n", -BASE); ! 346: ! 347: /* An extra goody: the approximate amount of data-space */ ! 348: /* Put here because it is likely to be slower then the rest */ ! 349: ! 350: /*Allocate blocks of 1000 until no more available*/ ! 351: /*Don't be tempted to change this to 1024: */ ! 352: /*we don't know how much header information there is*/ ! 353: ! 354: for(count=0; (p=(int *)malloc(1000))!=0; count++) { } ! 355: ! 356: printf("\n/\* Memory~= %d000 *\/\n", count); ! 357: ! 358: exit(0); ! 359: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.