summaryrefslogtreecommitdiff
path: root/ext/standard/math.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/standard/math.c')
-rw-r--r--ext/standard/math.c50
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", &dividend, &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);
}
/* }}} */