⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hard-params.c

📁 这是完整的gcc源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
#define F_check fCheck#define Validate fValidate#define MARK "F"#define EPROP efprop#define Integer short#define INT "short"#define IPROP sprop#define Iname "SHRT"#ifndef NO_UI#define OK_UI 1#endif#define UPROP usprop#define Uname "USHRT"#ifdef VERIFY#define I_MAX SHRT_MAX#define I_MIN SHRT_MIN#define U_MAX USHRT_MAX#define F_RADIX FLT_RADIX#define F_MANT_DIG FLT_MANT_DIG#define F_DIG FLT_DIG#define F_ROUNDS FLT_ROUNDS#define F_EPSILON FLT_EPSILON#define F_MIN_EXP FLT_MIN_EXP#define F_MIN FLT_MIN#define F_MIN_10_EXP FLT_MIN_10_EXP#define F_MAX_EXP FLT_MAX_EXP#define F_MAX FLT_MAX#define F_MAX_10_EXP FLT_MAX_10_EXP#endif /* VERIFY */#endif /* PASS1 */#ifdef PASS2#define Number double#define THING "DOUBLE"#define Thing "Double"#define thing "double"#define Fname "DBL"#define FPROP dprop#define Store dStore#define Sum dSum#define Diff dDiff#define Mul dMul#define Div dDiv#define Self dSelf#define F_check dCheck#define Validate dValidate#define MARK ""#define EPROP edprop#define Integer int#define INT "int"#define IPROP iprop#define Iname "INT"#define OK_UI 1 /* Unsigned int is always possible */#define UPROP uiprop#define Uname "UINT"#ifdef VERIFY#define I_MAX INT_MAX#define I_MIN INT_MIN#define U_MAX UINT_MAX#define F_MANT_DIG DBL_MANT_DIG#define F_DIG DBL_DIG#define F_EPSILON DBL_EPSILON#define F_MIN_EXP DBL_MIN_EXP#define F_MIN DBL_MIN#define F_MIN_10_EXP DBL_MIN_10_EXP#define F_MAX_EXP DBL_MAX_EXP#define F_MAX DBL_MAX#define F_MAX_10_EXP DBL_MAX_10_EXP#endif /* VERIFY */#endif /* PASS2 */#ifdef PASS3#if defined(__STDC__) && !defined(NO_LONG_DOUBLE)#define Number long double#endif#define THING "LONG DOUBLE"#define Thing "Long double"#define thing "long double"#define Fname "LDBL"#define FPROP ldprop#define Store ldStore#define Sum ldSum#define Diff ldDiff#define Mul ldMul#define Div ldDiv#define Self ldSelf#define F_check ldCheck#define Validate ldValidate#define MARK "L"#define EPROP eldprop#define Integer long#define INT "long"#define IPROP lprop#define Iname "LONG"#ifndef NO_UI#define OK_UI 1#endif#define UPROP ulprop#define Uname "ULONG"#ifdef VERIFY#define I_MAX LONG_MAX#define I_MIN LONG_MIN#define U_MAX ULONG_MAX#define F_MANT_DIG LDBL_MANT_DIG#define F_DIG LDBL_DIG#define F_EPSILON LDBL_EPSILON#define F_MIN_EXP LDBL_MIN_EXP#define F_MIN LDBL_MIN#define F_MIN_10_EXP LDBL_MIN_10_EXP#define F_MAX_EXP LDBL_MAX_EXP#define F_MAX LDBL_MAX#define F_MAX_10_EXP LDBL_MAX_10_EXP#endif /* VERIFY */#endif /* PASS3 */#ifndef VERIFY#define I_MAX int_max#define I_MIN int_min#define U_MAX int_max#define F_RADIX f_radix#define F_MANT_DIG f_mant_dig#define F_DIG f_dig#define F_ROUNDS f_rounds#define F_EPSILON f_epsilon#define F_MIN_EXP f_min_exp#define F_MIN f_min#define F_MIN_10_EXP f_min_10_exp#define F_MAX_EXP f_max_exp#define F_MAX f_max#define F_MAX_10_EXP f_max_10_exp#endifProcedure IPROP() { /* for short, int, and long */	volatile Integer newi, int_max, maxeri, int_min, minneri;	volatile int ibits, ipower, two=2;	/* Calculate max short/int/long ***********************************/	/* Calculate 2**n-1 until overflow - then use the previous value  */	newi=1; int_max=0;	if (setjmp(lab)==0) { /* Yields int_max */		for(ipower=0; newi>int_max; ipower++) {			int_max=newi;			newi=newi*two+1;		}		Vprintf("%sOverflow of a%s %s does not generate a trap%s\n",			co, INT[0]=='i'?"n":"", INT, oc);	} else {		Vprintf("%sOverflow of a%s %s generates a trap%s\n",			co, INT[0]=='i'?"n":"", INT, oc);	}	Unexpected(7);	/* Minimum value: assume either two's or one's complement *********/	int_min= -int_max;	if (setjmp(lab)==0) { /* Yields int_min */		if (int_min-1 < int_min) int_min--;	}	Unexpected(8);	/* Now for those daft Cybers: */	maxeri=0; newi=int_max;	if (setjmp(lab)==0) { /* Yields maxeri */		for(ibits=ipower; newi>maxeri; ibits++) {			maxeri=newi;			newi=newi+newi+1;		}	}	Unexpected(9);	minneri= -maxeri;	if (setjmp(lab)==0) { /* Yields minneri */		if (minneri-1 < minneri) minneri--;	}	Unexpected(10);	Vprintf("%sMaximum %s = %ld (= 2**%d-1)%s\n",		co, INT, (long)int_max, ipower, oc);	Vprintf("%sMinimum %s = %ld%s\n", co, INT, (long)int_min, oc);	if (L) i_define(Iname, "_MAX", (long) int_max, (long) I_MAX);	if (L) i_define(Iname, "_MIN", (long) int_min, (long) I_MIN);	if (maxeri>int_max) {		Vprintf("%sThere is a larger %s, %ld (= 2**%d-1), %s %s%s\n",			co, INT, (long)maxeri, ibits, 			"but only for addition, not multiplication",			"(I smell a Cyber!)",			oc);	}	if (minneri<int_min) {		Vprintf("%sThere is a smaller %s, %ld, %s %s%s\n",			co, INT, (long)minneri, 			"but only for addition, not multiplication",			"(I smell a Cyber!)",			oc);	}}Procedure UPROP () { /* unsigned short/int/long */#ifdef OK_UI	volatile unsigned Integer int_max, newi, two;	newi=1; int_max=0; two=2;	if (setjmp(lab)==0) { /* Yields int_max */		while(newi>int_max) {			int_max=newi;			newi=newi*two+1;		}	}	Unexpected(11);	Vprintf("%sMaximum unsigned %s = %lu%s\n",		co, INT, (unsigned long) int_max, oc);	if (L) u_define(Uname, "_MAX", (unsigned long) int_max,			(unsigned long) U_MAX);#endif}#ifdef Number/* These routines are intended to defeat any attempt at optimisation   or use of extended precision, and to defeat faulty narrowing casts:*/Procedure Store(a, b) Number a, *b; { *b=a; }Number Sum(a, b) Number a, b; { Number r; Store(a+b, &r); return (r); }Number Diff(a, b) Number a, b; { Number r; Store(a-b, &r); return (r); }Number Mul(a, b) Number a, b; { Number r; Store(a*b, &r); return (r); }Number Div(a, b) Number a, b; { Number r; Store(a/b, &r); return (r); }Number Self(a) Number a; { Number r; Store(a, &r); return (r); }Procedure F_check(precision, val1) int precision; Long_double val1; {	/* You don't think I'm going to go to all the trouble of writing	   a program that works out what all sorts of values are, only to	   have printf go and print the wrong values out, do you?	   No, you're right, so this function tries to see if printf	   has written the right value, by reading it back again.	   This introduces a new problem of course: suppose printf writes	   the correct value, and scanf reads it back wrong... oh well.	   But I'm adamant about this: the precision given is enough	   to uniquely identify the printed number, therefore I insist	   that sscanf read the number back identically. Harsh yes, but	   sometimes you've got to be cruel to be kind.	*/	Long_double new1;	Number val, new, diff;	double rem;	int e;	char *rep;	char *f2;	if (sizeof(double) == sizeof(Long_double)) {		/* Assume they're the same, and use non-stdc format */		/* This is for stdc compilers using non-stdc libraries */		f2= "%le";   /* Input */	} else {		/* It had better support Le then */		f2= "%Le";	}	val= val1;	rep= f_rep(precision, (Long_double) val);	if (setjmp(lab)==0) {		sscanf(rep, f2, &new1);	} else {		eek_a_bug("sscanf caused a trap");		printf("%s    scanning: %s format: %s%s\n\n", co, rep, f2, oc);		Unexpected(12);		return;	}	if (setjmp(lab)==0) { /* See if new is usable */		new= new1;		if (new != 0.0) {			diff= val/new - 1.0;			if (diff < 0.1) diff= 1.0;			/* That should be enough to generate a trap */		}	} else {		eek_a_bug("sscanf returned an unusable number");		printf("%s    scanning: %s with format: %s%s\n\n",		       co, rep, f2, oc);		Unexpected(13);		return;	}	Unexpected(14);	if (new != val) {		eek_a_bug("Possibly bad output from printf above");		if (!exponent(val, &rem, &e)) {			printf("%s    but value was an unusable number%s\n\n",			       co, oc);			return;		}		printf("%s    expected value around %.*fe%d, bit pattern:\n    ",		       co, precision, rem, e);		bitpattern((char *) &val, sizeof(val));		printf ("%s\n", oc);		printf("%s    sscanf gave           %s, bit pattern:\n    ",		       co, f_rep(precision, (Long_double) new));		bitpattern((char *) &new, sizeof(new));		printf ("%s\n", oc);		printf("%s    difference= %s%s\n\n", 		       co, f_rep(precision, (Long_double) (val-new)), oc);	}}Procedure Validate(prec, val, req, same) int prec, same; Long_double val, req; {	Unexpected(15);	if (!same) {		printf("%s*** Verify failed for above #define!\n", co);		if (setjmp(lab) == 0) { /* for the case that req == nan */			printf("       Compiler has %s for value%s\n", 			       f_rep(prec, req), oc);		} else {			printf("       Compiler has %s for value%s\n",			       "an unusable number", oc);		}		if (setjmp(lab) == 0) {			F_check(prec, (Long_double) req);		} /*else forget it*/		if (setjmp(lab) == 0) {					if (req > 0.0 && val > 0.0) {				printf("%s    difference= %s%s\n",				       co, f_rep(prec, val-req), oc);			}		} /*else forget it*/		Unexpected(16);		printf("\n");		bugs++;	} else if (val != req) {		if (stdc) {			printf("%s*** Verify failed for above #define!\n", co);			printf("       Constant has the wrong precision%s\n",			       oc);			bugs++;		} else eek_a_bug("the cast didn't work");		printf("\n");	}}int FPROP(bits_per_byte) int bits_per_byte; {	/* Properties of floating types, using algorithms by Cody and Waite	   from MA Malcolm, as modified by WM Gentleman and SB Marovich.	   Further extended by S Pemberton.	   Returns the number of digits in the fraction.	*/	volatile int i, f_radix, iexp, irnd, mrnd, f_rounds, f_mant_dig,	    iz, k, inf, machep, f_max_exp, f_min_exp, mx, negeps,	    mantbits, digs, f_dig, trap,	    hidden, normal, f_min_10_exp, f_max_10_exp;	volatile Number a, b, base, basein, basem1, f_epsilon, epsneg,	       f_max, newxmax, f_min, xminner, y, y1, z, z1, z2;	Unexpected(17);	Vprintf("%sPROPERTIES OF %s:%s\n", co, THING, oc);	/* Base and size of mantissa **************************************/	/* First repeatedly double until adding 1 has no effect.	  */	/* For instance, if base is 10, with 3 significant digits	  */	/* it will try 1, 2, 4, 8, ... 512, 1024, and stop there,	  */	/* since 1024 is only representable as 1020.			  */	a=1.0;	if (setjmp(lab)==0) { /* inexact trap? */		do { a=Sum(a, a); }		while (Diff(Diff(Sum(a, 1.0), a), 1.0) == 0.0);	} else {		fprintf(stderr, "*** Program got loss-of-precision trap!\n");		/* And supporting those is just TOO much trouble! */		exit(bugs+1);	}	Unexpected(18);	/* Now double until you find a number that can be added to the	  */	/* above number. For 1020 this is 8 or 16, depending whether the  */	/* result is rounded or truncated.				  */	/* In either case the result is 1030. 1030-1020= the base, 10.	  */	b=1.0;	do { b=Sum(b, b); } while ((base=Diff(Sum(a, b), a)) == 0.0);	f_radix=base;	Vprintf("%sBase = %d%s\n", co, f_radix, oc);	/* Sanity check; if base<2, I can't guarantee the rest will work  */	if (f_radix < 2) {		eek_a_bug("Function return or parameter passing faulty? (This is a guess.)");		printf("\n");		return(0);	}#ifdef PASS1 /* only for FLT */	if (F) i_define("FLT", "_RADIX", (long) f_radix, (long) F_RADIX);#endif	/* Now the number of digits precision: */	f_mant_dig=0; b=1.0;	do { f_mant_dig++; b=Mul(b, base); }	while (Diff(Diff(Sum(b,1.0),b),1.0) == 0.0);	f_dig=floor_log(10, (Long_double)(b/base)) + (base==10?1:0);	Vprintf("%sSignificant base digits = %d %s %d %s%s\n",		co, f_mant_dig, "(= at least", f_dig, "decimal digits)", oc);	if (F) i_define(Fname, "_MANT_DIG", (long) f_mant_dig,			(long) F_MANT_DIG);	if (F) i_define(Fname, "_DIG", (long) f_dig, (long) F_DIG);	digs= ceil_log(10, (Long_double)b); /* the number of digits to printf */	/* Rounding *******************************************************/	basem1=Diff(base, 0.5);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -