diff --git a/ext/standard/math.c b/ext/standard/math.c index 74ffa565031a3..46a777e16399f 100644 --- a/ext/standard/math.c +++ b/ext/standard/math.c @@ -99,7 +99,8 @@ static inline double php_round_helper(double value, int mode) { tmp_value = floor(value + 0.5); if ((mode == PHP_ROUND_HALF_DOWN && value == (-0.5 + tmp_value)) || (mode == PHP_ROUND_HALF_EVEN && value == (0.5 + 2 * floor(tmp_value/2.0))) || - (mode == PHP_ROUND_HALF_ODD && value == (0.5 + 2 * floor(tmp_value/2.0) - 1.0))) + (mode == PHP_ROUND_HALF_ODD && value == (0.5 + 2 * floor(tmp_value/2.0) - 1.0)) || + value < (-0.5 + tmp_value)) { tmp_value = tmp_value - 1.0; } @@ -107,7 +108,8 @@ static inline double php_round_helper(double value, int mode) { tmp_value = ceil(value - 0.5); if ((mode == PHP_ROUND_HALF_DOWN && value == (0.5 + tmp_value)) || (mode == PHP_ROUND_HALF_EVEN && value == (-0.5 + 2 * ceil(tmp_value/2.0))) || - (mode == PHP_ROUND_HALF_ODD && value == (-0.5 + 2 * ceil(tmp_value/2.0) + 1.0))) + (mode == PHP_ROUND_HALF_ODD && value == (-0.5 + 2 * ceil(tmp_value/2.0) + 1.0)) || + value > (0.5 + tmp_value)) { tmp_value = tmp_value + 1.0; } @@ -131,7 +133,7 @@ PHPAPI double _php_math_round(double value, int places, int mode) { return value; } - places = places < INT_MIN+1 ? INT_MIN+1 : places; + places = places < INT_MIN + 1 ? INT_MIN + 1 : places; precision_places = 14 - php_intlog10abs(value); f1 = php_intpow10(abs(places)); @@ -140,7 +142,7 @@ 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 - 15 < places) { - int64_t use_precision = precision_places < INT_MIN+1 ? INT_MIN+1 : precision_places; + 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) { @@ -153,7 +155,7 @@ PHPAPI double _php_math_round(double value, int places, int mode) { 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; + use_precision = use_precision < INT_MIN + 1 ? INT_MIN + 1 : use_precision; /* now correctly move the decimal point */ f2 = php_intpow10(abs((int)use_precision)); /* because places < precision_places */ diff --git a/ext/standard/tests/math/round_bug12143.phpt b/ext/standard/tests/math/round_bug12143.phpt new file mode 100644 index 0000000000000..25797a36100e9 --- /dev/null +++ b/ext/standard/tests/math/round_bug12143.phpt @@ -0,0 +1,38 @@ +--TEST-- +Bug #12143 round() with large FP +--FILE-- + +--EXPECT-- +float(0) +float(0) +float(0) +float(0) +float(0) +float(0) +float(0) +float(0) +float(1) +float(1) +float(1) +float(1) +float(-1) +float(-1) +float(-1) +float(-1)