Skip to content

Commit 9ad8aa7

Browse files
committed
round: Bypass the precision logic when rounding to 0 places
Since phpGH-12220 the implementation of `php_round_helper()`, which performs rounding to an integral value, is easy to verify for correctness up to the floating point precision. If rounding to 0 places is desired, i.e. the userland `round()` function is called with `$precision = 0`, we bypass all logic for the decimal point adjustment and instead directly call `php_round_helper()`. This change fixes the remaining two cases of phpGH-12143 and likely guarantees correct rounding for all possible inputs and `$precision = 0`.
1 parent 659c06d commit 9ad8aa7

File tree

3 files changed

+58
-0
lines changed

3 files changed

+58
-0
lines changed

ext/standard/math.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,10 @@ PHPAPI double _php_math_round(double value, int places, int mode) {
177177
return value;
178178
}
179179

180+
if (places == 0) {
181+
return php_round_helper(value, mode);
182+
}
183+
180184
places = places < INT_MIN+1 ? INT_MIN+1 : places;
181185
precision_places = 14 - php_intlog10abs(value);
182186

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
GH-12143: Test rounding of 1.4999999999999998.
3+
--FILE--
4+
<?php
5+
foreach ([
6+
1.4999999999999998,
7+
-1.4999999999999998,
8+
] as $number) {
9+
foreach ([
10+
'PHP_ROUND_HALF_UP',
11+
'PHP_ROUND_HALF_DOWN',
12+
'PHP_ROUND_HALF_EVEN',
13+
'PHP_ROUND_HALF_ODD',
14+
] as $mode) {
15+
printf("%-20s: %+.17g -> %+.17g\n", $mode, $number, round($number, 0, constant($mode)));
16+
}
17+
}
18+
?>
19+
--EXPECT--
20+
PHP_ROUND_HALF_UP : +1.4999999999999998 -> +1
21+
PHP_ROUND_HALF_DOWN : +1.4999999999999998 -> +1
22+
PHP_ROUND_HALF_EVEN : +1.4999999999999998 -> +1
23+
PHP_ROUND_HALF_ODD : +1.4999999999999998 -> +1
24+
PHP_ROUND_HALF_UP : -1.4999999999999998 -> -1
25+
PHP_ROUND_HALF_DOWN : -1.4999999999999998 -> -1
26+
PHP_ROUND_HALF_EVEN : -1.4999999999999998 -> -1
27+
PHP_ROUND_HALF_ODD : -1.4999999999999998 -> -1
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
GH-12143: Test rounding of 4503599627370495.5.
3+
--FILE--
4+
<?php
5+
foreach ([
6+
4503599627370495.5,
7+
-4503599627370495.5,
8+
] as $number) {
9+
foreach ([
10+
'PHP_ROUND_HALF_UP',
11+
'PHP_ROUND_HALF_DOWN',
12+
'PHP_ROUND_HALF_EVEN',
13+
'PHP_ROUND_HALF_ODD',
14+
] as $mode) {
15+
printf("%-20s: %+.17g -> %+.17g\n", $mode, $number, round($number, 0, constant($mode)));
16+
}
17+
}
18+
?>
19+
--EXPECT--
20+
PHP_ROUND_HALF_UP : +4503599627370495.5 -> +4503599627370496
21+
PHP_ROUND_HALF_DOWN : +4503599627370495.5 -> +4503599627370495
22+
PHP_ROUND_HALF_EVEN : +4503599627370495.5 -> +4503599627370496
23+
PHP_ROUND_HALF_ODD : +4503599627370495.5 -> +4503599627370495
24+
PHP_ROUND_HALF_UP : -4503599627370495.5 -> -4503599627370496
25+
PHP_ROUND_HALF_DOWN : -4503599627370495.5 -> -4503599627370495
26+
PHP_ROUND_HALF_EVEN : -4503599627370495.5 -> -4503599627370496
27+
PHP_ROUND_HALF_ODD : -4503599627370495.5 -> -4503599627370495

0 commit comments

Comments
 (0)