diff options
Diffstat (limited to 'ext/standard/math.c')
-rw-r--r-- | ext/standard/math.c | 50 |
1 files changed, 26 insertions, 24 deletions
diff --git a/ext/standard/math.c b/ext/standard/math.c index 9ab457b41d..688ae9f6d1 100644 --- a/ext/standard/math.c +++ b/ext/standard/math.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 7 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2015 The PHP Group | + | Copyright (c) 1997-2016 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -93,18 +93,6 @@ static inline double php_intpow10(int power) { } /* }}} */ -/* {{{ php_math_is_finite */ -static inline int php_math_is_finite(double value) { -#if defined(PHP_WIN32) - return _finite(value); -#elif defined(isfinite) - return isfinite(value); -#else - return value == value && (value == 0. || value * 2. != value); -#endif -} -/* }}} */ - /* {{{ php_round_helper Actually performs the rounding of a value to integer in a certain mode */ static inline double php_round_helper(double value, int mode) { @@ -142,10 +130,11 @@ PHPAPI double _php_math_round(double value, int places, int mode) { double tmp_value; int precision_places; - if (!php_math_is_finite(value)) { + if (!zend_finite(value)) { return value; } + places = places < INT_MIN+1 ? INT_MIN+1 : places; precision_places = 14 - php_intlog10abs(value); f1 = php_intpow10(abs(places)); @@ -154,8 +143,10 @@ PHPAPI double _php_math_round(double value, int places, int mode) { the requested places BUT is small enough to make sure a non-zero value is returned, pre-round the result to the precision */ if (precision_places > places && precision_places - places < 15) { - f2 = php_intpow10(abs(precision_places)); - if (precision_places >= 0) { + int64_t use_precision = precision_places < INT_MIN+1 ? INT_MIN+1 : precision_places; + + f2 = php_intpow10(abs((int)use_precision)); + if (use_precision >= 0) { tmp_value = value * f2; } else { tmp_value = value / f2; @@ -163,8 +154,11 @@ PHPAPI double _php_math_round(double value, int places, int mode) { /* preround the result (tmp_value will always be something * 1e14, thus never larger than 1e15 here) */ tmp_value = php_round_helper(tmp_value, mode); + + use_precision = places - precision_places; + use_precision = use_precision < INT_MIN+1 ? INT_MIN+1 : use_precision; /* now correctly move the decimal point */ - f2 = php_intpow10(abs(places - precision_places)); + f2 = php_intpow10(abs((int)use_precision)); /* because places < precision_places */ tmp_value = tmp_value / f2; } else { @@ -390,7 +384,15 @@ PHP_FUNCTION(round) } if (ZEND_NUM_ARGS() >= 2) { - places = (int) precision; +#if SIZEOF_ZEND_LONG > SIZEOF_INT + if (precision >= 0) { + places = precision > INT_MAX ? INT_MAX : (int)precision; + } else { + places = precision <= INT_MIN ? INT_MIN+1 : (int)precision; + } +#else + places = precision; +#endif } convert_scalar_to_number_ex(value); @@ -1456,27 +1458,27 @@ PHP_FUNCTION(fmod) } /* }}} */ -/* {{{ proto int intdiv(int numerator, int divisor) - Returns the integer division of the numerator by the divisor */ +/* {{{ proto int intdiv(int dividend, int divisor) + Returns the integer quotient of the division of dividend by divisor */ PHP_FUNCTION(intdiv) { - zend_long numerator, divisor; + zend_long dividend, divisor; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &numerator, &divisor) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", ÷nd, &divisor) == FAILURE) { return; } if (divisor == 0) { zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Division by zero"); return; - } else if (divisor == -1 && numerator == ZEND_LONG_MIN) { + } else if (divisor == -1 && dividend == ZEND_LONG_MIN) { /* Prevent overflow error/crash ... really should not happen: We don't return a float here as that violates function contract */ zend_throw_exception_ex(zend_ce_arithmetic_error, 0, "Division of PHP_INT_MIN by -1 is not an integer"); return; } - RETURN_LONG(numerator / divisor); + RETURN_LONG(dividend / divisor); } /* }}} */ |