static uint8_t *ccder_encode_nanoseconds(CFAbsoluteTime at, const uint8_t *der,
                                         uint8_t *der_end) {
    int dotoff;
    int sign;
    char *end;
    char *str = __dtoa(at, 0, 0, &dotoff, &sign, &end);
    char *begin = str + (dotoff < 0 ? 0 : dotoff);
    // Compute 1.0000000 - fraction in ascii space
    if (at < 0.0 && begin < end) {
        char *p = end - 1;
        // Borrow for last digit
        *p = ('9' + 1) - (*p - '0');
        while (p-- > begin) {
            // Every other digit is a 9 since we borrowed from the last one
            *p = '9' - (*p - '0');
        }
    }

    ptrdiff_t len = end - str;
    if (len > dotoff) {
        if (dotoff < 0) {
            assert(-1.0 < at && at < 1.0);
            der_end = ccder_encode_body(len, (const uint8_t *)str, der, der_end);
            der_end = ccder_encode_body_nocopy(-dotoff, der, der_end);
            if (der_end)
                memset(der_end, at < 0.0 ? '9' : '0', -dotoff);
        } else {
            der_end = ccder_encode_body(len - dotoff, (const uint8_t *)(str + dotoff), der, der_end);
        }
        der_end = ccder_encode_byte('.', der, der_end);
    }
    __freedtoa(str);

    return der_end;
}
static size_t ccder_sizeof_nanoseconds(CFAbsoluteTime at) {
    int dotoff;
    int sign;
    char *end;
    char *str = __dtoa(at, 0, 0, &dotoff, &sign, &end);
    ptrdiff_t len = end - str;
    __freedtoa(str);
    return len < dotoff ? 0 : len - dotoff;
    //return len < dotoff ? 0 : len - dotoff > 9 ? 9 : len - dotoff;
}
Beispiel #3
0
int main(int argc, char **argv)
{
    double cst = M_PI;
    if (argc > 1)
        cst = strtod(argv[1], 0);

    printf("%g\n", cst);
    printf("%.0g\n", cst);
    printf("%.1g\n", cst);
    printf("%.2g\n", cst);

#if 0
#ifdef __mt_freestanding__
    int expt, signflag;
    char *dtoaend;
    char *s;
    s = __dtoa(cst, 0, 6 /*prec*/, &expt, &signflag, &dtoaend);
    fprintf(stderr, "dtoa 0: '%s', exp %d, sign %d len %d\n", s, expt, signflag, dtoaend - s);
    s = __dtoa(cst, 1, 6 /*prec*/, &expt, &signflag, &dtoaend);
    fprintf(stderr, "dtoa 1: '%s', exp %d, sign %d len %d\n", s, expt, signflag, dtoaend - s);
    s = __dtoa(cst, 2, 6 /*prec*/, &expt, &signflag, &dtoaend);
    fprintf(stderr, "dtoa 2: '%s', exp %d, sign %d len %d\n", s, expt, signflag, dtoaend - s);
    s = __dtoa(cst, 3, 6 /*prec*/, &expt, &signflag, &dtoaend);
    fprintf(stderr, "dtoa 3: '%s', exp %d, sign %d len %d\n", s, expt, signflag, dtoaend - s);
    s = __dtoa(cst, 4, 6 /*prec*/, &expt, &signflag, &dtoaend);
    fprintf(stderr, "dtoa 4: '%s', exp %d, sign %d len %d\n", s, expt, signflag, dtoaend - s);
    s = __dtoa(cst, 5, 6 /*prec*/, &expt, &signflag, &dtoaend);
    fprintf(stderr, "dtoa 5: '%s', exp %d, sign %d len %d\n", s, expt, signflag, dtoaend - s);
    s = __dtoa(cst, 6, 6 /*prec*/, &expt, &signflag, &dtoaend);
    fprintf(stderr, "dtoa 6: '%s', exp %d, sign %d len %d\n", s, expt, signflag, dtoaend - s);
    s = __dtoa(cst, 7, 6 /*prec*/, &expt, &signflag, &dtoaend);
    fprintf(stderr, "dtoa 7: '%s', exp %d, sign %d len %d\n", s, expt, signflag, dtoaend - s);
    s = __dtoa(cst, 8, 6 /*prec*/, &expt, &signflag, &dtoaend);
    fprintf(stderr, "dtoa 8: '%s', exp %d, sign %d len %d\n", s, expt, signflag, dtoaend - s);
    s = __dtoa(cst, 9, 6 /*prec*/, &expt, &signflag, &dtoaend);
    fprintf(stderr, "dtoa 9: '%s', exp %d, sign %d len %d\n", s, expt, signflag, dtoaend - s);
#endif
#endif

    return 0;
}
Beispiel #4
0
char *
fcvt_mp (double arg, int ndigits, int *decpt, int *sign, char *buffer)
{
    *decpt = __dtoa (buffer, ndigits, arg, 1, _ROUNDUP_RM) + 1;
    if (*decpt + ndigits <= 0 && buffer[1] >= '5' && buffer[1] <= '9') {
	/* need to round up the digit beyond 'ndigits' */
	buffer[1] = '1';
	buffer[2] = '0';
	buffer[3] = '\0';
	(*decpt)++;
    }
    *sign = buffer[0] == '-';
    return buffer+1;
}
Beispiel #5
0
char *
ecvt_mp (double arg, int ndigits, int *decpt, int *sign, char *buffer)
{
    /*
    extern FILE *debugfile;
    */
    if (ndigits > 17) {
	register char *p, *e;
	*decpt = __dtoa (buffer, 17, arg, 0, _ROUNDUP_RM) + 1;
        for (p = buffer+18, e = buffer + 1 + (ndigits > NDIG ? NDIG : ndigits);
             p != e; ) *p++ = '0';
        *p++ = '\0';
    }
    else if (ndigits <= 0) {
	*decpt = __dtoa (buffer, 1, arg, 0, _ROUNDUP_RM) + 1;
	buffer[1] = '\0';
    }
    else {
	*decpt = __dtoa (buffer, ndigits, arg, 0, _ROUNDUP_RM) + 1;
    }
    *sign = buffer[0] == '-';
    return buffer+1;
}
Beispiel #6
0
static char *
__cvt(double value, int ndigit, int *decpt, int *sign, int fmode, int pad)
{
	static char *s;
	char *p, *rve, c;
	size_t siz;

	if (ndigit == 0) {
		*sign = value < 0.0;
		*decpt = 0;
		return ("");
	}

	if (s) {
		free(s);
		s = NULL;
	}

	if (ndigit < 0)
		siz = -ndigit + 1;
	else
		siz = ndigit + 1;


	/* __dtoa() doesn't allocate space for 0 so we do it by hand */
	if (value == 0.0) {
		*decpt = 1 - fmode;	/* 1 for 'e', 0 for 'f' */
		*sign = 0;
		if ((rve = s = (char *)malloc(siz)) == NULL)
			return(NULL);
		*rve++ = '0';
		*rve = '\0';
	} else {
		p = __dtoa(value, fmode + 2, ndigit, decpt, sign, &rve);
		if (*decpt == 9999) {
			/* Infinity or Nan, convert to inf or nan like printf */
			*decpt = 0;
			c = *p;
			__freedtoa(p);
			return(c == 'I' ? "inf" : "nan");
		}
		/* Make a local copy and adjust rve to be in terms of s */
		if (pad && fmode)
			siz += *decpt;
		if ((s = (char *)malloc(siz)) == NULL) {
			__freedtoa(p);
			return(NULL);
		}
		(void) strlcpy(s, p, siz);
		rve = s + (rve - p);
		__freedtoa(p);
	}

	/* Add trailing zeros */
	if (pad) {
		siz -= rve - s;
		while (--siz)
			*rve++ = '0';
		*rve = '\0';
	}

	return(s);
}
static void lib_dtoa(FAR struct lib_outstream_s *obj, int fmt, int prec,
                     uint8_t flags, double value)
{
  FAR char *digits;     /* String returned by __dtoa */
  FAR char *digalloc;   /* Copy of digits to be freed after usage */
  FAR char *rve;        /* Points to the end of the return value */
  int  expt;            /* Integer value of exponent */
  int  numlen;          /* Actual number of digits returned by cvt */
  int  nchars;          /* Number of characters to print */
  int  dsgn;            /* Unused sign indicator */
  int  i;

  /* Special handling for NaN and Infinity */

  if (isnan(value))
    {
      lib_dtoa_string(obj, "NaN");
      return;
    }

  if (isinf(value))
    {
      if (value < 0.0)
        {
          obj->put(obj, '-');
        }

      lib_dtoa_string(obj, "Infinity");
      return;
    }

  /* Non-zero... positive or negative */

  if (value < 0)
    {
      value = -value;
      SET_NEGATE(flags);
    }

  /* Perform the conversion */

  digits   = __dtoa(value, 3, prec, &expt, &dsgn, &rve);
  digalloc = digits;
  numlen   = rve - digits;

  if (IS_NEGATE(flags))
    {
      obj->put(obj, '-');
    }
  else if (IS_SHOWPLUS(flags))
    {
      obj->put(obj, '+');
    }

  /* Special case exact zero or the case where the number is smaller than
   * the print precision.
   */

  if (value == 0 || expt < -prec)
    {
      /* kludge for __dtoa irregularity */

      obj->put(obj, '0');

      /* A decimal point is printed only in the alternate form or if a
       * particular precision is requested.
       */

      if (prec > 0 || IS_ALTFORM(flags))
        {
          obj->put(obj, '.');

          /* Always print at least one digit to the right of the decimal point. */

          prec = MAX(1, prec);
        }
    }

  /* A non-zero value will be printed */

  else
    {

      /* Handle the case where the value is less than 1.0 (in magnitude) and
       * will need a leading zero.
       */

      if (expt <= 0)
        {
          /* Print a single zero to the left of the decimal point */

          obj->put(obj, '0');

          /* Print the decimal point */

          obj->put(obj, '.');

          /* Print any leading zeros to the right of the decimal point */

          if (expt < 0)
            {
              nchars = MIN(-expt, prec);
              zeroes(obj, nchars);
              prec -= nchars;
            }
        }

      /* Handle the general case where the value is greater than 1.0 (in
       * magnitude).
       */

      else
        {
          /* Print the integer part to the left of the decimal point */

          for (i = expt; i > 0; i--)
            {
              if (*digits != '\0')
                {
                  obj->put(obj, *digits);
                  digits++;
                }
              else
                {
                  obj->put(obj, '0');
                }
            }

          /* Get the length of the fractional part */

          numlen -= expt;

          /* If there is no fractional part, then a decimal point is printed
           * only in the alternate form or if a particular precision is
           * requested.
           */

          if (numlen > 0 || prec > 0 || IS_ALTFORM(flags))
            {
              /* Print the decimal point */

              obj->put(obj, '.');

              /* Always print at least one digit to the right of the decimal
               * point.
               */

              prec = MAX(1, prec);
            }
        }

      /* If a precision was specified, then limit the number digits to the
       * right of the decimal point.
       */

      if (prec > 0)
        {
          nchars = MIN(numlen, prec);
        }
      else
        {
          nchars = numlen;
        }

      /* Print the fractional part to the right of the decimal point */

      for (i = nchars; i > 0; i--)
        {
          obj->put(obj, *digits);
          digits++;
        }

      /* Decremnt to get the number of trailing zeroes to print */

      prec -= nchars;
    }

  /* Finally, print any trailing zeroes */

  zeroes(obj, prec);

  /* Is this memory supposed to be freed or not? */

#if 0
  if (digalloc)
    {
      lib_free(digalloc);
    }
#endif
}
Beispiel #8
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
}
Beispiel #9
0
char *
gcvt(double value, int ndigit, char *buf)
{
	char *digits, *dst, *src;
	int i, decpt, sign;
	struct lconv *lconv;

	lconv = localeconv();
	if (ndigit == 0) {
		buf[0] = '\0';
		return (buf);
	}

	digits = __dtoa(value, 2, ndigit, &decpt, &sign, NULL);
	if (decpt == 9999) {
		/*
		 * Infinity or NaN, convert to inf or nan with sign.
		 * We assume the buffer is at least ndigit long.
		 */
		snprintf(buf, ndigit + 1, "%s%s", sign ? "-" : "",
		    *digits == 'I' ? "inf" : "nan");
		__freedtoa(digits);
		return (buf);
	}

	dst = buf;
	if (sign)
		*dst++ = '-';

	if (decpt < 0 || decpt > ndigit) {
		/* exponential format (e.g. 1.2345e+13) */
		if (--decpt < 0) {
			sign = 1;
			decpt = -decpt;
		} else
			sign = 0;
		src = digits;
		*dst++ = *src++;
		*dst++ = *lconv->decimal_point;
		while (*src != '\0')
			*dst++ = *src++;
		*dst++ = 'e';
		if (sign)
			*dst++ = '-';
		else
			*dst++ = '+';
		if (decpt < 10) {
			*dst++ = '0';
			*dst++ = '0' + decpt;
			*dst = '\0';
		} else {
			/* XXX - optimize */
			for (sign = decpt, i = 0; (sign /= 10) != 0; i++)
				continue;
			dst[i + 1] = '\0';
			while (decpt != 0) {
				dst[i--] = '0' + decpt % 10;
				decpt /= 10;
			}
		}
	} else {
		/* standard format */
		for (i = 0, src = digits; i < decpt; i++) {
			if (*src != '\0')
				*dst++ = *src++;
			else
				*dst++ = '0';
		}
		if (*src != '\0') {
			if (src == digits)
				*dst++ = '0';	/* zero before decimal point */
			*dst++ = *lconv->decimal_point;
			for (i = decpt; digits[i] != '\0'; i++) {
				*dst++ = digits[i];
			}
		}
		*dst = '\0';
	}
	__freedtoa(digits);
	return (buf);
}
Beispiel #10
0
static char* cvt(double value, int ndigits, int flags, char *sign,
                 int *decpt, int ch, int *length)
{
  int mode, dsgn;
  char *digits, *bp, *rve;

  if (ch == 'f')
    {
      mode = 3;               /* ndigits after the decimal point */
    }
  else
    {
      /* To obtain ndigits after the decimal point for the 'e' and 'E'
       * formats, round to ndigits + 1 significant figures.
       */

      if (ch == 'e' || ch == 'E')
        {
          ndigits++;
        }
      mode = 2;               /* ndigits significant digits */
    }

  if (value < 0)
    {
      value = -value;
      *sign = '-';
    }
  else
    {
      *sign = '\000';
    }

  digits = __dtoa(value, mode, ndigits, decpt, &dsgn, &rve);
  if ((ch != 'g' && ch != 'G') || IS_ALTFORM(flags))
    {
      /* Print trailing zeros */

      bp = digits + ndigits;
      if (ch == 'f')
        {
          if (*digits == '0' && value)
            {
              *decpt = -ndigits + 1;
            }
          bp += *decpt;
        }

      if (value == 0)
        {
	  /* kludge for __dtoa irregularity */

          rve = bp;
        }

      while (rve < bp)
        {
          *rve++ = '0';
        }
    }

  *length = rve - digits;
  return digits;
}
Beispiel #11
0
				prec = DEFPREC;
			if (dtoaresult)
				__freedtoa(dtoaresult);
			if (flags & LONGDBL) {
				fparg.ldbl = GETARG(long double);
				dtoaresult = cp =
				    __ldtoa(&fparg.ldbl, expchar ? 2 : 3, prec,
				    &expt, &signflag, &dtoaend);
				if (dtoaresult == NULL) {
					/*errno = ENOMEM*/;
					goto error;
				}
			} else {
				fparg.dbl = GETARG(double);
				dtoaresult = cp =
				    __dtoa(fparg.dbl, expchar ? 2 : 3, prec,
				    &expt, &signflag, &dtoaend);
				if (dtoaresult == NULL) {
					/*errno = ENOMEM*/;
					goto error;
				}
				if (expt == 9999)
					expt = INT_MAX;
 			}
fp_common:
			if (signflag)
				sign = '-';
			if (expt == INT_MAX) {	/* inf or nan */
				if (*cp == 'N') {
					cp = (ch >= 'a') ? "nan" : "NAN";
					sign = '\0';
				} else