Beispiel #1
0
/*

   __ldtoa: wrapper for long double conversion using gdtoa()
  
   NOTE: This only works for IEEE extended precision long doubles.
  
   Input:
     ld       - a pointer to the value to convert

     The rest of the parameters are the analogous to the corresponding
     parameters to gdtoa().
  
   Returns:
     This function returns a string that is to be free'd with freedtoa().

*/
char *
__ldtoa(long double *ld,
        int mode,
        int ndigits,
        int *decpt,
        int *sign,
        char **rve)
{
  FPI fpi =
  {
    64,                 /* nbits */
    1 - 16383 - 63,     /* emin  */
    32766 - 16383 - 63, /* emax  */
    1,                  /* rounding */
    0                   /* sudden_underflow */
  };
  union ieee_ext *l;
  uint32_t bits[2];
  int exp, kind;
  char *ret;

  l = (union ieee_ext *) ld;
  *sign = l->ieee.sgn;
  exp = l->ieee.exp;
  bits[0] = l->ieee.mt0;
  bits[1] = l->ieee.mt1;

  if (isnan(*ld))        /* NaN                */
      kind = STRTOG_NaN;
  else if (isinf(*ld))   /* Infinity           */
      kind = STRTOG_Infinite;
  else if (exp == 0)     /* Denormalized       */
  {
    kind = STRTOG_Denormal;
    exp = 1;
  }
  else                   /* Normalized or zero */
  {
    if (bits[0] | bits[1])
      kind = STRTOG_Normal;
    else
      kind = STRTOG_Zero;
  }

  exp -= 16383 + 63;

  ret = gdtoa(&fpi, exp, &bits[0], &kind, mode, ndigits, decpt, rve);

  if (*decpt == -32768)
    *decpt = INT_MAX;

  return ret;
}
Beispiel #2
0
g_xfmt(char *buf, void *V, int ndig, size_t bufsize)
#endif
{
	static FPI fpi0 = { 64, 1-16383-64+1, 32766 - 16383 - 64 + 1, 1, 0 };
	char *b, *s, *se;
	ULong bits[2], sign;
	UShort *L;
	int decpt, ex, i, mode;
#ifdef Honor_FLT_ROUNDS
#include "gdtoa_fltrnds.h"
#else
#define fpi &fpi0
#endif

	if (ndig < 0)
		ndig = 0;
	if (bufsize < ndig + 10)
		return 0;

	L = (UShort *)V;
	sign = L[_0] & 0x8000;
	bits[1] = (L[_1] << 16) | L[_2];
	bits[0] = (L[_3] << 16) | L[_4];
	if ( (ex = L[_0] & 0x7fff) !=0) {
		if (ex == 0x7fff) {
			/* Infinity or NaN */
			if (bits[0] | bits[1])
				b = strcp(buf, "NaN");
			else {
				b = buf;
				if (sign)
					*b++ = '-';
				b = strcp(b, "Infinity");
				}
			return b;
			}
		i = STRTOG_Normal;
		}
	else if (bits[0] | bits[1]) {
		i = STRTOG_Denormal;
		ex = 1;
		}
	else {
		b = buf;
#ifndef IGNORE_ZERO_SIGN
		if (sign)
			*b++ = '-';
#endif
		*b++ = '0';
		*b = 0;
		return b;
		}
	ex -= 0x3fff + 63;
	mode = 2;
	if (ndig <= 0) {
		if (bufsize < 32)
			return 0;
		mode = 0;
		}
	s = gdtoa(fpi, ex, bits, &i, mode, ndig, &decpt, &se);
	return g__fmt(buf, s, se, decpt, sign, bufsize);
	}
Beispiel #3
0
/*
 * ldtoa() is a wrapper for gdtoa() that makes it smell like dtoa(),
 * except that the floating point argument is passed by reference.
 * When dtoa() is passed a NaN or infinity, it sets expt to 9999.
 * However, a long double could have a valid exponent of 9999, so we
 * use INT_MAX in ldtoa() instead.
 */
char *
__ldtoa(long double *ld, int mode, int ndigits, int *decpt, int *sign,
    char **rve)
{
	FPI fpi = {
		LDBL_MANT_DIG,			/* nbits */
		LDBL_MIN_EXP - LDBL_MANT_DIG,	/* emin */
		LDBL_MAX_EXP - LDBL_MANT_DIG,	/* emax */
		FLT_ROUNDS,	       		/* rounding */
#ifdef Sudden_Underflow	/* unused, but correct anyway */
		1
#else
		0
#endif
	};
	int be, kind;
	char *ret;
	struct ieee_ext *p = (struct ieee_ext *)ld;
	uint32_t bits[(LDBL_MANT_DIG + 31) / 32];
	void *vbits = bits;

	/*
	 * gdtoa doesn't know anything about the sign of the number, so
	 * if the number is negative, we need to swap rounding modes of
	 * 2 (upwards) and 3 (downwards).
	 */
	*sign = p->ext_sign;
	fpi.rounding ^= (fpi.rounding >> 1) & p->ext_sign;

	be = p->ext_exp - (LDBL_MAX_EXP - 1) - (LDBL_MANT_DIG - 1);
	EXT_TO_ARRAY32(p, bits);

	switch (fpclassify(*ld)) {
	case FP_NORMAL:
		kind = STRTOG_Normal;
#ifdef EXT_IMPLICIT_NBIT
		bits[LDBL_MANT_DIG / 32] |= 1 << ((LDBL_MANT_DIG - 1) % 32);
#endif /* EXT_IMPLICIT_NBIT */
		break;
	case FP_ZERO:
		kind = STRTOG_Zero;
		break;
	case FP_SUBNORMAL:
		kind = STRTOG_Denormal;
		be++;
		break;
	case FP_INFINITE:
		kind = STRTOG_Infinite;
		break;
	case FP_NAN:
		kind = STRTOG_NaN;
		break;
	default:
		abort();
	}

	ret = gdtoa(&fpi, be, vbits, &kind, mode, ndigits, decpt, rve);
	if (*decpt == -32768)
		*decpt = INT_MAX;
	return ret;
}
Beispiel #4
0
g_ddfmt(char *buf, double *dd0, int ndig, size_t bufsize)
#endif
{
	FPI fpi;
	char *b, *s, *se;
	ULong *L, bits0[4], *bits, *zx;
	int bx, by, decpt, ex, ey, i, j, mode;
	Bigint *x, *y, *z;
	U *dd, ddx[2];
#ifdef Honor_FLT_ROUNDS /*{{*/
	int Rounding;
#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */
	Rounding = Flt_Rounds;
#else /*}{*/
	Rounding = 1;
	switch(fegetround()) {
	  case FE_TOWARDZERO:	Rounding = 0; break;
	  case FE_UPWARD:	Rounding = 2; break;
	  case FE_DOWNWARD:	Rounding = 3;
	  }
#endif /*}}*/
#else /*}{*/
#define Rounding FPI_Round_near
#endif /*}}*/

	if (bufsize < 10 || bufsize < ndig + 8)
		return 0;

	dd = (U*)dd0;
	L = dd->L;
	if ((L[_0] & 0x7ff00000L) == 0x7ff00000L) {
		/* Infinity or NaN */
		if (L[_0] & 0xfffff || L[_1]) {
 nanret:
			return strcp(buf, "NaN");
			}
		if ((L[2+_0] & 0x7ff00000) == 0x7ff00000) {
			if (L[2+_0] & 0xfffff || L[2+_1])
				goto nanret;
			if ((L[_0] ^ L[2+_0]) & 0x80000000L)
				goto nanret;	/* Infinity - Infinity */
			}
 infret:
		b = buf;
		if (L[_0] & 0x80000000L)
			*b++ = '-';
		return strcp(b, "Infinity");
		}
	if ((L[2+_0] & 0x7ff00000) == 0x7ff00000) {
		L += 2;
		if (L[_0] & 0xfffff || L[_1])
			goto nanret;
		goto infret;
		}
	if (dval(&dd[0]) + dval(&dd[1]) == 0.) {
		b = buf;
#ifndef IGNORE_ZERO_SIGN
		if (L[_0] & L[2+_0] & 0x80000000L)
			*b++ = '-';
#endif
		*b++ = '0';
		*b = 0;
		return b;
		}
	if ((L[_0] & 0x7ff00000L) < (L[2+_0] & 0x7ff00000L)) {
		dval(&ddx[1]) = dval(&dd[0]);
		dval(&ddx[0]) = dval(&dd[1]);
		dd = ddx;
		L = dd->L;
		}
	z = d2b(dval(&dd[0]), &ex, &bx);
	if (dval(&dd[1]) == 0.)
		goto no_y;
	x = z;
	y = d2b(dval(&dd[1]), &ey, &by);
	if ( (i = ex - ey) !=0) {
		if (i > 0) {
			x = lshift(x, i);
			ex = ey;
			}
		else
			y = lshift(y, -i);
		}
	if ((L[_0] ^ L[2+_0]) & 0x80000000L) {
		z = diff(x, y);
		if (L[_0] & 0x80000000L)
			z->sign = 1 - z->sign;
		}
	else {
		z = sum(x, y);
		if (L[_0] & 0x80000000L)
			z->sign = 1;
		}
	Bfree(x);
	Bfree(y);
 no_y:
	bits = zx = z->x;
	for(i = 0; !*zx; zx++)
		i += 32;
	i += lo0bits(zx);
	if (i) {
		rshift(z, i);
		ex += i;
		}
	fpi.nbits = z->wds * 32 - hi0bits(z->x[j = z->wds-1]);
	if (fpi.nbits < 106) {
		fpi.nbits = 106;
		if (j < 3) {
			for(i = 0; i <= j; i++)
				bits0[i] = bits[i];
			while(i < 4)
				bits0[i++] = 0;
			bits = bits0;
			}
		}
	mode = 2;
	if (ndig <= 0) {
		if (bufsize < (int)(fpi.nbits * .301029995664) + 10) {
			Bfree(z);
			return 0;
			}
		mode = 0;
		}
	fpi.emin = 1-1023-53+1;
	fpi.emax = 2046-1023-106+1;
	fpi.rounding = Rounding;
	fpi.sudden_underflow = 0;
	i = STRTOG_Normal;
	s = gdtoa(&fpi, ex, bits, &i, mode, ndig, &decpt, &se);
	b = g__fmt(buf, s, se, decpt, z->sign, bufsize);
	Bfree(z);
	return b;
	}
Beispiel #5
0
/*
 * ldtoa() is a wrapper for gdtoa() that makes it smell like dtoa(),
 * except that the floating point argument is passed by reference.
 * When dtoa() is passed a NaN or infinity, it sets expt to 9999.
 * However, a long double could have a valid exponent of 9999, so we
 * use INT_MAX in ldtoa() instead.
 */
char *
__ldtoa(long double *ld, int mode, int ndigits, int *decpt, int *sign,
    char **rve)
{
#if defined(__arm__) 
	/* On arm, double == long double, so short circuit this */
	char * ret = __dtoa((double)*ld, mode, ndigits, decpt, sign, rve);
	if (*decpt == 9999)
		*decpt = INT_MAX;
	return ret;
#else
	FPI fpi = {
		LDBL_MANT_DIG,			/* nbits */
		LDBL_MIN_EXP - LDBL_MANT_DIG,	/* emin */
		LDBL_MAX_EXP - LDBL_MANT_DIG,	/* emax */
		FLT_ROUNDS,	       		/* rounding */
#ifdef Sudden_Underflow	/* unused, but correct anyway */
		1
#else
		0
#endif
	};
	int be, kind;
	char *ret;
	union IEEEl2bits u;
	uint32_t bits[(LDBL_MANT_DIG + 31) / 32];
	void *vbits = bits;
	int type;

	u.e = *ld;
	type = fpclassify(u.e);

	/*
	 * gdtoa doesn't know anything about the sign of the number, so
	 * if the number is negative, we need to swap rounding modes of
	 * 2 (upwards) and 3 (downwards).
	 */
	*sign = u.bits.sign;
	fpi.rounding ^= (fpi.rounding >> 1) & u.bits.sign;

	be = u.bits.exp - (LDBL_MAX_EXP - 1) - (LDBL_MANT_DIG - 1);
	LDBL_TO_ARRAY32(u, bits);

	switch (type) {
	case FP_NORMAL:
	case FP_SUPERNORMAL:
		kind = STRTOG_Normal;
#ifdef	LDBL_IMPLICIT_NBIT
		bits[LDBL_MANT_DIG / 32] |= 1 << ((LDBL_MANT_DIG - 1) % 32);
#endif /* LDBL_IMPLICIT_NBIT */
		break;
	case FP_ZERO:
		kind = STRTOG_Zero;
		break;
	case FP_SUBNORMAL:
		kind = STRTOG_Denormal;
		be++;
		break;
	case FP_INFINITE:
		kind = STRTOG_Infinite;
		break;
	case FP_NAN:
		kind = STRTOG_NaN;
		break;
	default:
		LIBC_ABORT("fpclassify returned %d", type);
	}

	ret = gdtoa(&fpi, be, vbits, &kind, mode, ndigits, decpt, rve);
	if (*decpt == -32768)
		*decpt = INT_MAX;
	return ret;
#endif
}