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

📄 ieee.c

📁 128位长双精度型数字运算包
💻 C
📖 第 1 页 / 共 5 页
字号:
	for( j=0; j<NE-1; j++ )		{		if( t[j] != w[j] )			goto noint;		}	emov( t, u );	expon += (int )m;noint:	p += NE;	m >>= 1;	}while( m != 0 );/* Rescale from integer significand */	u[NE-1] += y[NE-1] - (unsigned int )(EXONE + NBITS - 1);	emov( u, y );/* Find power of 10 */	emov( eone, t );	m = MAXP;	p = &etens[0][0];	while( ecmp( ten, u ) <= 0 )		{		if( ecmp( p, u ) <= 0 )			{			ediv( p, u, u );			emul( p, t, t );			expon += (int )m;			}		m >>= 1;		if( m == 0 )			break;		p += NE;		}	}else	{ /* Number is less than 1.0 *//* Pad significand with trailing decimal zeros. */	if( y[NE-1] == 0 )		{		while( (y[NE-2] & 0x8000) == 0 )			{			emul( ten, y, y );			expon -= 1;			}		}	else		{		emovi( y, w );		for( i=0; i<NDEC+1; i++ )			{			if( (w[NI-1] & 0x7) != 0 )				break;/* multiply by 10 */			emovz( w, u );			eshdn1( u );			eshdn1( u );			eaddm( w, u );			u[1] += 3;			while( u[2] != 0 )				{				eshdn1(u);				u[1] += 1;				}			if( u[NI-1] != 0 )				break;			if( eone[NE-1] <= u[1] )				break;			emovz( u, w );			expon -= 1;			}		emovo( w, y );		}	k = -MAXP;	p = &emtens[0][0];	r = &etens[0][0];	emov( y, w );	emov( eone, t );	while( ecmp( eone, w ) > 0 )		{		if( ecmp( p, w ) >= 0 )			{			emul( r, w, w );			emul( r, t, t );			expon += k;			}		k /= 2;		if( k == 0 )			break;		p += NE;		r += NE;		}	ediv( t, eone, t );	}isone:/* Find the first (leading) digit. */emovi( t, w );emovz( w, t );emovi( y, w );emovz( w, y );eiremain( t, y );digit = equot[NI-1];while( (digit == 0) && (ecmp(y,ezero) != 0) )	{	eshup1( y );	emovz( y, u );	eshup1( u );	eshup1( u );	eaddm( u, y );	eiremain( t, y );	digit = equot[NI-1];	expon -= 1;	}s = string;if( sign )	*s++ = '-';else	*s++ = ' ';/* Examine number of digits requested by caller. */if( ndigs < 0 )	ndigs = 0;if( ndigs > NDEC )	ndigs = NDEC;if( digit == 10 )	{	*s++ = '1';	*s++ = '.';	if( ndigs > 0 )		{		*s++ = '0';		ndigs -= 1;		}	expon += 1;	}else	{	*s++ = (char )digit + '0';	*s++ = '.';	}/* Generate digits after the decimal point. */for( k=0; k<=ndigs; k++ )	{/* multiply current number by 10, without normalizing */	eshup1( y );	emovz( y, u );	eshup1( u );	eshup1( u );	eaddm( u, y );	eiremain( t, y );	*s++ = (char )equot[NI-1] + '0';	}digit = equot[NI-1];--s;ss = s;/* round off the ASCII string */if( digit > 4 )	{/* Test for critical rounding case in ASCII output. */	if( digit == 5 )		{		emovo( y, t );		if( ecmp(t,ezero) != 0 )			goto roun;	/* round to nearest */		if( (*(s-1) & 1) == 0 )			goto doexp;	/* round to even */		}/* Round up and propagate carry-outs */roun:	--s;	k = *s & 0x7f;/* Carry out to most significant digit? */	if( k == '.' )		{		--s;		k = *s;		k += 1;		*s = (char )k;/* Most significant digit carries to 10? */		if( k > '9' )			{			expon += 1;			*s = '1';			}		goto doexp;		}/* Round up and carry out from less significant digits */	k += 1;	*s = (char )k;	if( k > '9' )		{		*s = '0';		goto roun;		}	}doexp:/*if( expon >= 0 )	sprintf( ss, "e+%d", expon );else	sprintf( ss, "e%d", expon );*/	sprintf( ss, "E%d", expon );bxit:rndprc = rndsav;}/*;								ASCTOQ;		ASCTOQ.MAC		LATEST REV: 11 JAN 84;					SLM, 3 JAN 78;;	Convert ASCII string to quadruple precision floating point;;		Numeric input is free field decimal number;		with max of 15 digits with or without ;		decimal point entered as ASCII from teletype.;	Entering E after the number followed by a second;	number causes the second number to be interpreted;	as a power of 10 to be multiplied by the first number;	(i.e., "scientific" notation).;;	Usage:;		asctoq( string, q );*//* ASCII to single */void asctoe24( s, y )char *s;unsigned short *y;{asctoeg( s, y, 24 );}/* ASCII to double */void asctoe53( s, y )char *s;unsigned short *y;{#ifdef DECasctoeg( s, y, 56 );#elseasctoeg( s, y, 53 );#endif}/* ASCII to long double */void asctoe64( s, y )char *s;unsigned short *y;{asctoeg( s, y, 64 );}/* ASCII to 128-bit long double */void asctoe113 (s, y)char *s;unsigned short *y;{asctoeg( s, y, 113 );}/* ASCII to super double */void asctoe( s, y )char *s;unsigned short *y;{asctoeg( s, y, NBITS );}/* Space to make a copy of the input string: */static char lstr[82] = {0};void asctoeg( ss, y, oprec )char *ss;unsigned short *y;int oprec;{unsigned short yy[NI], xt[NI], tt[NI];int esign, decflg, sgnflg, nexp, exp, prec, lost;int k, trail, c, rndsav;long lexp;unsigned short nsign, *p;char *sp, *s;/* Copy the input string. */s = ss;while( *s == ' ' ) /* skip leading spaces */	++s;sp = lstr;for( k=0; k<79; k++ )	{	if( (*sp++ = *s++) == '\0' )		break;	}*sp = '\0';s = lstr;rndsav = rndprc;rndprc = NBITS; /* Set to full precision */lost = 0;nsign = 0;decflg = 0;sgnflg = 0;nexp = 0;exp = 0;prec = 0;ecleaz( yy );trail = 0;nxtcom:k = *s - '0';if( (k >= 0) && (k <= 9) )	{/* Ignore leading zeros */	if( (prec == 0) && (decflg == 0) && (k == 0) )		goto donchr;/* Identify and strip trailing zeros after the decimal point. */	if( (trail == 0) && (decflg != 0) )		{		sp = s;		while( (*sp >= '0') && (*sp <= '9') )			++sp;/* Check for syntax error */		c = *sp & 0x7f;		if( (c != 'e') && (c != 'E') && (c != '\0')			&& (c != '\n') && (c != '\r') && (c != ' ')			&& (c != ',') )			goto error;		--sp;		while( *sp == '0' )			*sp-- = 'z';		trail = 1;		if( *s == 'z' )			goto donchr;		}/* If enough digits were given to more than fill up the yy register, * continuing until overflow into the high guard word yy[2] * guarantees that there will be a roundoff bit at the top * of the low guard word after normalization. */	if( yy[2] == 0 )		{		if( decflg )			nexp += 1; /* count digits after decimal point */		eshup1( yy );	/* multiply current number by 10 */		emovz( yy, xt );		eshup1( xt );		eshup1( xt );		eaddm( xt, yy );		ecleaz( xt );		xt[NI-2] = (unsigned short )k;		eaddm( xt, yy );		}	else		{		/* Mark any lost non-zero digit.  */		lost |= k;		/* Count lost digits before the decimal point.  */		if (decflg == 0)		        nexp -= 1;		}	prec += 1;	goto donchr;	}switch( *s )	{	case 'z':		break;	case 'E':	case 'e':		goto expnt;	case '.':	/* decimal point */		if( decflg )			goto error;		++decflg;		break;	case '-':		nsign = 0xffff;		if( sgnflg )			goto error;		++sgnflg;		break;	case '+':		if( sgnflg )			goto error;		++sgnflg;		break;	case ',':	case ' ':	case '\0':	case '\n':	case '\r':		goto daldone;	case 'i':	case 'I':		goto infinite;	default:	error:#ifdef NANS		enan( yy, NI*16 );#else		mtherr( "asctoe", DOMAIN );		ecleaz(yy);#endif		goto aexit;	}donchr:++s;goto nxtcom;/* Exponent interpretation */expnt:esign = 1;exp = 0;++s;/* check for + or - */if( *s == '-' )	{	esign = -1;	++s;	}if( *s == '+' )	++s;while( (*s >= '0') && (*s <= '9') )	{	exp *= 10;	exp += *s++ - '0';	if (exp > 4977)		{		if (esign < 0)			goto zero;		else			goto infinite;		}	}if( esign < 0 )	exp = -exp;if( exp > 4932 )	{infinite:	ecleaz(yy);	yy[E] = 0x7fff;  /* infinity */	goto aexit;	}if( exp < -4977 )	{zero:	ecleaz(yy);	goto aexit;	}daldone:nexp = exp - nexp;/* Pad trailing zeros to minimize power of 10, per IEEE spec. */while( (nexp > 0) && (yy[2] == 0) )	{	emovz( yy, xt );	eshup1( xt );	eshup1( xt );	eaddm( yy, xt );	eshup1( xt );	if( xt[2] != 0 )		break;	nexp -= 1;	emovz( xt, yy );	}if( (k = enormlz(yy)) > NBITS )	{	ecleaz(yy);	goto aexit;	}lexp = (EXONE - 1 + NBITS) - k;emdnorm( yy, lost, 0, lexp, 64 );/* convert to external format *//* Multiply by 10**nexp.  If precision is 64 bits, * the maximum relative error incurred in forming 10**n * for 0 <= n <= 324 is 8.2e-20, at 10**180. * For 0 <= n <= 999, the peak relative error is 1.4e-19 at 10**947. * For 0 >= n >= -999, it is -1.55e-19 at 10**-435. */lexp = yy[E];if( nexp == 0 )	{	k = 0;	goto expdon;	}esign = 1;if( nexp < 0 )	{	nexp = -nexp;	esign = -1;	if( nexp > 4096 )		{ /* Punt.  Can't handle this without 2 divides. */		emovi( etens[0], tt );		lexp -= tt[E];		k = edivm( tt, yy );		lexp += EXONE;		nexp -= 4096;		}	}p = &etens[NTEN][0];emov( eone, xt );exp = 1;do	{	if( exp & nexp )		emul( p, xt, xt );	p -= NE;	exp = exp + exp;	}while( exp <= MAXP );emovi( xt, tt );if( esign < 0 )	{	lexp -= tt[E];	k = edivm( tt, yy );	lexp += EXONE;	}else	{	lexp += tt[E];	k = emulm( tt, yy );	lexp -= EXONE - 1;	}expdon:/* Round and convert directly to the destination type */if( oprec == 53 )	lexp -= EXONE - 0x3ff;else if( oprec == 24 )	lexp -= EXONE - 0177;#ifdef DECelse if( oprec == 56 )	lexp -= EXONE - 0201;#endifrndprc = oprec;emdnorm( yy, k, 0, lexp, 64 );aexit:rndprc = rndsav;yy[0] = nsign;switch( oprec )	{#ifdef DEC	case 56:		todec( yy, y ); /* see etodec.c */		break;#endif	case 53:		toe53( yy, y );		break;	case 24:		toe24( yy, y );		break;	case 64:		toe64( yy, y );		break;	case 113:		toe113( yy, y );		break;	case NBITS:		emovo( yy, y );		break;	}} /* y = largest integer not greater than x * (truncated toward minus infinity) * * unsigned short x[NE], y[NE] * * efloor( x, y ); */static unsigned short bmask[] = {0xffff,0xfffe,0xfffc,0xfff8,0xfff0,0xffe0,0xffc0,0xff80,0xff00,0xfe00,0xfc00,0xf800,0xf000,0xe000,0xc000,0x8000,0x0000,};void efloor( x, y )unsigned short x[], y[];{register unsigned short *p;int e, expon, i;unsigned short f[NE];emov( x, f ); /* leave in external format */expon = (int )f[NE-1];e = (expon & 0x7fff) - (EXONE - 1);if( e <= 0 )	{	eclear(y);	goto isitneg;	}/* number of bits to clear out */e = NBITS - e;emov( f, y );if( e <= 0 )	return;p = &y[0];while( e >= 16 )	{	*p++ = 0;	e -= 16;	}/* clear the remaining bits */*p &= bmask[e];/* truncate negatives toward minus infinity */isitneg:if( (unsigned short )expon & (unsigned short )0x8000 )	{	for( i=0; i<NE-1; i++ )		{		if( f[i] != y[i] )			{			esub( eone, y, y );			break;			}		}	}}/* unsigned short x[], s[]; * long *exp; * * efrexp( x, exp, s ); * * Returns s and exp such that  s * 2**exp = x and .5 <= s < 1. * For example, 1.1 = 0.55 * 2**1 * Handles denormalized numbers properly using long integer exp. */void efrexp( x, exp, s )unsigned short x[];long *exp;unsigned short s[];{unsigned short xi[NI];long li;emovi( x, xi );li = (long )((short )xi[1]);if( li == 0 )	{	li -= enormlz( xi );	}xi[1] = 0x3ffe;emovo( xi, s );*exp = li - 0x3ffe;}/* unsigned short x[], y[]; * long pwr2; * * eldexp( x, pwr2, y ); * * Returns y = x * 2**pwr2. */void eldexp( x, pwr2, y )unsigned short x[];long pwr2;unsigned short y[];{unsigned short xi[NI];long li;int i;emovi( x, xi );li = xi[1];li += pwr2;i = 0;emdnorm( xi, i, i, li, 64 );emovo( xi, y );}/* c = remainder after dividing b by a * Least significant integer quotient bits left in equot[]. */void eremain( a, b, c )unsigned short a[], b[], c[];{unsigned short den[NI], num[NI];#ifdef NANSif( eisinf(b) || (ecmp(a,ezero) == 0) || eisnan(a) || eisnan(b))	{	enan( c, NBITS );	return;	}#endifif( ecmp(a,ezero) == 0 )	{	mtherr( "eremain", SING );	eclear( c );	return;	}emovi( a, den );emovi( b, num );eiremain( den, num );/* Sign of remainder = sign of quotient */if( a[0] == b[0] )	num[0] = 0;else	num[0] = 0xffff;emovo( num, c );}void eiremain( den, num )unsigned short den[], num[];{long ld, ln;unsigned short j;ld = den[E];ld -= enormlz( den );ln = num[E];ln -= enormlz( num );ecleaz( equot );while( ln >= ld )	{	if( ecmpm(den,num) <= 0 )		{		esubm(den, num);		j = 1;		}	else		{		j = 0;		}	eshup1(equot);	equot[NI-1] |= j;	eshup1(num);	ln -= 1;	}emdnorm( num, 0, 0, ln, 0 );}/* NaN bit patterns */#ifdef MIEEEunsigned short nan113[8] = {  0x7fff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff};unsigned short nan64[6] = {0x7fff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff};unsigned short nan53[4] = {0x7fff, 0xffff, 0xffff, 0xffff};unsigned short nan24[2] = {0x7fff, 0xffff};#endif#ifdef IBMPCunsigned short nan113[8] = {0, 0, 0, 0, 0, 0, 0xc000, 0xffff};unsigned short nan64[6] = {0, 0, 0, 0xc000, 0xffff, 0};unsigned short nan53[4] = {0, 0, 0, 0xfff8};unsigned short nan24[2] = {0, 0xffc0};#endifvoid enan (nan, size)unsigned short *nan;int size;{i

⌨️ 快捷键说明

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