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

📄 ldtoa.c

📁 KPIT GNU Tools is a set of GNU development tools for Renesas microcontrollers.
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Move internal format number from a to b. */static void emovz(register short unsigned int *a, register short unsigned int *b){register int i;for( i=0; i<NI-1; i++ )	*b++ = *a++;/* clear low guard word */*b = 0;}/* Return nonzero if internal format number is a NaN. */static int eiisnan (short unsigned int *x){int i;if( (x[E] & 0x7fff) == 0x7fff )	{	for( i=M+1; i<NI; i++ )		{		if( x[i] != 0 )			return(1);		}	}return(0);}#if LDBL_MANT_DIG == 64/* Return nonzero if internal format number is infinite. */static int eiisinf (x)     unsigned short x[];{#ifdef NANS  if (eiisnan (x))    return (0);#endif  if ((x[E] & 0x7fff) == 0x7fff)    return (1);  return (0);}#endif /* LDBL_MANT_DIG == 64 *//*;	Compare significands of numbers in internal format.;	Guard words are included in the comparison.;;	unsigned short a[NI], b[NI];;	cmpm( a, b );;;	for the significands:;	returns	+1 if a > b;		 0 if a == b;		-1 if a < b*/static int ecmpm(register short unsigned int *a, register short unsigned int *b){int i;a += M; /* skip up to significand area */b += M;for( i=M; i<NI; i++ )	{	if( *a++ != *b++ )		goto difrnt;	}return(0);difrnt:if( *(--a) > *(--b) )	return(1);else	return(-1);}/*;	Shift significand down by 1 bit*/static void eshdn1(register short unsigned int *x){register unsigned short bits;int i;x += M;	/* point to significand area */bits = 0;for( i=M; i<NI; i++ )	{	if( *x & 1 )		bits |= 1;	*x >>= 1;	if( bits & 2 )		*x |= 0x8000;	bits <<= 1;	++x;	}	}/*;	Shift significand up by 1 bit*/static void eshup1(register short unsigned int *x){register unsigned short bits;int i;x += NI-1;bits = 0;for( i=M; i<NI; i++ )	{	if( *x & 0x8000 )		bits |= 1;	*x <<= 1;	if( bits & 2 )		*x |= 1;	bits <<= 1;	--x;	}}/*;	Shift significand down by 8 bits*/static void eshdn8(register short unsigned int *x){register unsigned short newbyt, oldbyt;int i;x += M;oldbyt = 0;for( i=M; i<NI; i++ )	{	newbyt = *x << 8;	*x >>= 8;	*x |= oldbyt;	oldbyt = newbyt;	++x;	}}/*;	Shift significand up by 8 bits*/static void eshup8(register short unsigned int *x){int i;register unsigned short newbyt, oldbyt;x += NI-1;oldbyt = 0;for( i=M; i<NI; i++ )	{	newbyt = *x >> 8;	*x <<= 8;	*x |= oldbyt;	oldbyt = newbyt;	--x;	}}/*;	Shift significand up by 16 bits*/static void eshup6(register short unsigned int *x){int i;register unsigned short *p;p = x + M;x += M + 1;for( i=M; i<NI-1; i++ )	*p++ = *x++;*p = 0;}/*;	Shift significand down by 16 bits*/static void eshdn6(register short unsigned int *x){int i;register unsigned short *p;x += NI-1;p = x + 1;for( i=M; i<NI-1; i++ )	*(--p) = *(--x);*(--p) = 0;}/*;	Add significands;	x + y replaces y*/static void eaddm(short unsigned int *x, short unsigned int *y){register unsigned long a;int i;unsigned int carry;x += NI-1;y += NI-1;carry = 0;for( i=M; i<NI; i++ )	{	a = (unsigned long )(*x) + (unsigned long )(*y) + carry;	if( a & 0x10000 )		carry = 1;	else		carry = 0;	*y = (unsigned short )a;	--x;	--y;	}}/*;	Subtract significands;	y - x replaces y*/static void esubm(short unsigned int *x, short unsigned int *y){unsigned long a;int i;unsigned int carry;x += NI-1;y += NI-1;carry = 0;for( i=M; i<NI; i++ )	{	a = (unsigned long )(*y) - (unsigned long )(*x) - carry;	if( a & 0x10000 )		carry = 1;	else		carry = 0;	*y = (unsigned short )a;	--x;	--y;	}}/* Divide significands *//* Multiply significand of e-type number bby 16-bit quantity a, e-type result to c. */static void m16m(short unsigned int a, short unsigned int *b, short unsigned int *c){register unsigned short *pp;register unsigned long carry;unsigned short *ps;unsigned short p[NI];unsigned long aa, m;int i;aa = a;pp = &p[NI-2];*pp++ = 0;*pp = 0;ps = &b[NI-1];for( i=M+1; i<NI; i++ )	{	if( *ps == 0 )		{		--ps;		--pp;		*(pp-1) = 0;		}	else		{		m = (unsigned long) aa * *ps--;		carry = (m & 0xffff) + *pp;		*pp-- = (unsigned short )carry;		carry = (carry >> 16) + (m >> 16) + *pp;		*pp = (unsigned short )carry;		*(pp-1) = carry >> 16;		}	}for( i=M; i<NI; i++ )	c[i] = p[i];}/* Divide significands. Neither the numerator nor the denominatoris permitted to have its high guard word nonzero.  */static int edivm(short unsigned int *den, short unsigned int *num, LDPARMS *ldp){int i;register unsigned short *p;unsigned long tnum;unsigned short j, tdenm, tquot;unsigned short tprod[NI+1];unsigned short *equot = ldp->equot;p = &equot[0];*p++ = num[0];*p++ = num[1];for( i=M; i<NI; i++ )	{	*p++ = 0;	}eshdn1( num );tdenm = den[M+1];for( i=M; i<NI; i++ )	{	/* Find trial quotient digit (the radix is 65536). */	tnum = (((unsigned long) num[M]) << 16) + num[M+1];	/* Do not execute the divide instruction if it will overflow. */        if( (tdenm * 0xffffUL) < tnum )		tquot = 0xffff;	else		tquot = tnum / tdenm;		/* Prove that the divide worked. *//*	tcheck = (unsigned long )tquot * tdenm;	if( tnum - tcheck > tdenm )		tquot = 0xffff;*/	/* Multiply denominator by trial quotient digit. */	m16m( tquot, den, tprod );	/* The quotient digit may have been overestimated. */	if( ecmpm( tprod, num ) > 0 )		{		tquot -= 1;		esubm( den, tprod );		if( ecmpm( tprod, num ) > 0 )			{			tquot -= 1;			esubm( den, tprod );			}		}/*	if( ecmpm( tprod, num ) > 0 )		{		eshow( "tprod", tprod );		eshow( "num  ", num );		printf( "tnum = %08lx, tden = %04x, tquot = %04x\n",			 tnum, den[M+1], tquot );		}*/	esubm( tprod, num );/*	if( ecmpm( num, den ) >= 0 )		{		eshow( "num  ", num );		eshow( "den  ", den );		printf( "tnum = %08lx, tden = %04x, tquot = %04x\n",			 tnum, den[M+1], tquot );		}*/	equot[i] = tquot;	eshup6(num);	}/* test for nonzero remainder after roundoff bit */p = &num[M];j = 0;for( i=M; i<NI; i++ )	{	j |= *p++;	}if( j )	j = 1;for( i=0; i<NI; i++ )	num[i] = equot[i];return( (int )j );}/* Multiply significands */static int emulm(short unsigned int *a, short unsigned int *b, LDPARMS *ldp) {unsigned short *p, *q;unsigned short pprod[NI];unsigned short j;int i;unsigned short *equot = ldp->equot;equot[0] = b[0];equot[1] = b[1];for( i=M; i<NI; i++ )	equot[i] = 0;j = 0;p = &a[NI-1];q = &equot[NI-1];for( i=M+1; i<NI; i++ )	{	if( *p == 0 )		{		--p;		}	else		{		m16m( *p--, b, pprod );		eaddm(pprod, equot);		}	j |= *q;	eshdn6(equot);	}for( i=0; i<NI; i++ )	b[i] = equot[i];/* return flag for lost nonzero bits */return( (int)j );}/*static void eshow(str, x)char *str;unsigned short *x;{int i;printf( "%s ", str );for( i=0; i<NI; i++ )	printf( "%04x ", *x++ );printf( "\n" );}*//* * Normalize and round off. * * The internal format number to be rounded is "s". * Input "lost" indicates whether the number is exact. * This is the so-called sticky bit. * * Input "subflg" indicates whether the number was obtained * by a subtraction operation.  In that case if lost is nonzero * then the number is slightly smaller than indicated. * * Input "exp" is the biased exponent, which may be negative. * the exponent field of "s" is ignored but is replaced by * "exp" as adjusted by normalization and rounding. * * Input "rcntrl" is the rounding control. */static void emdnorm(short unsigned int *s, int lost, int subflg, long int exp, int rcntrl, LDPARMS *ldp){int i, j;unsigned short r;/* Normalize */j = enormlz( s );/* a blank significand could mean either zero or infinity. */#ifndef INFINITYif( j > NBITS )	{	ecleazs( s );	return;	}#endifexp -= j;#ifndef INFINITYif( exp >= 32767L )	goto overf;#elseif( (j > NBITS) && (exp < 32767L) )	{	ecleazs( s );	return;	}#endifif( exp < 0L )	{	if( exp > (long )(-NBITS-1) )		{		j = (int )exp;		i = eshift( s, j );		if( i )			lost = 1;		}	else		{		ecleazs( s );		return;		}	}/* Round off, unless told not to by rcntrl. */if( rcntrl == 0 )	goto mdfin;/* Set up rounding parameters if the control register changed. */if( ldp->rndprc != ldp->rlast )	{	ecleaz( ldp->rbit );	switch( ldp->rndprc )		{		default:		case NBITS:			ldp->rw = NI-1; /* low guard word */			ldp->rmsk = 0xffff;			ldp->rmbit = 0x8000;			ldp->rebit = 1;			ldp->re = ldp->rw - 1;			break;		case 113:			ldp->rw = 10;			ldp->rmsk = 0x7fff;			ldp->rmbit = 0x4000;			ldp->rebit = 0x8000;			ldp->re = ldp->rw;			break;		case 64:			ldp->rw = 7;			ldp->rmsk = 0xffff;			ldp->rmbit = 0x8000;			ldp->rebit = 1;			ldp->re = ldp->rw-1;			break;/* For DEC arithmetic */		case 56:			ldp->rw = 6;			ldp->rmsk = 0xff;			ldp->rmbit = 0x80;			ldp->rebit = 0x100;			ldp->re = ldp->rw;			break;		case 53:			ldp->rw = 6;			ldp->rmsk = 0x7ff;			ldp->rmbit = 0x0400;			ldp->rebit = 0x800;			ldp->re = ldp->rw;			break;		case 24:			ldp->rw = 4;			ldp->rmsk = 0xff;			ldp->rmbit = 0x80;			ldp->rebit = 0x100;			ldp->re = ldp->rw;			break;		}	ldp->rbit[ldp->re] = ldp->rebit;	ldp->rlast = ldp->rndprc;	}/* Shift down 1 temporarily if the data structure has an implied * most significant bit and the number is denormal. * For rndprc = 64 or NBITS, there is no implied bit. * But Intel long double denormals lose one bit of significance even so. */#if IBMPCif( (exp <= 0) && (ldp->rndprc != NBITS) )#elseif( (exp <= 0) && (ldp->rndprc != 64) && (ldp->rndprc != NBITS) )#endif	{	lost |= s[NI-1] & 1;	eshdn1(s);	}/* Clear out all bits below the rounding bit, * remembering in r if any were nonzero. */r = s[ldp->rw] & ldp->rmsk;if( ldp->rndprc < NBITS )	{	i = ldp->rw + 1;	while( i < NI )		{		if( s[i] )			r |= 1;		s[i] = 0;		++i;		}	}s[ldp->rw] &= ~ldp->rmsk;if( (r & ldp->rmbit) != 0 )	{	if( r == ldp->rmbit )		{		if( lost == 0 )			{ /* round to even */			if( (s[ldp->re] & ldp->rebit) == 0 )				goto mddone;			}		else			{			if( subflg != 0 )				goto mddone;			}		}	eaddm( ldp->rbit, s );	}mddone:#if IBMPCif( (exp <= 0) && (ldp->rndprc != NBITS) )#elseif( (exp <= 0) && (ldp->rndprc != 64) && (ldp->rndprc != NBITS) )#endif	{	eshup1(s);	}if( s[2] != 0 )	{ /* overflow on roundoff */	eshdn1(s);	exp += 1;	}mdfin:s[NI-1] = 0;if( exp >= 32767L )	{#ifndef INFINITYoverf:#endif#ifdef INFINITY	s[1] = 32767;	for( i=2; i<NI-1; i++ )		s[i] = 0;#else	s[1] = 32766;	s[2] = 0;	for( i=M+1; i<NI-1; i++ )		s[i] = 0xffff;	s[NI-1] = 0;	if( (ldp->rndprc < 64) || (ldp->rndprc == 113) )		{		s[ldp->rw] &= ~ldp->rmsk;		if( ldp->rndprc == 24 )			{			s[5] = 0;			s[6] = 0;			}		}#endif	return;	}if( exp < 0 )	s[1] = 0;else	s[1] = (unsigned short )exp;}/*;	Subtract external format numbers.;;	unsigned short a[NE], b[NE], c[NE];;       LDPARMS *ldp;;	esub( a, b, c, ldp );	 c = b - a*/static void esub(short unsigned int *a, short unsigned int *b, short unsigned int *c, LDPARMS *ldp){#ifdef NANS

⌨️ 快捷键说明

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