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

📄 ldtoa.c

📁 Newlib 嵌入式 C库 标准实现代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	{ /* if zero exponent, then normalize the significand */	if( (k = enormlz(yy)) > NBITS )		ecleazs(yy);	else		yy[E] -= (unsigned short )(k-1);	}emovo( yy, y, ldp );#endif /* !DEC */}/*; e type to IEEE double precision;	double d;;	unsigned short x[NE];;	etoe53( x, &d );*/#ifdef DECstatic void etoe53( x, e )unsigned short *x, *e;{etodec( x, e ); /* see etodec.c */}static void toe53( x, y )unsigned short *x, *y;{todec( x, y );}#elsestatic void toe53(short unsigned int *x, short unsigned int *y){unsigned short i;unsigned short *p;#ifdef NANSif( eiisnan(x) )	{	enan( y, 53 );	return;	}#endifp = &x[0];#ifdef IBMPCy += 3;#endif#ifdef DECy += 3;#endif*y = 0;	/* output high order */if( *p++ )	*y = 0x8000;	/* output sign bit */i = *p++;if( i >= (unsigned int )2047 )	{	/* Saturate at largest number less than infinity. */#ifdef USE_INFINITY	*y |= 0x7ff0;#ifdef IBMPC	*(--y) = 0;	*(--y) = 0;	*(--y) = 0;#else /* !IBMPC */	++y;	*y++ = 0;	*y++ = 0;	*y++ = 0;#endif /* IBMPC */#else /* !USE_INFINITY */	*y |= (unsigned short )0x7fef;#ifdef IBMPC	*(--y) = 0xffff;	*(--y) = 0xffff;	*(--y) = 0xffff;#else /* !IBMPC */	++y;	*y++ = 0xffff;	*y++ = 0xffff;	*y++ = 0xffff;#endif#endif /* !USE_INFINITY */	return;	}if( i == 0 )	{	(void )eshift( x, 4 );	}else	{	i <<= 4;	(void )eshift( x, 5 );	}i |= *p++ & (unsigned short )0x0f;	/* *p = xi[M] */*y |= (unsigned short )i; /* high order output already has sign bit set */#ifdef IBMPC*(--y) = *p++;*(--y) = *p++;*(--y) = *p;#else /* !IBMPC */++y;*y++ = *p++;*y++ = *p++;*y++ = *p++;#endif /* !IBMPC */}#endif /* not DEC */#endif /* LDBL_MANT_DIG == 53 */#if LDBL_MANT_DIG == 24/*; Convert IEEE single precision to e type;	float d;;	unsigned short x[N+2];;	dtox( &d, x );*/void e24toe( short unsigned int *pe, short unsigned int *y, LDPARMS *ldp ){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 IBMPCe += 1;#endif#ifdef DECe += 1;#endifr = *e;yy[0] = 0;if( r & 0x8000 )	yy[0] = 0xffff;yy[M] = (r & 0x7f) | 0200;r &= ~0x807f;	/* strip sign and 7 significand bits */#ifdef USE_INFINITYif( r == 0x7f80 )	{#ifdef NANS#ifdef MIEEE	if( ((pe[0] & 0x7f) != 0) || (pe[1] != 0) )		{		enan( y, NBITS );		return;		}#else  /* !MIEEE */	if( ((pe[1] & 0x7f) != 0) || (pe[0] != 0) )		{		enan( y, NBITS );		return;		}#endif /* !MIEEE */#endif  /* NANS */	eclear( y );	einfin( y, ldp );	if( yy[0] )		eneg(y);	return;	}#endifr >>= 7;/* If zero exponent, then the significand is denormalized. * So, take back the understood high significand bit. */ if( r == 0 )	{	denorm = 1;	yy[M] &= ~0200;	}r += EXONE - 0177;yy[E] = r;p = &yy[M+1];#ifdef IBMPC*p++ = *(--e);#endif#ifdef DEC*p++ = *(--e);#endif#ifdef MIEEE++e;*p++ = *e++;#endif(void )eshift( yy, -8 );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, ldp );}static void toe24(short unsigned int *x, short unsigned int *y){unsigned short i;unsigned short *p;#ifdef NANSif( eiisnan(x) )	{	enan( y, 24 );	return;	}#endifp = &x[0];#ifdef IBMPCy += 1;#endif#ifdef DECy += 1;#endif*y = 0;	/* output high order */if( *p++ )	*y = 0x8000;	/* output sign bit */i = *p++;if( i >= 255 )	{	/* Saturate at largest number less than infinity. */#ifdef USE_INFINITY	*y |= (unsigned short )0x7f80;#ifdef IBMPC	*(--y) = 0;#endif#ifdef DEC	*(--y) = 0;#endif#ifdef MIEEE	++y;	*y = 0;#endif#else /* !USE_INFINITY */	*y |= (unsigned short )0x7f7f;#ifdef IBMPC	*(--y) = 0xffff;#endif#ifdef DEC	*(--y) = 0xffff;#endif#ifdef MIEEE	++y;	*y = 0xffff;#endif#endif /* !USE_INFINITY */	return;	}if( i == 0 )	{	(void )eshift( x, 7 );	}else	{	i <<= 7;	(void )eshift( x, 8 );	}i |= *p++ & (unsigned short )0x7f;	/* *p = xi[M] */*y |= i;	/* high order output already has sign bit set */#ifdef IBMPC*(--y) = *p;#endif#ifdef DEC*(--y) = *p;#endif#ifdef MIEEE++y;*y = *p;#endif}#endif /* LDBL_MANT_DIG == 24 *//* Compare two e type numbers. * * unsigned short a[NE], b[NE]; * 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. */static int ecmp(short unsigned int *a, short unsigned int *b){unsigned short ai[NI], bi[NI];register unsigned short *p, *q;register int i;int msign;#ifdef NANSif (eisnan (a)  || eisnan (b))	return( -2 );#endifemovi( a, ai );p = ai;emovi( b, bi );q = bi;if( *p != *q )	{ /* the signs are different *//* -0 equals + 0 */	for( i=1; i<NI-1; i++ )		{		if( ai[i] != 0 )			goto nzro;		if( bi[i] != 0 )			goto nzro;		}	return(0);nzro:	if( *p == 0 )		return( 1 );	else		return( -1 );	}/* both are the same sign */if( *p == 0 )	msign = 1;else	msign = -1;i = NI-1;do	{	if( *p++ != *q++ )		{		goto diff;		}	}while( --i > 0 );return(0);	/* equality */diff:if( *(--p) > *(--q) )	return( msign );		/* p is bigger */else	return( -msign );	/* p is littler */}/*;	Shift significand;;	Shifts significand area up or down by the number of bits;	given by the variable sc.*/static int eshift(short unsigned int *x, int sc){unsigned short lost;unsigned short *p;if( sc == 0 )	return( 0 );lost = 0;p = x + NI-1;if( sc < 0 )	{	sc = -sc;	while( sc >= 16 )		{		lost |= *p;	/* remember lost bits */		eshdn6(x);		sc -= 16;		}	while( sc >= 8 )		{		lost |= *p & 0xff;		eshdn8(x);		sc -= 8;		}	while( sc > 0 )		{		lost |= *p & 1;		eshdn1(x);		sc -= 1;		}	}else	{	while( sc >= 16 )		{		eshup6(x);		sc -= 16;		}	while( sc >= 8 )		{		eshup8(x);		sc -= 8;		}	while( sc > 0 )		{		eshup1(x);		sc -= 1;		}	}if( lost )	lost = 1;return( (int )lost );}/*;	normalize;; Shift normalizes the significand area pointed to by argument; shift count (up = positive) is returned.*/static int enormlz(short unsigned int *x){register unsigned short *p;int sc;sc = 0;p = &x[M];if( *p != 0 )	goto normdn;++p;if( *p & 0x8000 )	return( 0 );	/* already normalized */while( *p == 0 )	{	eshup6(x);	sc += 16;/* With guard word, there are NBITS+16 bits available. * return true if all are zero. */	if( sc > NBITS )		return( sc );	}/* see if high byte is zero */while( (*p & 0xff00) == 0 )	{	eshup8(x);	sc += 8;	}/* now shift 1 bit at a time */while( (*p  & 0x8000) == 0)	{	eshup1(x);	sc += 1;	if( sc > (NBITS+16) )		{		mtherr( "enormlz", UNDERFLOW );		return( sc );		}	}return( sc );/* Normalize by shifting down out of the high guard word   of the significand */normdn:if( *p & 0xff00 )	{	eshdn8(x);	sc -= 8;	}while( *p != 0 )	{	eshdn1(x);	sc -= 1;	if( sc < -NBITS )		{		mtherr( "enormlz", OVERFLOW );		return( sc );		}	}return( sc );}/* Convert e type number to decimal format ASCII string. * The constants are for 64 bit precision. */#define NTEN 12#define MAXP 4096#if NE == 10static unsigned short etens[NTEN + 1][NE] ={  {0x6576, 0x4a92, 0x804a, 0x153f,   0xc94c, 0x979a, 0x8a20, 0x5202, 0xc460, 0x7525,},	/* 10**4096 */  {0x6a32, 0xce52, 0x329a, 0x28ce,   0xa74d, 0x5de4, 0xc53d, 0x3b5d, 0x9e8b, 0x5a92,},	/* 10**2048 */  {0x526c, 0x50ce, 0xf18b, 0x3d28,   0x650d, 0x0c17, 0x8175, 0x7586, 0xc976, 0x4d48,},  {0x9c66, 0x58f8, 0xbc50, 0x5c54,   0xcc65, 0x91c6, 0xa60e, 0xa0ae, 0xe319, 0x46a3,},  {0x851e, 0xeab7, 0x98fe, 0x901b,   0xddbb, 0xde8d, 0x9df9, 0xebfb, 0xaa7e, 0x4351,},  {0x0235, 0x0137, 0x36b1, 0x336c,   0xc66f, 0x8cdf, 0x80e9, 0x47c9, 0x93ba, 0x41a8,},  {0x50f8, 0x25fb, 0xc76b, 0x6b71,   0x3cbf, 0xa6d5, 0xffcf, 0x1f49, 0xc278, 0x40d3,},  {0x0000, 0x0000, 0x0000, 0x0000,   0xf020, 0xb59d, 0x2b70, 0xada8, 0x9dc5, 0x4069,},  {0x0000, 0x0000, 0x0000, 0x0000,   0x0000, 0x0000, 0x0400, 0xc9bf, 0x8e1b, 0x4034,},  {0x0000, 0x0000, 0x0000, 0x0000,   0x0000, 0x0000, 0x0000, 0x2000, 0xbebc, 0x4019,},  {0x0000, 0x0000, 0x0000, 0x0000,   0x0000, 0x0000, 0x0000, 0x0000, 0x9c40, 0x400c,},  {0x0000, 0x0000, 0x0000, 0x0000,   0x0000, 0x0000, 0x0000, 0x0000, 0xc800, 0x4005,},  {0x0000, 0x0000, 0x0000, 0x0000,   0x0000, 0x0000, 0x0000, 0x0000, 0xa000, 0x4002,},	/* 10**1 */};static unsigned short emtens[NTEN + 1][NE] ={  {0x2030, 0xcffc, 0xa1c3, 0x8123,   0x2de3, 0x9fde, 0xd2ce, 0x04c8, 0xa6dd, 0x0ad8,},	/* 10**-4096 */  {0x8264, 0xd2cb, 0xf2ea, 0x12d4,   0x4925, 0x2de4, 0x3436, 0x534f, 0xceae, 0x256b,},	/* 10**-2048 */  {0xf53f, 0xf698, 0x6bd3, 0x0158,   0x87a6, 0xc0bd, 0xda57, 0x82a5, 0xa2a6, 0x32b5,},  {0xe731, 0x04d4, 0xe3f2, 0xd332,   0x7132, 0xd21c, 0xdb23, 0xee32, 0x9049, 0x395a,},  {0xa23e, 0x5308, 0xfefb, 0x1155,   0xfa91, 0x1939, 0x637a, 0x4325, 0xc031, 0x3cac,},  {0xe26d, 0xdbde, 0xd05d, 0xb3f6,   0xac7c, 0xe4a0, 0x64bc, 0x467c, 0xddd0, 0x3e55,},  {0x2a20, 0x6224, 0x47b3, 0x98d7,   0x3f23, 0xe9a5, 0xa539, 0xea27, 0xa87f, 0x3f2a,},  {0x0b5b, 0x4af2, 0xa581, 0x18ed,   0x67de, 0x94ba, 0x4539, 0x1ead, 0xcfb1, 0x3f94,},  {0xbf71, 0xa9b3, 0x7989, 0xbe68,   0x4c2e, 0xe15b, 0xc44d, 0x94be, 0xe695, 0x3fc9,},  {0x3d4d, 0x7c3d, 0x36ba, 0x0d2b,   0xfdc2, 0xcefc, 0x8461, 0x7711, 0xabcc, 0x3fe4,},  {0xc155, 0xa4a8, 0x404e, 0x6113,   0xd3c3, 0x652b, 0xe219, 0x1758, 0xd1b7, 0x3ff1,},  {0xd70a, 0x70a3, 0x0a3d, 0xa3d7,   0x3d70, 0xd70a, 0x70a3, 0x0a3d, 0xa3d7, 0x3ff8,},  {0xcccd, 0xcccc, 0xcccc, 0xcccc,   0xcccc, 0xcccc, 0xcccc, 0xcccc, 0xcccc, 0x3ffb,},	/* 10**-1 */};#elsestatic unsigned short etens[NTEN+1][NE] = {{0xc94c,0x979a,0x8a20,0x5202,0xc460,0x7525,},/* 10**4096 */{0xa74d,0x5de4,0xc53d,0x3b5d,0x9e8b,0x5a92,},/* 10**2048 */{0x650d,0x0c17,0x8175,0x7586,0xc976,0x4d48,},{0xcc65,0x91c6,0xa60e,0xa0ae,0xe319,0x46a3,},{0xddbc,0xde8d,0x9df9,0xebfb,0xaa7e,0x4351,},{0xc66f,0x8cdf,0x80e9,0x47c9,0x93ba,0x41a8,},{0x3cbf,0xa6d5,0xffcf,0x1f49,0xc278,0x40d3,},{0xf020,0xb59d,0x2b70,0xada8,0x9dc5,0x4069,},{0x0000,0x0000,0x0400,0xc9bf,0x8e1b,0x4034,},{0x0000,0x0000,0x0000,0x2000,0xbebc,0x4019,},{0x0000,0x0000,0x0000,0x0000,0x9c40,0x400c,},{0x0000,0x0000,0x0000,0x0000,0xc800,0x4005,},{0x0000,0x0000,0x0000,0x0000,0xa000,0x4002,}, /* 10**1 */};static unsigned short emtens[NTEN+1][NE] = {{0x2de4,0x9fde,0xd2ce,0x04c8,0xa6dd,0x0ad8,}, /* 10**-4096 */{0x4925,0x2de4,0x3436,0x534f,0xceae,0x256b,}, /* 10**-2048 */{0x87a6,0xc0bd,0xda57,0x82a5,0xa2a6,0x32b5,},{0x7133,0xd21c,0xdb23,0xee32,0x9049,0x395a,},{0xfa91,0x1939,0x637a,0x4325,0xc031,0x3cac,},{0xac7d,0xe4a0,0x64bc,0x467c,0xddd0,0x3e55,},{0x3f24,0xe9a5,0xa539,0xea27,0xa87f,0x3f2a,},{0x67de,0x94ba,0x4539,0x1ead,0xcfb1,0x3f94,},{0x4c2f,0xe15b,0xc44d,0x94be,0xe695,0x3fc9,},{0xfdc2,0xcefc,0x8461,0x7711,0xabcc,0x3fe4,},{0xd3c3,0x652b,0xe219,0x1758,0xd1b7,0x3ff1,},{0x3d71,0xd70a,0x70a3,0x0a3d,0xa3d7,0x3ff8,},{0xcccd,0xcccc,0xcccc,0xcccc,0xcccc,0x3ffb,}, /* 10**-1 */};#endif/* ASCII string outputs for unix */#if 0void _IO_ldtostr(x, string, ndigs, flags, fmt)long double *x;char *string;int ndigs;int flags;char fmt;{unsigned short w[NI];char *t, *u;LDPARMS rnd;LDPARMS *ldp = &rnd;rnd.rlast = -1;rnd.rndprc = NBITS;if (sizeof(long double) == 16)  e113toe( (unsigned short *)x, w, ldp );else  e64toe( (unsigned short *)x, w, ldp );etoasc( w, string, ndigs, -1, ldp );if( ndigs == 0 && flags == 0 )	{	/* Delete the decimal point unless alternate format.  */	t = string;		while( *t != '.' )		++t;	u = t +  1;	while( *t != '\0' )		*t++ = *u++;	}if (*string == ' ')	{	t = string;		u = t + 1;	while( *t != '\0' )		*t++ = *u++;	}if (fmt == 'E')	{	t = string;		while( *t != 'e' )		++t;	*t = 'E';	}}#endif/* This routine will not return more than NDEC+1 digits. */char *_ldtoa_r (struct _reent *ptr, long double d, int mode, int ndigits, int *decpt,           int *sign, char **rve){unsigned short e[NI];char *s, *p;int i, j, k;int orig_ndigits;LDPARMS rnd;LDPARMS *ldp = &rnd;char *outstr;char outbuf[NDEC + MAX_EXP_DIGITS + 10];union uconv du;du.d = d;orig_ndigits = ndigits;rnd.rlast = -1;rnd.rndprc = NBITS;  _REENT_CHECK_MP(ptr);/* reentrancy addition to use mprec storage pool */if (_REENT_MP_RESULT(ptr))  {    _REENT_MP_RESULT(ptr)->_k = _REENT_MP_RESULT_K(ptr);    _REENT_MP_RESULT(ptr)->_maxwds = 1 << _REENT_MP_RESULT_K(ptr);    Bfree (ptr, _REENT_MP_RESULT(ptr));    _REENT_MP_RESULT(ptr) = 0;  }#if LDBL_MANT_DIG == 24e24toe( &du.pe, e, ldp );#elif LDBL_MANT_DIG == 53e53toe( &du.pe, e, ldp );#elif LDBL_MANT_DIG == 64e64toe( &du.pe, e, ldp );#elsee113toe( &du.pe, e, ldp );#endifif( eisneg(e) )

⌨️ 快捷键说明

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