real.c

来自「GCC编译器源代码」· C语言 代码 · 共 2,875 行 · 第 1/5 页

C
2,875
字号
  endian (e, l, TFmode);}/* Convert R to a double extended precision value.  The output array L   contains three 32-bit pieces of the result, in the order they would   appear in memory.  */void etarldouble (r, l)     REAL_VALUE_TYPE r;     long l[];{  unsigned EMUSHORT e[NE];  GET_REAL (&r, e);  etoe64 (e, e);  endian (e, l, XFmode);}/* Convert R to a double precision value.  The output array L contains two   32-bit pieces of the result, in the order they would appear in memory.  */void etardouble (r, l)     REAL_VALUE_TYPE r;     long l[];{  unsigned EMUSHORT e[NE];  GET_REAL (&r, e);  etoe53 (e, e);  endian (e, l, DFmode);}/* Convert R to a single precision float value stored in the least-significant   bits of a `long'.  */longetarsingle (r)     REAL_VALUE_TYPE r;{  unsigned EMUSHORT e[NE];  long l;  GET_REAL (&r, e);  etoe24 (e, e);  endian (e, &l, SFmode);  return ((long) l);}/* Convert X to a decimal ASCII string S for output to an assembly   language file.  Note, there is no standard way to spell infinity or   a NaN, so these values may require special treatment in the tm.h   macros.  */voidereal_to_decimal (x, s)     REAL_VALUE_TYPE x;     char *s;{  unsigned EMUSHORT e[NE];  GET_REAL (&x, e);  etoasc (e, s, 20);}/* Compare X and Y.  Return 1 if X > Y, 0 if X == Y, -1 if X < Y,   or -2 if either is a NaN.   */intereal_cmp (x, y)     REAL_VALUE_TYPE x, y;{  unsigned EMUSHORT ex[NE], ey[NE];  GET_REAL (&x, ex);  GET_REAL (&y, ey);  return (ecmp (ex, ey));}/*  Return 1 if the sign bit of X is set, else return 0.  */intereal_isneg (x)     REAL_VALUE_TYPE x;{  unsigned EMUSHORT ex[NE];  GET_REAL (&x, ex);  return (eisneg (ex));}/* End of REAL_ARITHMETIC interface *//*  Extended precision IEEE binary floating point arithmetic routines  Numbers are stored in C language as arrays of 16-bit unsigned  short integers.  The arguments of the routines are pointers to  the arrays.  External e type data structure, similar to Intel 8087 chip  temporary real format but possibly with a larger significand:	NE-1 significand words	(least significant word first,				 most significant bit is normally set)	exponent		(value = EXONE for 1.0,				top bit is the sign)  Internal exploded e-type data structure of a number (a "word" is 16 bits):  ei[0]	sign word	(0 for positive, 0xffff for negative)  ei[1]	biased exponent	(value = EXONE for the number 1.0)  ei[2]	high guard word	(always zero after normalization)  ei[3]  to ei[NI-2]	significand	(NI-4 significand words, 				 most significant word first, 				 most significant bit is set)  ei[NI-1]	low guard word	(0x8000 bit is rounding place)    		Routines for external format e-type numbers  	asctoe (string, e)	ASCII string to extended double e type 	asctoe64 (string, &d)	ASCII string to long double 	asctoe53 (string, &d)	ASCII string to double 	asctoe24 (string, &f)	ASCII string to single 	asctoeg (string, e, prec) ASCII string to specified precision 	e24toe (&f, e)		IEEE single precision to e type 	e53toe (&d, e)		IEEE double precision to e type 	e64toe (&d, e)		IEEE long double precision to e type 	e113toe (&d, e)		128-bit long double precision to e type 	eabs (e)			absolute value 	eadd (a, b, c)		c = b + a 	eclear (e)		e = 0 	ecmp (a, b)		Returns 1 if a > b, 0 if a == b, 				-1 if a < b, -2 if either a or b is a NaN. 	ediv (a, b, c)		c = b / a 	efloor (a, b)		truncate to integer, toward -infinity 	efrexp (a, exp, s)	extract exponent and significand 	eifrac (e, &l, frac)    e to HOST_WIDE_INT and e type fraction 	euifrac (e, &l, frac)   e to unsigned HOST_WIDE_INT and e type fraction 	einfin (e)		set e to infinity, leaving its sign alone 	eldexp (a, n, b)	multiply by 2**n 	emov (a, b)		b = a 	emul (a, b, c)		c = b * a 	eneg (e)			e = -e 	eround (a, b)		b = nearest integer value to a 	esub (a, b, c)		c = b - a 	e24toasc (&f, str, n)	single to ASCII string, n digits after decimal 	e53toasc (&d, str, n)	double to ASCII string, n digits after decimal 	e64toasc (&d, str, n)	80-bit long double to ASCII string 	e113toasc (&d, str, n)	128-bit long double to ASCII string 	etoasc (e, str, n)	e to ASCII string, n digits after decimal 	etoe24 (e, &f)		convert e type to IEEE single precision 	etoe53 (e, &d)		convert e type to IEEE double precision 	etoe64 (e, &d)		convert e type to IEEE long double precision 	ltoe (&l, e)		HOST_WIDE_INT to e type 	ultoe (&l, e)		unsigned HOST_WIDE_INT to e type	eisneg (e)              1 if sign bit of e != 0, else 0	eisinf (e)              1 if e has maximum exponent (non-IEEE) 				or is infinite (IEEE)        eisnan (e)              1 if e is a NaN  		Routines for internal format exploded e-type numbers  	eaddm (ai, bi)		add significands, bi = bi + ai 	ecleaz (ei)		ei = 0 	ecleazs (ei)		set ei = 0 but leave its sign alone 	ecmpm (ai, bi)		compare significands, return 1, 0, or -1 	edivm (ai, bi)		divide  significands, bi = bi / ai 	emdnorm (ai,l,s,exp)	normalize and round off 	emovi (a, ai)		convert external a to internal ai 	emovo (ai, a)		convert internal ai to external a 	emovz (ai, bi)		bi = ai, low guard word of bi = 0 	emulm (ai, bi)		multiply significands, bi = bi * ai 	enormlz (ei)		left-justify the significand 	eshdn1 (ai)		shift significand and guards down 1 bit 	eshdn8 (ai)		shift down 8 bits 	eshdn6 (ai)		shift down 16 bits 	eshift (ai, n)		shift ai n bits up (or down if n < 0) 	eshup1 (ai)		shift significand and guards up 1 bit 	eshup8 (ai)		shift up 8 bits 	eshup6 (ai)		shift up 16 bits 	esubm (ai, bi)		subtract significands, bi = bi - ai        eiisinf (ai)            1 if infinite        eiisnan (ai)            1 if a NaN 	eiisneg (ai)		1 if sign bit of ai != 0, else 0        einan (ai)              set ai = NaN        eiinfin (ai)            set ai = infinity  The result is always normalized and rounded to NI-4 word precision  after each arithmetic operation.  Exception flags are NOT fully supported.   Signaling NaN's are NOT supported; they are treated the same  as quiet NaN's.   Define INFINITY for support of infinity; otherwise a  saturation arithmetic is implemented.   Define NANS for support of Not-a-Number items; otherwise the  arithmetic will never produce a NaN output, and might be confused  by a NaN input.  If NaN's are supported, the output of `ecmp (a,b)' is -2 if  either a or b is a NaN. This means asking `if (ecmp (a,b) < 0)'  may not be legitimate. Use `if (ecmp (a,b) == -1)' for `less than'  if in doubt.   Denormals are always supported here where appropriate (e.g., not  for conversion to DEC numbers).  *//* Definitions for error codes that are passed to the common error handling   routine mtherr.   For Digital Equipment PDP-11 and VAX computers, certain  IBM systems, and others that use numbers with a 56-bit  significand, the symbol DEC should be defined.  In this  mode, most floating point constants are given as arrays  of octal integers to eliminate decimal to binary conversion  errors that might be introduced by the compiler.   For computers, such as IBM PC, that follow the IEEE  Standard for Binary Floating Point Arithmetic (ANSI/IEEE  Std 754-1985), the symbol IEEE should be defined.  These numbers have 53-bit significands.  In this mode, constants  are provided as arrays of hexadecimal 16 bit integers.  The endian-ness of generated values is controlled by  REAL_WORDS_BIG_ENDIAN.   To accommodate other types of computer arithmetic, all  constants are also provided in a normal decimal radix  which one can hope are correctly converted to a suitable  format by the available C language compiler.  To invoke  this mode, the symbol UNK is defined.   An important difference among these modes is a predefined  set of machine arithmetic constants for each.  The numbers  MACHEP (the machine roundoff error), MAXNUM (largest number  represented), and several other parameters are preset by  the configuration symbol.  Check the file const.c to  ensure that these values are correct for your computer.   For ANSI C compatibility, define ANSIC equal to 1.  Currently  this affects only the atan2 function and others that use it.  *//* Constant definitions for math error conditions.  */#define DOMAIN		1	/* argument domain error */#define SING		2	/* argument singularity */#define OVERFLOW	3	/* overflow range error */#define UNDERFLOW	4	/* underflow range error */#define TLOSS		5	/* total loss of precision */#define PLOSS		6	/* partial loss of precision */#define INVALID		7	/* NaN-producing operation *//*  e type constants used by high precision check routines */#if LONG_DOUBLE_TYPE_SIZE == 128/* 0.0 */unsigned EMUSHORT ezero[NE] = {0x0000, 0x0000, 0x0000, 0x0000,  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,};extern unsigned EMUSHORT ezero[];/* 5.0E-1 */unsigned EMUSHORT ehalf[NE] = {0x0000, 0x0000, 0x0000, 0x0000,  0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0x3ffe,};extern unsigned EMUSHORT ehalf[];/* 1.0E0 */unsigned EMUSHORT eone[NE] = {0x0000, 0x0000, 0x0000, 0x0000,  0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0x3fff,};extern unsigned EMUSHORT eone[];/* 2.0E0 */unsigned EMUSHORT etwo[NE] = {0x0000, 0x0000, 0x0000, 0x0000,  0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0x4000,};extern unsigned EMUSHORT etwo[];/* 3.2E1 */unsigned EMUSHORT e32[NE] = {0x0000, 0x0000, 0x0000, 0x0000,  0x0000, 0x0000, 0x0000, 0x0000, 0x8000, 0x4004,};extern unsigned EMUSHORT e32[];/* 6.93147180559945309417232121458176568075500134360255E-1 */unsigned EMUSHORT elog2[NE] = {0x40f3, 0xf6af, 0x03f2, 0xb398,  0xc9e3, 0x79ab, 0150717, 0013767, 0130562, 0x3ffe,};extern unsigned EMUSHORT elog2[];/* 1.41421356237309504880168872420969807856967187537695E0 */unsigned EMUSHORT esqrt2[NE] = {0x1d6f, 0xbe9f, 0x754a, 0x89b3,  0x597d, 0x6484, 0174736, 0171463, 0132404, 0x3fff,};extern unsigned EMUSHORT esqrt2[];/* 3.14159265358979323846264338327950288419716939937511E0 */unsigned EMUSHORT epi[NE] = {0x2902, 0x1cd1, 0x80dc, 0x628b,  0xc4c6, 0xc234, 0020550, 0155242, 0144417, 0040000,};extern unsigned EMUSHORT epi[];#else/* LONG_DOUBLE_TYPE_SIZE is other than 128 */unsigned EMUSHORT ezero[NE] = {0, 0000000, 0000000, 0000000, 0000000, 0000000,};unsigned EMUSHORT ehalf[NE] = {0, 0000000, 0000000, 0000000, 0100000, 0x3ffe,};unsigned EMUSHORT eone[NE] = {0, 0000000, 0000000, 0000000, 0100000, 0x3fff,};unsigned EMUSHORT etwo[NE] = {0, 0000000, 0000000, 0000000, 0100000, 0040000,};unsigned EMUSHORT e32[NE] = {0, 0000000, 0000000, 0000000, 0100000, 0040004,};unsigned EMUSHORT elog2[NE] = {0xc9e4, 0x79ab, 0150717, 0013767, 0130562, 0x3ffe,};unsigned EMUSHORT esqrt2[NE] = {0x597e, 0x6484, 0174736, 0171463, 0132404, 0x3fff,};unsigned EMUSHORT epi[NE] = {0xc4c6, 0xc234, 0020550, 0155242, 0144417, 0040000,};#endif/* Control register for rounding precision.   This can be set to 113 (if NE=10), 80 (if NE=6), 64, 56, 53, or 24 bits.  */int rndprc = NBITS;extern int rndprc;/*  Clear out entire e-type number X.  */static void eclear (x)     register unsigned EMUSHORT *x;{  register int i;  for (i = 0; i < NE; i++)    *x++ = 0;}/* Move e-type number from A to B.  */static void emov (a, b)     register unsigned EMUSHORT *a, *b;{  register int i;  for (i = 0; i < NE; i++)    *b++ = *a++;}/* Absolute value of e-type X.  */static void eabs (x)     unsigned EMUSHORT x[];{  /* sign is top bit of last word of external format */  x[NE - 1] &= 0x7fff;		}/* Negate the e-type number X.  */static void eneg (x)     unsigned EMUSHORT x[];{  x[NE - 1] ^= 0x8000;		/* Toggle the sign bit */}/* Return 1 if sign bit of e-type number X is nonzero, else zero.  */static int eisneg (x)     unsigned EMUSHORT x[];{  if (x[NE - 1] & 0x8000)    return (1);  else    return (0);}/* Return 1 if e-type number X is infinity, else return zero.  */static int eisinf (x)     unsigned EMUSHORT x[];{#ifdef NANS  if (eisnan (x))    return (0);#endif  if ((x[NE - 1] & 0x7fff) == 0x7fff)    return (1);  else    return (0);}/* Check if e-type number is not a number.  The bit pattern is one that we   defined, so we know for sure how to detect it.  */static int eisnan (x)     unsigned EMUSHORT x[];{#ifdef NANS  int i;  /* NaN has maximum exponent */  if ((x[NE - 1] & 0x7fff) != 0x7fff)    return (0);  /* ... and non-zero significand field.  */  for (i = 0; i < NE - 1; i++)    {      if (*x++ != 0)        return (1);    }#endif  return (0);}/*  Fill e-type number X with infinity pattern (IEEE)    or largest possible number (non-IEEE).  */static void einfin (x)     register unsigned EMUSHORT *x;{  register int i;#ifdef INFINITY  for (i = 0; i < NE - 1; i++)    *x++ = 0;  *x |= 32767;#else  for (i = 0; i < NE - 1; i++)    *x++ = 0xffff;  *x |= 32766;  if (rndprc < NBITS)    {      if (rndprc == 113)	{	  *(x - 9) = 0;	  *(x - 8) = 0;	}      if (rndprc == 64)	{	  *(x - 5) = 0;	}      if (rndprc == 53)	{	  *(x - 4) = 0xf800;	}      else	{	  *(x - 4) = 0;	  *(x - 3) = 0;	  *(x - 2) = 0xff00;	}    }#endif}/* Output an e-type NaN.   This generates Intel's quiet NaN pattern for extended real.   The exponent is 7fff, the leading mantissa word is c000.  */static void enan (x, sign)     register unsigned EMUSHORT *x;     int sign;{  register int i;  for (i = 0; i < NE - 2; i++)    *x++ = 0;  *x++ = 0xc000;  *x = (sign << 15) | 0x7fff;}/* Move in an e-type number A, converting it to exploded e-type B.  */static void emovi (a, b)     unsigned EMUSHORT *a, *b;{  register unsigned EMUSHORT *p, *q;  int i;  q = b;  p = a + (NE - 1);		/* point to last word of external number */  /* get the sign bit */  if (*p & 0x8000)    *q++ = 0xffff;  else    *q++ = 0;  /* get the exponent */  *q = *p--;  *q++ &= 0x7fff;		/* delete the sign bit */#ifdef INFINITY  if ((*(q - 1) & 0x7fff) == 0x7fff)    {#ifdef NANS      if (eisnan (a))	{	  *q++ = 0;	  for (i = 3; i < NI; i++)	    *q++ = *p--;	  return;	}#endif      for (i = 2; i < NI; i++)	*q++ = 0;      return;    }#endif  /* clear high guard word */  *q++ = 0;  /* move in the significand */  for (i = 0; i < NE - 1; i++)    *q++ = *p--;  /* clear low guard word */  *q = 0;}/* Move out exploded e-type number A, converting it to e type B.  */static void emovo (a, b)     unsigned EMUSHORT *a, *b;{  register unsigned EMUSHORT *p, *q;  unsigned EMUSHORT i;  int j;  p = a;  q = b + (NE - 1);		/* point to output exponent */  /* combine sign and exponent */  i = *p++;  if (i)    *q-- = *p++ | 0x8000;  else    *q-- = *p++;#ifdef INFINITY  if (*(p - 1) == 0x7fff)    {#ifdef NANS      if (eiisnan (a))	{	  enan (b, eiisneg (a));	  return;	}#endif      einfin (b);	return;    }#endif  /* skip over guard word */

⌨️ 快捷键说明

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