if (!php_math_is_finite(value)) {
return value;
}
-
+
places = places < INT_MIN+1 ? INT_MIN+1 : places;
precision_places = 14 - php_intlog10abs(value);
/* round the temp value */
tmp_value = php_round_helper(tmp_value, mode);
-
+
/* see if it makes sense to use simple division to round the value */
if (abs(places) < 23) {
if (places > 0) {
/* {{{ proto int abs(int number)
Return the absolute value of the number */
-PHP_FUNCTION(abs)
+PHP_FUNCTION(abs)
{
zval **value;
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &value) == FAILURE) {
return;
}
convert_scalar_to_number_ex(value);
-
+
if (Z_TYPE_PP(value) == IS_DOUBLE) {
RETURN_DOUBLE(fabs(Z_DVAL_PP(value)));
} else if (Z_TYPE_PP(value) == IS_LONG) {
}
RETURN_FALSE;
}
-/* }}} */
+/* }}} */
/* {{{ proto float ceil(float number)
Returns the next highest integer value of the number */
-PHP_FUNCTION(ceil)
+PHP_FUNCTION(ceil)
{
zval **value;
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &value) == FAILURE) {
return;
}
PHP_FUNCTION(floor)
{
zval **value;
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &value) == FAILURE) {
return;
}
long precision = 0;
long mode = PHP_ROUND_HALF_UP;
double return_val;
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|ll", &value, &precision, &mode) == FAILURE) {
return;
}
PHP_FUNCTION(cos)
{
double num;
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &num) == FAILURE) {
return;
}
PHP_FUNCTION(acosh)
{
double num;
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &num) == FAILURE) {
return;
}
/* {{{ proto float expm1(float number)
Returns exp(number) - 1, computed in a way that accurate even when the value of number is close to zero */
/*
- WARNING: this function is expermental: it could change its name or
+ WARNING: this function is expermental: it could change its name or
disappear in the next version of PHP!
*/
PHP_FUNCTION(expm1)
/* }}} */
/* {{{ proto float log1p(float number)
- Returns log(1 + number), computed in a way that accurate even when the value of number is close to zero */
+ Returns log(1 + number), computed in a way that accurate even when the value of number is close to zero */
/*
- WARNING: this function is expermental: it could change its name or
+ WARNING: this function is expermental: it could change its name or
disappear in the next version of PHP!
*/
PHP_FUNCTION(log1p)
PHP_FUNCTION(log)
{
double num, base = 0;
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|d", &num, &base) == FAILURE) {
return;
}
RETURN_DOUBLE(log(num));
}
if (base <= 0.0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "base must be greater than 0");
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "base must be greater than 0");
RETURN_FALSE;
}
if (base == 1) {
/* }}} */
/* {{{ proto float hypot(float num1, float num2)
- Returns sqrt(num1*num1 + num2*num2) */
+ Returns sqrt(num1*num1 + num2*num2) */
PHP_FUNCTION(hypot)
{
double num1, num2;
for (i = Z_STRLEN_P(arg); i > 0; i--) {
c = *s++;
-
+
digit = (c >= '0' && c <= '9') ? c - '0'
: (c >= 'A' && c <= 'Z') ? c - 'A' + 10
: (c >= 'a' && c <= 'z') ? c - 'a' + 10
: base;
-
+
if (digit >= base) {
continue;
}
cutoff = LONG_MAX / base;
cutlim = LONG_MAX % base;
-
+
for (i = Z_STRLEN_P(arg); i > 0; i--) {
c = *s++;
/* might not work for EBCDIC */
- if (c >= '0' && c <= '9')
+ if (c >= '0' && c <= '9')
c -= '0';
- else if (c >= 'A' && c <= 'Z')
+ else if (c >= 'A' && c <= 'Z')
c -= 'A' - 10;
- else if (c >= 'a' && c <= 'z')
+ else if (c >= 'a' && c <= 'z')
c -= 'a' - 10;
else
continue;
if (c >= base)
continue;
-
+
switch (mode) {
case 0: /* Integer */
if (num < cutoff || (num == cutoff && c <= cutlim)) {
/* fall-through */
case 1: /* Float */
fnum = fnum * base + c;
- }
+ }
}
if (mode == 1) {
return estrndup(ptr, end - ptr);
}
-
+
return _php_math_longtobase(arg, base);
-}
+}
/* }}} */
/* {{{ proto int bindec(string binary_number)
PHP_FUNCTION(bindec)
{
zval **arg;
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
return;
}
PHP_FUNCTION(hexdec)
{
zval **arg;
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
return;
}
PHP_FUNCTION(octdec)
{
zval **arg;
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
return;
}
return;
}
convert_to_string_ex(number);
-
+
if (frombase < 2 || frombase > 36) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid `from base' (%ld)", frombase);
RETURN_FALSE;
}
result = _php_math_zvaltobase(&temp, tobase TSRMLS_CC);
RETVAL_STRING(result, 0);
-}
+}
/* }}} */
-/* {{{ _php_math_number_format
+/* {{{ _php_math_number_format
*/
PHPAPI char *_php_math_number_format(double d, int dec, char dec_point, char thousand_sep)
{
static char *_php_math_number_format_ex_len(double d, int dec, char *dec_point,
size_t dec_point_len, char *thousand_sep, size_t thousand_sep_len,
- int *result_len)
+ size_t *result_len)
{
char *tmpbuf = NULL, *resbuf;
char *s, *t; /* source, target */
char *dp;
- int integral;
- int tmplen, reslen=0;
+ size_t integral;
+ size_t tmplen, reslen=0;
int count=0;
int is_negative=0;
/* allow for thousand separators */
if (thousand_sep) {
+ if (integral + thousand_sep_len * ((integral-1) / 3) < integral) {
+ /* overflow */
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "String overflow");
+ }
integral += thousand_sep_len * ((integral-1) / 3);
}
-
+
reslen = integral;
-
+
if (dec) {
reslen += dec;
if (dec_point) {
+ if (reslen + dec_point < dec_point) {
+ /* overflow */
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "String overflow");
+ }
reslen += dec_point_len;
}
}
while (topad--) {
*t-- = '0';
}
-
+
if (dp) {
s -= declen + 1; /* +1 to skip the point */
t -= declen;
}
efree(tmpbuf);
-
+
if (result_len) {
*result_len = reslen;
}
char *thousand_sep = NULL, *dec_point = NULL;
char thousand_sep_chr = ',', dec_point_chr = '.';
int thousand_sep_len = 0, dec_point_len = 0;
-
+ char *formatted;
+ size_t formatted_len;
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d|ls!s!", &num, &dec, &dec_point, &dec_point_len, &thousand_sep, &thousand_sep_len) == FAILURE) {
return;
}
switch(ZEND_NUM_ARGS()) {
case 1:
- RETURN_STRING(_php_math_number_format(num, 0, dec_point_chr, thousand_sep_chr), 0);
+ formatted = _php_math_number_format(num, 0, dec_point_chr, thousand_sep_chr);
+ formatted_len = strlen(formatted);
break;
case 2:
- RETURN_STRING(_php_math_number_format(num, dec, dec_point_chr, thousand_sep_chr), 0);
+ formatted = _php_math_number_format(num, dec, dec_point_chr, thousand_sep_chr);
+ formatted_len = strlen(formatted);
break;
case 4:
if (dec_point == NULL) {
thousand_sep_len = 1;
}
- Z_TYPE_P(return_value) = IS_STRING;
- Z_STRVAL_P(return_value) = _php_math_number_format_ex_len(num, dec,
+ formatted = _php_math_number_format_ex_len(num, dec,
dec_point, dec_point_len, thousand_sep, thousand_sep_len,
- &Z_STRLEN_P(return_value));
+ &formatted_len);
break;
default:
WRONG_PARAM_COUNT;
- break;
+ return;
}
+ RETVAL_STRINGL_CHECK(formatted, formatted_len, 0);
}
/* }}} */