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

📄 prdtoa.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 4 页
字号:
				if ((s[0] == 'I' && bufsize < 9) || (s[0] == 'N' && bufsize < 4)) {					PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0);					return PR_FAILURE;				}				strcpy(buf, s);				if (rve) {					*rve =#ifdef IEEE_Arith						buf[3] ? buf + 8 :#endif					buf + 3;					PR_ASSERT(**rve == '\0');				}				return PR_SUCCESS;			}#endif#ifdef IBM	d += 0; /* normalize */#endif	if (!d) {		*decpt = 1;		if (bufsize < 2) {			PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0);			return PR_FAILURE;		}		buf[0] = '0'; buf[1] = '\0';  /* copy "0" to buffer */		if (rve) {			*rve = buf + 1;			PR_ASSERT(**rve == '\0');		}		return PR_SUCCESS;	}	b = d2b(d, &be, &bbits);#ifdef Sudden_Underflow	i = (PRInt32)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));#else	if ((i = (PRInt32)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) {#endif		d2 = d;		word0(d2) &= Frac_mask1;		word0(d2) |= Exp_11;#ifdef IBM		if (j = 11 - hi0bits(word0(d2) & Frac_mask))			d2 /= 1 << j;#endif		/* log(x)	~=~ log(1.5) + (x-1.5)/1.5		 * log10(x)	 =  log(x) / log(10)		 *		~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))		 * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)		 *		 * This suggests computing an approximation k to log10(d) by		 *		 * k = (i - Bias)*0.301029995663981		 *	+ ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );		 *		 * We want k to be too large rather than too small.		 * The error in the first-order Taylor series approximation		 * is in our favor, so we just round up the constant enough		 * to compensate for any error in the multiplication of		 * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,		 * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,		 * adding 1e-13 to the constant term more than suffices.		 * Hence we adjust the constant term to 0.1760912590558.		 * (We could get a more accurate k by invoking log10,		 *  but this is probably not worthwhile.)		 */		i -= Bias;#ifdef IBM		i <<= 2;		i += j;#endif#ifndef Sudden_Underflow		denorm = 0;	}	else {		/* d is denormalized */		i = bbits + be + (Bias + (P-1) - 1);		x = i > 32  ? word0(d) << (64 - i) | word1(d) >> (i - 32)			: word1(d) << (32 - i);		d2 = x;		word0(d2) -= 31*Exp_msk1; /* adjust exponent */		i -= (Bias + (P-1) - 1) + 1;		denorm = 1;	}#endif	ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;	k = (PRInt32)ds;	if (ds < 0. && ds != k)		k--;	/* want k = floor(ds) */	k_check = 1;	if (k >= 0 && k <= Ten_pmax) {		if (d < tens[k])			k--;		k_check = 0;	}	j = bbits - i - 1;	if (j >= 0) {		b2 = 0;		s2 = j;	}	else {		b2 = -j;		s2 = 0;	}	if (k >= 0) {		b5 = 0;		s5 = k;		s2 += k;	}	else {		b2 -= k;		b5 = -k;		s5 = 0;	}	if (mode < 0 || mode > 9)		mode = 0;	try_quick = 1;	if (mode > 5) {		mode -= 4;		try_quick = 0;	}	leftright = 1;	switch(mode) {	case 0:	case 1:		ilim = ilim1 = -1;		i = 18;		ndigits = 0;		break;	case 2:		leftright = 0;		/* no break */	case 4:		if (ndigits <= 0)			ndigits = 1;		ilim = ilim1 = i = ndigits;		break;	case 3:		leftright = 0;		/* no break */	case 5:		i = ndigits + k + 1;		ilim = i;		ilim1 = i - 1;		if (i <= 0)			i = 1;	}	j = sizeof(unsigned Long);	for(result_k = 0; sizeof(Bigint) - sizeof(unsigned Long) <= i - j;		j <<= 1) result_k++;	result = Balloc(result_k);	s = s0 = (char *)result;	if (ilim >= 0 && ilim <= Quick_max && try_quick) {		/* Try to get by with floating-point arithmetic. */		i = 0;		d2 = d;		k0 = k;		ilim0 = ilim;		ieps = 2; /* conservative */		if (k > 0) {			ds = tens[k&0xf];			j = k >> 4;			if (j & Bletch) {				/* prevent overflows */				j &= Bletch - 1;				d /= bigtens[n_bigtens-1];				ieps++;			}			for(; j; j >>= 1, i++)				if (j & 1) {					ieps++;					ds *= bigtens[i];				}			d /= ds;		}		else if ((j1 = -k) != 0) {			d *= tens[j1 & 0xf];			for(j = j1 >> 4; j; j >>= 1, i++)				if (j & 1) {					ieps++;					d *= bigtens[i];				}		}		if (k_check && d < 1. && ilim > 0) {			if (ilim1 <= 0)				goto fast_failed;			ilim = ilim1;			k--;			d *= 10.;			ieps++;		}		eps = ieps*d + 7.;		word0(eps) -= (P-1)*Exp_msk1;		if (ilim == 0) {			S = mhi = 0;			d -= 5.;			if (d > eps)				goto one_digit;			if (d < -eps)				goto no_digits;			goto fast_failed;		}#ifndef No_leftright		if (leftright) {			/* Use Steele & White method of only			 * generating digits needed.			 */			eps = 0.5/tens[ilim-1] - eps;			for(i = 0;;) {				L = (Long) d;				d -= L;				*s++ = '0' + (PRInt32)L;				if (d < eps)					goto ret1;				if (1. - d < eps)					goto bump_up;				if (++i >= ilim)					break;				eps *= 10.;				d *= 10.;			}		}		else {#endif			/* Generate ilim digits, then fix them up. */			eps *= tens[ilim-1];			for(i = 1;; i++, d *= 10.) {				L = (Long) d;				d -= L;				*s++ = '0' + (PRInt32)L;				if (i == ilim) {					if (d > 0.5 + eps)						goto bump_up;					else if (d < 0.5 - eps) {						while(*--s == '0'){} /* just count -- nothing to execute */						s++;						goto ret1;					}					break;				}			}#ifndef No_leftright		}#endif	fast_failed:		s = s0;		d = d2;		k = k0;		ilim = ilim0;	}	/* Do we have a "small" integer? */	if (be >= 0 && k <= Int_max) {		/* Yes. */		ds = tens[k];		if (ndigits < 0 && ilim <= 0) {			S = mhi = 0;			if (ilim < 0 || d <= 5*ds)				goto no_digits;			goto one_digit;		}		for(i = 1;; i++) {			L = (Long) (d / ds);			d -= L*ds;#ifdef Check_FLT_ROUNDS			/* If FLT_ROUNDS == 2, L will usually be high by 1 */			if (d < 0) {				L--;				d += ds;			}#endif			*s++ = '0' + (PRInt32)L;			if (i == ilim) {				d += d;				if ((d > ds) || (d == ds && L & 1)) {				bump_up:					while(*--s == '9')						if (s == s0) {							k++;							*s = '0';							break;						}					++*s++;				}				break;			}			if (!(d *= 10.))				break;		}		goto ret1;	}	m2 = b2;	m5 = b5;	mhi = mlo = 0;	if (leftright) {		if (mode < 2) {			i =#ifndef Sudden_Underflow				denorm ? be + (Bias + (P-1) - 1 + 1) :#endif#ifdef IBM				1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);#else			1 + P - bbits;#endif		}		else {			j = ilim - 1;			if (m5 >= j)				m5 -= j;			else {				s5 += j -= m5;				b5 += j;				m5 = 0;			}			if ((i = ilim) < 0) {				m2 -= i;				i = 0;			}		}		b2 += i;		s2 += i;		mhi = i2b(1);	}	if (m2 > 0 && s2 > 0) {		i = m2 < s2 ? m2 : s2;		b2 -= i;		m2 -= i;		s2 -= i;	}	if (b5 > 0) {		if (leftright) {			if (m5 > 0) {				mhi = pow5mult(mhi, m5);				b1 = mult(mhi, b);				Bfree(b);				b = b1;			}			if ((j = b5 - m5) != 0)				b = pow5mult(b, j);		}		else			b = pow5mult(b, b5);	}	S = i2b(1);	if (s5 > 0)		S = pow5mult(S, s5);	/* Check for special case that d is a normalized power of 2. */	if (mode < 2) {		if (!word1(d) && !(word0(d) & Bndry_mask)#ifndef Sudden_Underflow			&& word0(d) & Exp_mask#endif			) {			/* The special case */			b2 += Log2P;			s2 += Log2P;			spec_case = 1;		}		else			spec_case = 0;	}	/* Arrange for convenient computation of quotients:	 * shift left if necessary so divisor has 4 leading 0 bits.	 *	 * Perhaps we should just compute leading 28 bits of S once	 * and for all and pass them and a shift to quorem, so it	 * can do shifts and ors to compute the numerator for q.	 */#ifdef Pack_32	if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) != 0)		i = 32 - i;#else	if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf)		i = 16 - i;#endif	if (i > 4) {		i -= 4;		b2 += i;		m2 += i;		s2 += i;	}	else if (i < 4) {		i += 28;		b2 += i;		m2 += i;		s2 += i;	}	if (b2 > 0)		b = lshift(b, b2);	if (s2 > 0)		S = lshift(S, s2);	if (k_check) {		if (cmp(b,S) < 0) {			k--;			b = multadd(b, 10, 0);	/* we botched the k estimate */			if (leftright)				mhi = multadd(mhi, 10, 0);			ilim = ilim1;		}	}	if (ilim <= 0 && mode > 2) {		if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {			/* no digits, fcvt style */		no_digits:			k = -1 - ndigits;			goto ret;		}	one_digit:		*s++ = '1';		k++;		goto ret;	}	if (leftright) {		if (m2 > 0)			mhi = lshift(mhi, m2);		/* Compute mlo -- check for special case		 * that d is a normalized power of 2.		 */		mlo = mhi;		if (spec_case) {			mhi = Balloc(mhi->k);			Bcopy(mhi, mlo);			mhi = lshift(mhi, Log2P);		}		for(i = 1;;i++) {			dig = quorem(b,S) + '0';			/* Do we yet have the shortest decimal string			 * that will round to d?			 */			j = cmp(b, mlo);			delta = diff(S, mhi);			j1 = delta->sign ? 1 : cmp(b, delta);			Bfree(delta);#ifndef ROUND_BIASED			if (j1 == 0 && !mode && !(word1(d) & 1)) {				if (dig == '9')					goto round_9_up;				if (j > 0)					dig++;				*s++ = dig;				goto ret;			}#endif			if ((j < 0) || ((j == 0) && (!mode)#ifndef ROUND_BIASED				&& (!(word1(d) & 1)))#endif				) {				if (j1 > 0) {					b = lshift(b, 1);					j1 = cmp(b, S);					if (((j1 > 0) || (j1 == 0 && dig & 1))						&& (dig++ == '9'))						goto round_9_up;				}				*s++ = dig;				goto ret;			}			if (j1 > 0) {				if (dig == '9') { /* possible if i == 1 */				round_9_up:					*s++ = '9';					goto roundoff;				}				*s++ = dig + 1;				goto ret;			}			*s++ = dig;			if (i == ilim)				break;			b = multadd(b, 10, 0);			if (mlo == mhi)				mlo = mhi = multadd(mhi, 10, 0);			else {				mlo = multadd(mlo, 10, 0);				mhi = multadd(mhi, 10, 0);			}		}	}	else		for(i = 1;; i++) {			*s++ = dig = quorem(b,S) + '0';			if (i >= ilim)				break;			b = multadd(b, 10, 0);		}	/* Round off last digit */	b = lshift(b, 1);	j = cmp(b, S);	if ((j > 0) || (j == 0 && dig & 1)) {	roundoff:		while(*--s == '9')			if (s == s0) {				k++;				*s++ = '1';				goto ret;			}		++*s++;	}	else {		while(*--s == '0'){} /* just count -- nothing to execute */		s++;	}ret:	Bfree(S);	if (mhi) {		if (mlo && mlo != mhi)			Bfree(mlo);		Bfree(mhi);	}ret1:	Bfree(b);	*s = 0;	*decpt = k + 1;	strsize = (s - s0) + 1;	if (strsize <= bufsize) {		retval = PR_SUCCESS;		memcpy(buf, s0, strsize);		if (rve) {			*rve = buf + strsize - 1;			PR_ASSERT(**rve == '\0');		}	} else {		PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0);		retval = PR_FAILURE;	}	/* cleanup */	result->k = result_k;	result->maxwds = 1 << result_k;	Bfree(result);	return retval;}/*** conversion routines for floating point** prcsn - number of digits of precision to generate floating** point value.** This should be reparameterized so that you can send in a**   prcn for the positive and negative ranges.  For now, **   conform to the ECMA JavaScript spec which says numbers**   less than 1e-6 are in scientific notation.** Also, the ECMA spec says that there should always be a**   '+' or '-' after the 'e' in scientific notation*/PR_IMPLEMENT(void)PR_cnvtf(char *buf,int bufsz, int prcsn,double fval){    PRIntn decpt, sign, numdigits;    char *num, *nump;    char *bufp = buf;    char *endnum;	/* If anything fails, we store an empty string in 'buf' */	num = (char*)PR_MALLOC(bufsz);	if (num == NULL) {		buf[0] = '\0';		return;	}	/* XXX Why use mode 1? */	if (PR_dtoa(fval,1,prcsn,&decpt,&sign,&endnum,num,bufsz)			== PR_FAILURE) {		buf[0] = '\0';		goto done;	}	numdigits = endnum - num;	nump = num;	if (sign &&	    !(word0(fval) == Sign_bit && word1(fval) == 0) &&	    !((word0(fval) & Exp_mask) == Exp_mask &&	      (word1(fval) || (word0(fval) & 0xfffff)))) {	    *bufp++ = '-';	}		if(decpt == 9999){		while((*bufp++ = *nump++) != 0){} /* nothing to execute */		goto done;	}	if(decpt > (prcsn+1) || decpt < -(prcsn-1) || decpt < -5){	    *bufp++ = *nump++;	    if(numdigits != 1){			*bufp++ = '.';	    }			    while(*nump != '\0'){			*bufp++ = *nump++;	    }	    *bufp++ = 'e';	    PR_snprintf(bufp,bufsz - (bufp - buf), "%+d",decpt-1);	}	else if(decpt >= 0){	    if(decpt == 0){			*bufp++ = '0';	    }	    else {		while(decpt--){			if(*nump != '\0'){				*bufp++ = *nump++;			}			else {				*bufp++ = '0';			}		}	    }	    if(*nump != '\0'){			*bufp++ = '.';			while(*nump != '\0'){				*bufp++ = *nump++;			}	    }	    *bufp++ = '\0';	}	else if(decpt < 0){	    *bufp++ = '0';	    *bufp++ = '.';	    while(decpt++){			*bufp++ = '0';	    }	    	    while(*nump != '\0'){			*bufp++ = *nump++;	    }	    *bufp++ = '\0';	}done:	PR_DELETE(num);}

⌨️ 快捷键说明

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