diff --git a/ext/standard/math.c b/ext/standard/math.c index 05f2252e304e..fc2d926e1ff6 100644 --- a/ext/standard/math.c +++ b/ext/standard/math.c @@ -184,7 +184,7 @@ PHPAPI double _php_math_round(double value, int places, int mode) { /* If the decimal precision guaranteed by FP arithmetic is higher than the requested places BUT is small enough to make sure a non-zero value - is returned, pre-round the result to the precision */ + is returned, adjust result digits 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; @@ -194,9 +194,9 @@ PHPAPI double _php_math_round(double value, int places, int mode) { } else { tmp_value = value / f2; } - /* preround the result (tmp_value will always be something * 1e14, + /* adjust result digits (tmp_value will always be something * 1e14, thus never larger than 1e15 here) */ - tmp_value = php_round_helper(tmp_value, mode); + tmp_value = (tmp_value >= 0.0) ? floor(tmp_value) : ceil(tmp_value); use_precision = places - precision_places; use_precision = use_precision < INT_MIN+1 ? INT_MIN+1 : use_precision; diff --git a/ext/standard/tests/math/bug24142.phpt b/ext/standard/tests/math/bug24142.phpt index 947deaebd669..739ac25421dc 100644 --- a/ext/standard/tests/math/bug24142.phpt +++ b/ext/standard/tests/math/bug24142.phpt @@ -2,19 +2,65 @@ Bug #24142 (round() problems) --FILE-- ".round($v, 2)."\n"; - $v += 0.01; -} +echo "round(0.005, 2)\n"; +var_dump(round(0.005, 2)); +echo "\n"; + +echo "round(0.015, 2)\n"; +var_dump(round(0.015, 2)); +echo "\n"; + +echo "round(0.025, 2)\n"; +var_dump(round(0.025, 2)); +echo "\n"; + +echo "round(0.035, 2)\n"; +var_dump(round(0.035, 2)); +echo "\n"; + +echo "round(0.045, 2)\n"; +var_dump(round(0.045, 2)); +echo "\n"; + +echo "round(0.055, 2)\n"; +var_dump(round(0.055, 2)); +echo "\n"; + +echo "round(0.065, 2)\n"; +var_dump(round(0.065, 2)); +echo "\n"; + +echo "round(0.075, 2)\n"; +var_dump(round(0.075, 2)); +echo "\n"; + +echo "round(0.085, 2)\n"; +var_dump(round(0.085, 2)); ?> --EXPECT-- -round(0.005, 2) -> 0.01 -round(0.015, 2) -> 0.02 -round(0.025, 2) -> 0.03 -round(0.035, 2) -> 0.04 -round(0.045, 2) -> 0.05 -round(0.055, 2) -> 0.06 -round(0.065, 2) -> 0.07 -round(0.075, 2) -> 0.08 -round(0.085, 2) -> 0.09 +round(0.005, 2) +float(0.01) + +round(0.015, 2) +float(0.02) + +round(0.025, 2) +float(0.03) + +round(0.035, 2) +float(0.04) + +round(0.045, 2) +float(0.05) + +round(0.055, 2) +float(0.06) + +round(0.065, 2) +float(0.07) + +round(0.075, 2) +float(0.08) + +round(0.085, 2) +float(0.09) diff --git a/ext/standard/tests/math/round_gh12143_adjustment_result_digit.phpt b/ext/standard/tests/math/round_gh12143_adjustment_result_digit.phpt new file mode 100644 index 000000000000..4917ee88d5e9 --- /dev/null +++ b/ext/standard/tests/math/round_gh12143_adjustment_result_digit.phpt @@ -0,0 +1,55 @@ +--TEST-- +Fix GH-12143: Improved handling of adjusting result digits +--FILE-- + +--EXPECT-- +HALF_UP +float(1.7000000000001) +float(-1.7000000000001) +float(123456789012340) +float(-123456789012340) + +HALF_DOWN +float(1.7000000000001) +float(-1.7000000000001) +float(123456789012340) +float(-123456789012340) + +HALF_EVEN +float(1.7000000000002) +float(-1.7000000000002) +float(12345678901234) +float(-12345678901234) + +HALF_ODD +float(1.7000000000007) +float(-1.7000000000007) +float(12345678901233) +float(-12345678901233)