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

📄 ieee.c

📁 win32program disassembler
💻 C
📖 第 1 页 / 共 5 页
字号:
int lost;
int subflg;
long exp;
int rcntrl;
{
int i, j;
unsigned short r;

/* Normalize */
j = enormlz( s );

/* a blank significand could mean either zero or infinity. */
#ifndef INFINITY
if( j > NBITS )
	{
	ecleazs( s );
	return;
	}
#endif
exp -= j;
#ifndef INFINITY
if( exp >= 32767L )
	goto overf;
#else
if( (j > NBITS) && (exp < 32767L) )
	{
	ecleazs( s );
	return;
	}
#endif
if( 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( rndprc != rlast )
	{
	ecleaz( rbit );
	switch( rndprc )
		{
		default:
		case NBITS:
			rw = NI-1; /* low guard word */
			rmsk = 0xffff;
			rmbit = 0x8000;
			rebit = 1;
			re = rw - 1;
			break;
		case 113:
			rw = 10;
			rmsk = 0x7fff;
			rmbit = 0x4000;
			rebit = 0x8000;
			re = rw;
			break;
		case 64:
			rw = 7;
			rmsk = 0xffff;
			rmbit = 0x8000;
			rebit = 1;
			re = rw-1;
			break;
/* For DEC arithmetic */
		case 56:
			rw = 6;
			rmsk = 0xff;
			rmbit = 0x80;
			rebit = 0x100;
			re = rw;
			break;
		case 53:
			rw = 6;
			rmsk = 0x7ff;
			rmbit = 0x0400;
			rebit = 0x800;
			re = rw;
			break;
		case 24:
			rw = 4;
			rmsk = 0xff;
			rmbit = 0x80;
			rebit = 0x100;
			re = rw;
			break;
		}
	rbit[re] = rebit;
	rlast = 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.
 */
#ifdef IBMPC
if( (exp <= 0) && (rndprc != NBITS) )
#else
if( (exp <= 0) && (rndprc != 64) && (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[rw] & rmsk;
if( rndprc < NBITS )
	{
	i = rw + 1;
	while( i < NI )
		{
		if( s[i] )
			r |= 1;
		s[i] = 0;
		++i;
		}
	}
s[rw] &= ~rmsk;
if( (r & rmbit) != 0 )
	{
	if( r == rmbit )
		{
		if( lost == 0 )
			{ /* round to even */
			if( (s[re] & rebit) == 0 )
				goto mddone;
			}
		else
			{
			if( subflg != 0 )
				goto mddone;
			}
		}
	eaddm( rbit, s );
	}
mddone:
#ifdef IBMPC
if( (exp <= 0) && (rndprc != NBITS) )
#else
if( (exp <= 0) && (rndprc != 64) && (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 INFINITY
overf:
#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( (rndprc < 64) || (rndprc == 113) )
		{
		s[rw] &= ~rmsk;
		if( 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];
;	esub( a, b, c );	 c = b - a
*/

static int subflg = 0;

void esub( a, b, c )
unsigned short *a, *b, *c;
{

#ifdef NANS
if( eisnan(a) )
	{
	emov (a, c);
	return;
	}
if( eisnan(b) )
	{
	emov(b,c);
	return;
	}
/* Infinity minus infinity is a NaN.
 * Test for subtracting infinities of the same sign.
 */
if( eisinf(a) && eisinf(b) && ((eisneg (a) ^ eisneg (b)) == 0))
	{
	mtherr( "esub", DOMAIN );
	enan( c, NBITS );
	return;
	}
#endif
subflg = 1;
eadd1( a, b, c );
}


/*
;	Add.
;
;	unsigned short a[NE], b[NE], c[NE];
;	eadd( a, b, c );	 c = b + a
*/
void eadd( a, b, c )
unsigned short *a, *b, *c;
{

#ifdef NANS
/* NaN plus anything is a NaN. */
if( eisnan(a) )
	{
	emov(a,c);
	return;
	}
if( eisnan(b) )
	{
	emov(b,c);
	return;
	}
/* Infinity minus infinity is a NaN.
 * Test for adding infinities of opposite signs.
 */
if( eisinf(a) && eisinf(b)
	&& ((eisneg(a) ^ eisneg(b)) != 0) )
	{
	mtherr( "eadd", DOMAIN );
	enan( c, NBITS );
	return;
	}
#endif
subflg = 0;
eadd1( a, b, c );
}

void eadd1( a, b, c )
unsigned short *a, *b, *c;
{
unsigned short ai[NI], bi[NI], ci[NI];
int i, lost, j, k;
long lt, lta, ltb;

#ifdef INFINITY
if( eisinf(a) )
	{
	emov(a,c);
	if( subflg )
		eneg(c);
	return;
	}
if( eisinf(b) )
	{
	emov(b,c);
	return;
	}
#endif
emovi( a, ai );
emovi( b, bi );
if( subflg )
	ai[0] = ~ai[0];

/* compare exponents */
lta = ai[E];
ltb = bi[E];
lt = lta - ltb;
if( lt > 0L )
	{	/* put the larger number in bi */
	emovz( bi, ci );
	emovz( ai, bi );
	emovz( ci, ai );
	ltb = bi[E];
	lt = -lt;
	}
lost = 0;
if( lt != 0L )
	{
	if( lt < (long )(-NBITS-1) )
		goto done;	/* answer same as larger addend */
	k = (int )lt;
	lost = eshift( ai, k ); /* shift the smaller number down */
	}
else
	{
/* exponents were the same, so must compare significands */
	i = ecmpm( ai, bi );
	if( i == 0 )
		{ /* the numbers are identical in magnitude */
		/* if different signs, result is zero */
		if( ai[0] != bi[0] )
			{
			eclear(c);
			return;
			}
		/* if same sign, result is double */
		/* double denomalized tiny number */
		if( (bi[E] == 0) && ((bi[3] & 0x8000) == 0) )
			{
			eshup1( bi );
			goto done;
			}
		/* add 1 to exponent unless both are zero! */
		for( j=1; j<NI-1; j++ )
			{
			if( bi[j] != 0 )
				{
				ltb += 1;
				if( ltb >= 0x7fff )
					{
					eclear(c);
					einfin(c);
					if( ai[0] != 0 )
						eneg(c);
					return;
					}
				break;
				}
			}
		bi[E] = (unsigned short )ltb;
		goto done;
		}
	if( i > 0 )
		{	/* put the larger number in bi */
		emovz( bi, ci );
		emovz( ai, bi );
		emovz( ci, ai );
		}
	}
if( ai[0] == bi[0] )
	{
	eaddm( ai, bi );
	subflg = 0;
	}
else
	{
	esubm( ai, bi );
	subflg = 1;
	}
emdnorm( bi, lost, subflg, ltb, 64 );

done:
emovo( bi, c );
}



/*
;	Divide.
;
;	unsigned short a[NE], b[NE], c[NE];
;	ediv( a, b, c );	c = b / a
*/
void ediv( a, b, c )
unsigned short *a, *b, *c;
{
unsigned short ai[NI], bi[NI];
int i, sign;
long lt, lta, ltb;

/* IEEE says if result is not a NaN, the sign is "-" if and only if
   operands have opposite signs -- but flush -0 to 0 later if not IEEE.  */
sign = eisneg(a) ^ eisneg(b);

#ifdef NANS
/* Return any NaN input. */
if( eisnan(a) )
	{
	emov(a,c);
	return;
	}
if( eisnan(b) )
	{
	emov(b,c);
	return;
	}
/* Zero over zero, or infinity over infinity, is a NaN. */
if( ((ecmp(a,ezero) == 0) && (ecmp(b,ezero) == 0))
	|| (eisinf (a) && eisinf (b)) )
	{
	mtherr( "ediv", DOMAIN );
	enan( c, NBITS );
	return;
	}
#endif
/* Infinity over anything else is infinity. */
#ifdef INFINITY
if( eisinf(b) )
	{
	einfin(c);
	goto divsign;
	}
if( eisinf(a) )
	{
	eclear(c);
	goto divsign;
	}
#endif
emovi( a, ai );
emovi( b, bi );
lta = ai[E];
ltb = bi[E];
if( bi[E] == 0 )
	{ /* See if numerator is zero. */
	for( i=1; i<NI-1; i++ )
		{
		if( bi[i] != 0 )
			{
			ltb -= enormlz( bi );
			goto dnzro1;
			}
		}
	eclear(c);
	goto divsign;
	}
dnzro1:

if( ai[E] == 0 )
	{	/* possible divide by zero */
	for( i=1; i<NI-1; i++ )
		{
		if( ai[i] != 0 )
			{
			lta -= enormlz( ai );
			goto dnzro2;
			}
		}
	einfin(c);
	mtherr( "ediv", SING );
	goto divsign;
	}
dnzro2:

i = edivm( ai, bi );
/* calculate exponent */
lt = ltb - lta + EXONE;
emdnorm( bi, i, 0, lt, 64 );
emovo( bi, c );

divsign:

if( sign )
	*(c+(NE-1)) |= 0x8000;
else
	*(c+(NE-1)) &= ~0x8000;
}



/*
;	Multiply.
;
;	unsigned short a[NE], b[NE], c[NE];
;	emul( a, b, c );	c = b * a
*/
void emul( a, b, c )
unsigned short *a, *b, *c;
{
unsigned short ai[NI], bi[NI];
int i, j, sign;
long lt, lta, ltb;

/* IEEE says if result is not a NaN, the sign is "-" if and only if
   operands have opposite signs -- but flush -0 to 0 later if not IEEE.  */
sign = eisneg(a) ^ eisneg(b);

#ifdef NANS
/* NaN times anything is the same NaN. */
if( eisnan(a) )
	{
	emov(a,c);
	return;
	}
if( eisnan(b) )
	{
	emov(b,c);
	return;
	}
/* Zero times infinity is a NaN. */
if( (eisinf(a) && (ecmp(b,ezero) == 0))
	|| (eisinf(b) && (ecmp(a,ezero) == 0)) )
	{
	mtherr( "emul", DOMAIN );
	enan( c, NBITS );
	return;
	}
#endif
/* Infinity times anything else is infinity. */
#ifdef INFINITY
if( eisinf(a) || eisinf(b) )
	{
	einfin(c);
	goto mulsign;
	}
#endif
emovi( a, ai );
emovi( b, bi );
lta = ai[E];
ltb = bi[E];
if( ai[E] == 0 )
	{
	for( i=1; i<NI-1; i++ )
		{
		if( ai[i] != 0 )
			{
			lta -= enormlz( ai );
			goto mnzer1;
			}
		}
	eclear(c);
	goto mulsign;
	}
mnzer1:

if( bi[E] == 0 )
	{
	for( i=1; i<NI-1; i++ )
		{
		if( bi[i] != 0 )
			{
			ltb -= enormlz( bi );
			goto mnzer2;
			}
		}
	eclear(c);
	goto mulsign;
	}
mnzer2:

/* Multiply significands */
j = emulm( ai, bi );
/* calculate exponent */
lt = lta + ltb - (EXONE - 1);
emdnorm( bi, j, 0, lt, 64 );
emovo( bi, c );
/*  IEEE says sign is "-" if and only if operands have opposite signs.  */
mulsign:
if( sign )
	*(c+(NE-1)) |= 0x8000;
else
	*(c+(NE-1)) &= ~0x8000;
}




/*
; Convert IEEE double precision to e type
;	double d;
;	unsigned short x[N+2];
;	e53toe( &d, x );
*/
void e53toe( pe, y )
unsigned short *pe, *y;
{
#ifdef DEC

dectoe( pe, y ); /* see etodec.c */

#else

register unsigned short r;
register unsigned short *p, *e;
unsigned short yy[NI];
int denorm, k;

e = pe;
denorm = 0;	/* flag if denormalized number */
ecleaz(yy);
#ifdef IBMPC
e += 3;
#endif
r = *e;
yy[0] = 0;
if( r & 0x8000 )
	yy[0] = 0xffff;
yy[M] = (r & 0x0f) | 0x10;
r &= ~0x800f;	/* strip sign and 4 significand bits */
#ifdef INFINITY
if( r == 0x7ff0 )
	{
#ifdef NANS
#ifdef IBMPC
	if( ((pe[3] & 0xf) != 0) || (pe[2] != 0)
		|| (pe[1] != 0) || (pe[0] != 0) )
		{
		enan( y, NBITS );
		return;
		}
#else
	if( ((pe[0] & 0xf) != 0) || (pe[1] != 0)
		 || (pe[2] != 0) || (pe[3] != 0) )
		{
		enan( y, NBITS );
		return;
		}
#endif
#endif  /* NANS */
	eclear( y );
	einfin( y );
	if( yy[0] )
		eneg(y);
	return;
	}
#endif
r >>= 4;
/* If zero exponent, then the significand is denormalized.
 * So, take back the understood high significand bit. */ 
if( r == 0 )
	{
	denorm = 1;
	yy[M] &= ~0x10;
	}
r += EXONE - 01777;
yy[E] = r;
p = &yy[M+1];
#ifdef IBMPC
*p++ = *(--e);
*p++ = *(--e);
*p++ = *(--e);
#endif
#ifdef MIEEE
++e;
*p++ = *e++;
*p++ = *e++;
*p++ = *e++;
#endif
(void )eshift( yy, -5 );
if( denorm )
	{ /* if zero exponent, then normalize the significand */
	if( (k = enormlz(yy)) > NBITS )
		ecleazs(yy);
	else
		yy[E] -= (unsigned short )(k-1);
	}
emovo( yy, y );
#endif /* not DEC */
}

void e64toe( pe, y )
unsigned short *pe, *y;
{
unsigned short yy[NI];
unsigned short *p, *q, *e;
int i;

e = pe;
p = yy;
for( i=0; i<NE-5; i++ )
	*p++ = 0;
#ifdef IBMPC
for( i=0; i<5; i++ )
	*p++ = *e++;
#endif
#ifdef DEC
for( i=0; i<5; i++ )
	*p++ = *e++;
#endif
#ifdef MIEEE
p = &yy[0] + (NE-1);
*p-- = *e++;
++e;
for( i=0; i<4; i++ )
	*p-- = *e++;

⌨️ 快捷键说明

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