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

📄 double_decim.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#if !defined(lint) && defined(SCCSIDS)static char     sccsid[] = "@(#)double_decim.c 1.1 92/07/30 SMI";#endif/* * Copyright (c) 1988 by Sun Microsystems, Inc. *//* Conversion between binary and decimal floating point. */#include "base_conversion.h"/* PRIVATE FUNCTIONS */voiddecimal_round(pm, pd, ps, round, sticky)	decimal_mode   *pm;	decimal_record *pd;	fp_exception_field_type *ps;	char            round;	unsigned        sticky;/* * Rounds decimal record *pd according to modes in *pm, recording exceptions * for inexact or overflow in *ps.  round is the round digit and sticky is 0 * or non-zero to indicate exact or inexact. pd->ndigits is expected to be * correctly set. */{	int             lsd, i;	if ((round == '0') && (sticky == 0)) {	/* Exact. */		goto done;	}	*ps |= 1 << fp_inexact;	switch (pm->rd) {	case fp_nearest:		if (round < '5')			goto done;		if (round > '5')			goto roundup;		if (sticky != 0)			goto roundup;		/* Now in ambiguous case; round up if lsd is odd. */		if (pd->ndigits <= 0)			goto done;	/* Presumed 0. */		lsd = pd->ds[pd->ndigits - 1] - '0';		if ((lsd % 2) == 0)			goto done;		goto roundup;	case fp_positive:		if (pd->sign != 0)			goto done;		goto roundup;	case fp_negative:		if (pd->sign == 0)			goto done;		goto roundup;	case fp_tozero:		goto done;	}roundup:	for (i = (pd->ndigits - 1); (pd->ds[i] == '9') && (i >= 0); i--)		pd->ds[i] = '0';	if (i >= 0)		(pd->ds[i])++;	else {			/* Rounding carry out has occurred. */		pd->ds[0] = '1';		if (pm->df == floating_form) {	/* For E format, simply						 * adjust exponent. */			pd->exponent++;		} else {	/* For F format, increase length of string. */			if (pd->ndigits > 0)				pd->ds[pd->ndigits] = '0';			pd->ndigits++;		}	}	goto ret;done:	if (pd->ndigits <= 0) {	/* Create zero string. */		pd->ds[0] = '0';		pd->ndigits = 1;	}ret:	pd->ds[pd->ndigits] = 0;/* Terminate string. */	return;}voidbinary_to_decimal_integer(pu, nsig, ds, nzeros, ndigs)	unpacked       *pu;	/* Input unpacked integer value input. */	unsigned        nsig;	/* Input number of significant digits				 * required. */	char            ds[];	/* Output decimal integer string output -				 * must be large enough. */unsigned       *nzeros;		/* Output number of implicit trailing zeros				 * produced. */unsigned       *ndigs;		/* Output number of explicit digits produced				 * in ds. *//* * Converts an unpacked integer value *pu into a decimal string in *ds, of * length returned in *ndigs. /* Inexactness is indicated by setting * ds[ndigs-1] odd. */{	_big_float     *pd, b, d;	int             e, i, is;	_BIG_FLOAT_DIGIT stickyshift;	char            s[4];	b.bsize = _BIG_FLOAT_SIZE;	/* Initialize sizes of big floats. */	d.bsize = _BIG_FLOAT_SIZE;	_unpacked_to_big_float(pu, &b, &e);	if (e < 0) {		_right_shift_base_two(&b, (short unsigned) -e, &stickyshift);#ifdef DEBUG		assert(stickyshift == 0);#endif	}	_big_binary_to_big_decimal(&b, &d);	if (e <= 0)		pd = &d;	else {		_big_float_times_power(&d, 2, e, (int) nsig, &pd);		switch (pd) {		case BIG_FLOAT_TIMES_TOOBIG:			{				char            bcastring[80];				(void) sprintf(bcastring, " binary exponent %d ", e);				_base_conversion_abort(ERANGE, bcastring);				break;			}		case BIG_FLOAT_TIMES_NOMEM:			{				char            bcastring[80];				(void) sprintf(bcastring, " binary exponent %d ", e);				_base_conversion_abort(ENOMEM, bcastring);				break;			}		default:#ifdef DEBUG			if (pd != &d)				(void) printf(" large binary exponent %d needs heap buffer \n", e);			printf(" product ");			_display_big_float(pd, 10);#endif			break;		}	}	_fourdigitsquick((short unsigned) pd->bsignificand[pd->blength - 1], s);	for (i = 0; s[i] == '0'; i++);	/* Find first non-zero digit. */	for (is = 0; i <= 3;)		ds[is++] = s[i++];	/* Copy subsequent digits. */	for (i = (pd->blength - 2); i >= 0; i--) {	/* Convert powers of							 * 10**4 to decimal							 * digits. */		_fourdigitsquick((short unsigned) pd->bsignificand[i], &(ds[is]));		is += 4;	}	ds[is] = 0;	*ndigs = is;	*nzeros = pd->bexponent;	if (pd != &d)		_free_big_float(pd);#ifdef DEBUG	printf(" binary to decimal integer result %s * 10**%d \n", ds, *nzeros);#endif}voidbinary_to_decimal_fraction(pu, nsig, nfrac, ds, nzeros, ndigs)	unpacked       *pu;	/* Input unpacked fraction value output < 1				 * in magnitude. */	unsigned        nsig;	/* Input number of significant digits				 * required. */	unsigned        nfrac;	/* Input number of digits after point				 * required. */	char            ds[];	/* Output decimal integer string output -				 * must be large enough. */int            *nzeros;		/* Output number of implicit leading zeros				 * produced. */int            *ndigs;		/* Output number of explicit digits produced				 * in ds. *//* * Converts an unpacked fraction value *pu into a decimal string consisting * of a) an implicit '.' b) *nzeros implicit leading zeros c) *ndigs explicit * digits in ds ds contains at least nsig significant digits. nzeros + * * *ndigs is at least nfrac digits after the point. Inexactness is indicated * by sticking to the lsb. */{	_big_float     *pb, b, d;	int             e, i, j, is, excess;	char            s[4];	int             tensig, tenpower;	_BIG_FLOAT_DIGIT stickyshift;	*nzeros = 0;	if (pu->fpclass == fp_zero) {	/* Exact zero. */		for (i = 0; i <= nfrac; i++)			ds[i] = '0';		for (; i <= nsig; i++)			ds[i] = '0';		*ndigs = i;		return;	}	b.bsize = _BIG_FLOAT_SIZE;	/* Initialize sizes of big floats. */	d.bsize = _BIG_FLOAT_SIZE;	_unpacked_to_big_float(pu, &b, &e);	/*	 * e < 0 always	 */	b.bexponent = e;	tenpower = nsig + (int) (((17 - e - 16 * b.blength) * (unsigned long) 19729) >> 16);	if (tenpower < nfrac)		tenpower = nfrac;	tensig = nfrac;	if (nsig > tensig)		tensig = nsig;	tensig = 1 + (((tensig + 2) * 217706) >> 16);	tensig = -tensig;#ifdef DEBUG	printf(" binary to decimal fraction exponent 2**%d \n", e);	printf(" binary to decimal fraction nsig %d nfrac %d tenpower %d tensig %d \n", nsig, nfrac, tenpower, tensig);#endif	_big_float_times_power(&b, 10, tenpower, tensig, &pb);	switch (pb) {	case BIG_FLOAT_TIMES_TOOBIG:		{			char            bcastring[80];			(void) sprintf(bcastring, " decimal exponent %d ", tenpower);			_base_conversion_abort(ERANGE, bcastring);			break;		}	case BIG_FLOAT_TIMES_NOMEM:		{			char            bcastring[80];			(void) sprintf(bcastring, " decimal exponent %d ", tenpower);			_base_conversion_abort(ENOMEM, bcastring);			break;		}	default:#ifdef DEBUG		if (pb != &b)			printf(" large decimal exponent %d needs heap buffer \n", tenpower);		printf(" product ");		_display_big_float(pb, 2);#endif		break;	}	if (pb->bexponent <= -16) {		/* Have computed appropriate decimal part; now toss fraction. */		excess = (-pb->bexponent) / 16;#ifdef DEBUG		printf(" discard %d excess fraction bits \n", 16 * excess);#endif		for (i = 0; (i < excess) && (pb->bsignificand[i] == 0); i++);		if (i < excess)			pb->bsignificand[excess] |= 1;	/* Sticky bit for							 * discarded fraction. */		for (i = excess; i < pb->blength; i++)			pb->bsignificand[i - excess] = pb->bsignificand[i];		pb->blength -= excess;		pb->bexponent += 16 * excess;	}	if (pb->bexponent < 0) {		_right_shift_base_two(pb, (short unsigned) -pb->bexponent, &stickyshift);		if (stickyshift != 0)			pb->bsignificand[0] |= 1;	/* Stick to lsb. */	}	_big_binary_to_big_decimal(pb, &d);	i = d.blength - 1;	while (d.bsignificand[i] == 0)		i--;	_fourdigitsquick((short unsigned) d.bsignificand[i], s);	for (j = 0; s[j] == '0'; j++);	/* Find first non-zero digit. */	for (is = 0; j <= 3;)		ds[is++] = s[j++];	/* Copy subsequent digits. */	for (i--; i >= 0; i--) {/* Convert powers of 10**4 to decimal digits. */		_fourdigitsquick((short unsigned) d.bsignificand[i], &(ds[is]));		is += 4;	}	ds[is] = 0;	*ndigs = is;#ifdef DEBUG	assert(tenpower >= is);#endif	*nzeros = tenpower - is;/* There were supposed to be tenpower leading				 * digits, and is were found. */	if (pb != &b)		_free_big_float(pb);#ifdef DEBUG	printf(" binary to decimal fraction result .%s * 10**%d \n", ds, -(*nzeros));#endif}void_unpacked_to_decimal(px, pm, pd, ps)	unpacked       *px;	decimal_mode   *pm;	decimal_record *pd;	fp_exception_field_type *ps;{	unpacked        fx, ix;	unsigned        fmask, imask;	int             i, intdigs, fracdigs, fraczeros, fracsigs, ids, idsbound, lzbound;	unsigned        nsig, nfrac, intzeros, intsigs;	char            is[_INTEGER_SIZE], fs[DECIMAL_STRING_LENGTH];	char            round = '0';	unsigned        sticky = 0;	pd->sign = px->sign;	pd->fpclass = px->fpclass;	if ((px->fpclass != fp_normal) && (px->fpclass != fp_subnormal))		return;	if ((pm->ndigits >= DECIMAL_STRING_LENGTH) ||	    ((pm->df == floating_form) && (pm->ndigits < 1))) {	/* Gross overflow or bad								 * spec. */overflow:		*ps |= 1 << fp_overflow;		return;

⌨️ 快捷键说明

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