Пример #1
0
inline static void appenddouble(StringBuffer *buffer,
                                double number,
                                int width, char padding,
                                int alignment, int precision,
                                int adjust, char fmt,
                                int always_sign) {
  char num_buf[NUM_BUF_SIZE];
  char *s = nullptr;
  int s_len = 0, is_negative = 0;

  if ((adjust & ADJ_PRECISION) == 0) {
    precision = FLOAT_PRECISION;
  } else if (precision > MAX_FLOAT_PRECISION) {
    precision = MAX_FLOAT_PRECISION;
  }

  if (isnan(number)) {
    is_negative = (number<0);
    appendstring(buffer, "NaN", 3, 0, padding,
                 alignment, 3, is_negative, 0, always_sign);
    return;
  }

  if (isinf(number)) {
    is_negative = (number<0);
    appendstring(buffer, "INF", 3, 0, padding,
                 alignment, 3, is_negative, 0, always_sign);
    return;
  }

  switch (fmt) {
  case 'e':
  case 'E':
  case 'f':
  case 'F':
    s = php_conv_fp((fmt == 'f')?'F':fmt, number, 0, precision, '.',
                    &is_negative, &num_buf[1], &s_len);
    if (is_negative) {
      num_buf[0] = '-';
      s = num_buf;
      s_len++;
    } else if (always_sign) {
      num_buf[0] = '+';
      s = num_buf;
      s_len++;
    }
    break;

  case 'g':
  case 'G':
    if (precision == 0)
      precision = 1;
    /*
     * * We use &num_buf[ 1 ], so that we have room for the sign
     */
    s = php_gcvt(number, precision, '.', (fmt == 'G')?'E':'e', &num_buf[1]);
    is_negative = 0;
    if (*s == '-') {
      is_negative = 1;
      s = &num_buf[1];
    } else if (always_sign) {
      num_buf[0] = '+';
      s = num_buf;
    }

    s_len = strlen(s);
    break;
  }

  appendstring(buffer, s, width, 0, padding,
               alignment, s_len, is_negative, 0, always_sign);
}
Пример #2
0
inline static void appenddouble(StringBuffer *buffer,
                                double number,
                                int width, char padding,
                                int alignment, int precision,
                                int adjust, char fmt,
                                int always_sign) {
  char num_buf[NUM_BUF_SIZE];
  char *s = nullptr;
  int s_len = 0, is_negative = 0;

  if ((adjust & ADJ_PRECISION) == 0) {
    precision = FLOAT_PRECISION;
  } else if (precision > MAX_FLOAT_PRECISION) {
    precision = MAX_FLOAT_PRECISION;
  }

  if (isnan(number)) {
    is_negative = (number<0);
    appendstring(buffer, "NaN", 3, 0, padding,
                 alignment, 3, is_negative, 0, always_sign);
    return;
  }

  if (isinf(number)) {
    is_negative = (number<0);
    appendstring(buffer, "INF", 3, 0, padding,
                 alignment, 3, is_negative, 0, always_sign);
    return;
  }

#if defined(HAVE_LOCALE_H)
  struct lconv *lconv;
  lconv = localeconv();
# define APPENDDOUBLE_LCONV_DECIMAL_POINT (*lconv->decimal_point)
#else
# define APPENDDOUBLE_LCONV_DECIMAL_POINT '.'
#endif

  switch (fmt) {
  case 'e':
  case 'E':
  case 'f':
  case 'F':
    s = php_conv_fp((fmt == 'f')?'F':fmt,
                    number, 0, precision,
                    (fmt == 'f')?APPENDDOUBLE_LCONV_DECIMAL_POINT:'.',
                    &is_negative, &num_buf[1], &s_len);
    if (is_negative) {
      num_buf[0] = '-';
      s = num_buf;
      s_len++;
    } else if (always_sign) {
      num_buf[0] = '+';
      s = num_buf;
      s_len++;
    }
    break;

  case 'g':
  case 'G':
    if (precision == 0)
      precision = 1;
    /*
     * * We use &num_buf[ 1 ], so that we have room for the sign
     */
    s = php_gcvt(number, precision,
                 APPENDDOUBLE_LCONV_DECIMAL_POINT,
                 (fmt == 'G')?'E':'e',
                 &num_buf[1]);
    is_negative = 0;
    if (*s == '-') {
      is_negative = 1;
      s = &num_buf[1];
    } else if (always_sign) {
      num_buf[0] = '+';
      s = num_buf;
    }

    s_len = strlen(s);
    break;
  }

  appendstring(buffer, s, width, 0, padding,
               alignment, s_len, is_negative, 0, always_sign);
}
Пример #3
0
/* php_spintf_appenddouble() {{{ */
inline static void
php_sprintf_appenddouble(char **buffer, int *pos,
						 int *size, double number,
						 int width, char padding,
						 int alignment, int precision,
						 int adjust, char fmt,
						 int always_sign
						 TSRMLS_DC)
{
	char num_buf[NUM_BUF_SIZE];
	char *s = NULL;
	int s_len = 0, is_negative = 0;
#ifdef HAVE_LOCALE_H
	struct lconv *lconv;
#endif

	PRINTF_DEBUG(("sprintf: appenddouble(%x, %x, %x, %f, %d, '%c', %d, %c)\n",
				  *buffer, pos, size, number, width, padding, alignment, fmt));
	if ((adjust & ADJ_PRECISION) == 0) {
		precision = FLOAT_PRECISION;
	} else if (precision > MAX_FLOAT_PRECISION) {
		php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Requested precision of %d digits was truncated to PHP maximum of %d digits", precision, MAX_FLOAT_PRECISION);
		precision = MAX_FLOAT_PRECISION;
	}
	
	if (zend_isnan(number)) {
		is_negative = (number<0);
		php_sprintf_appendstring(buffer, pos, size, "NaN", 3, 0, padding,
								 alignment, 3, is_negative, 0, always_sign);
		return;
	}

	if (zend_isinf(number)) {
		is_negative = (number<0);
		php_sprintf_appendstring(buffer, pos, size, "INF", 3, 0, padding,
								 alignment, 3, is_negative, 0, always_sign);
		return;
	}

	switch (fmt) {			
		case 'e':
		case 'E':
		case 'f':
		case 'F':
#ifdef HAVE_LOCALE_H
			lconv = localeconv();
#endif
			s = php_conv_fp((fmt == 'f')?'F':fmt, number, 0, precision,
						(fmt == 'f')?LCONV_DECIMAL_POINT:'.',
						&is_negative, &num_buf[1], &s_len);
			if (is_negative) {
				num_buf[0] = '-';
				s = num_buf;
				s_len++;
			} else if (always_sign) {
				num_buf[0] = '+';
				s = num_buf;
				s_len++;
			}
			break;

		case 'g':
		case 'G':
			if (precision == 0)
				precision = 1;
			/*
			 * * We use &num_buf[ 1 ], so that we have room for the sign
			 */
#ifdef HAVE_LOCALE_H
			lconv = localeconv();
#endif
			s = php_gcvt(number, precision, LCONV_DECIMAL_POINT, (fmt == 'G')?'E':'e', &num_buf[1]);
			is_negative = 0;
			if (*s == '-') {
				is_negative = 1;
				s = &num_buf[1];
			} else if (always_sign) {
				num_buf[0] = '+';
				s = num_buf;
			}

			s_len = strlen(s);
			break;
	}

	php_sprintf_appendstring(buffer, pos, size, s, width, 0, padding,
							 alignment, s_len, is_negative, 0, always_sign);
}