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

📄 ieee.c

📁 win32program disassembler
💻 C
📖 第 1 页 / 共 5 页
字号:
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, NBITS );
		return;
		}
#endif
	einfin(b);
	return;
	}
#endif
/* skip over guard word */
++p;
/* move the significand */
for( i=0; i<NE-1; i++ )
	*q-- = *p++;
}




/* Clear out internal format number.
 */

void ecleaz( xi )
register unsigned short *xi;
{
register int i;

for( i=0; i<NI; i++ )
	*xi++ = 0;
}

/* same, but don't touch the sign. */

void ecleazs( xi )
register unsigned short *xi;
{
register int i;

++xi;
for(i=0; i<NI-1; i++)
	*xi++ = 0;
}




/* Move internal format number from a to b.
 */
void emovz( a, b )
register unsigned short *a, *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.
 */

int eiisnan (x)
unsigned short x[];
{
int i;

if( (x[E] & 0x7fff) == 0x7fff )
	{
	for( i=M+1; i<NI; i++ )
		{
		if( x[i] != 0 )
			return(1);
		}
	}
return(0);
}

#ifdef INFINITY
/* 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

/*
;	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
*/
int ecmpm( a, b )
register unsigned short *a, *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
*/

void eshdn1(x)
register unsigned short *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
*/

void eshup1(x)
register unsigned short *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
*/

void eshdn8(x)
register unsigned short *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
*/

void eshup8(x)
register unsigned short *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
*/

void eshup6(x)
register unsigned short *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
*/

void eshdn6(x)
register unsigned short *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
*/

void eaddm( x, y )
unsigned short *x, *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
*/

void esubm( x, y )
unsigned short *x, *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 */

static unsigned short equot[NI] = {0}; /* was static */

#if 0
int edivm( den, num )
unsigned short den[], num[];
{
int i;
register unsigned short *p, *q;
unsigned short j;

p = &equot[0];
*p++ = num[0];
*p++ = num[1];

for( i=M; i<NI; i++ )
	{
	*p++ = 0;
	}

/* Use faster compare and subtraction if denominator
 * has only 15 bits of significance.
 */
p = &den[M+2];
if( *p++ == 0 )
	{
	for( i=M+3; i<NI; i++ )
		{
		if( *p++ != 0 )
			goto fulldiv;
		}
	if( (den[M+1] & 1) != 0 )
		goto fulldiv;
	eshdn1(num);
	eshdn1(den);

	p = &den[M+1];
	q = &num[M+1];

	for( i=0; i<NBITS+2; i++ )
		{
		if( *p <= *q )
			{
			*q -= *p;
			j = 1;
			}
		else
			{
			j = 0;
			}
		eshup1(equot);
		equot[NI-2] |= j;
		eshup1(num);
		}
	goto divdon;
	}

/* The number of quotient bits to calculate is
 * NBITS + 1 scaling guard bit + 1 roundoff bit.
 */
fulldiv:

p = &equot[NI-2];
for( i=0; i<NBITS+2; i++ )
	{
	if( ecmpm(den,num) <= 0 )
		{
		esubm(den, num);
		j = 1;	/* quotient bit = 1 */
		}
	else
		j = 0;
	eshup1(equot);
	*p |= j;
	eshup1(num);
	}

divdon:

eshdn1( equot );
eshdn1( equot );

/* 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 */
int emulm( a, b )
unsigned short a[], b[];
{
unsigned short *p, *q;
int i, j, k;

equot[0] = b[0];
equot[1] = b[1];
for( i=M; i<NI; i++ )
	equot[i] = 0;

p = &a[NI-2];
k = NBITS;
while( *p == 0 ) /* significand is not supposed to be all zero */
	{
	eshdn6(a);
	k -= 16;
	}
if( (*p & 0xff) == 0 )
	{
	eshdn8(a);
	k -= 8;
	}

q = &equot[NI-1];
j = 0;
for( i=0; i<k; i++ )
	{
	if( *p & 1 )
		eaddm(b, equot);
/* remember if there were any nonzero bits shifted out */
	if( *q & 1 )
		j |= 1;
	eshdn1(a);
	eshdn1(equot);
	}

for( i=0; i<NI; i++ )
	b[i] = equot[i];

/* return flag for lost nonzero bits */
return(j);
}

#else

/* Multiply significand of e-type number b
by 16-bit quantity a, e-type result to c. */

void m16m( a, b, c )
unsigned short a;
unsigned short b[], 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 denominator
is permitted to have its high guard word nonzero.  */


int edivm( den, num )
unsigned short den[], num[];
{
int i;
register unsigned short *p;
unsigned long tnum;
unsigned short j, tdenm, tquot;
unsigned short tprod[NI+1];

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 * 0xffffL) < 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 */
int emulm( a, b )
unsigned short a[], b[];
{
unsigned short *p, *q;
unsigned short pprod[NI];
unsigned short j;
int i;

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 );
}


/*
eshow(str, x)
char *str;
unsigned short *x;
{
int i;

printf( "%s ", str );
for( i=0; i<NI; i++ )
	printf( "%04x ", *x++ );
printf( "\n" );
}
*/
#endif



/*
 * 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 int rlast = -1;
static int rw = 0;
static unsigned short rmsk = 0;
static unsigned short rmbit = 0;
static unsigned short rebit = 0;
static int re = 0;
static unsigned short rbit[NI] = {0,0,0,0,0,0,0,0};

void emdnorm( s, lost, subflg, exp, rcntrl )
unsigned short s[];

⌨️ 快捷键说明

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