Skip to content

Commit 04420a7

Browse files
committed
standard: Add the RoundingMode enum for round()
1 parent fbc3297 commit 04420a7

26 files changed

+285
-109
lines changed

ext/bcmath/bcmath.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -696,15 +696,20 @@ PHP_FUNCTION(bcround)
696696
zend_string *numstr;
697697
zend_long precision = 0;
698698
zend_long mode = PHP_ROUND_HALF_UP;
699+
zend_object *mode_object = NULL;
699700
bc_num num = NULL, result;
700701

701702
ZEND_PARSE_PARAMETERS_START(1, 3)
702703
Z_PARAM_STR(numstr)
703704
Z_PARAM_OPTIONAL
704705
Z_PARAM_LONG(precision)
705-
Z_PARAM_LONG(mode)
706+
Z_PARAM_OBJ_OF_CLASS(mode_object, rounding_mode_ce)
706707
ZEND_PARSE_PARAMETERS_END();
707708

709+
if (mode_object != NULL) {
710+
mode = php_math_round_mode_from_enum(mode_object);
711+
}
712+
708713
switch (mode) {
709714
case PHP_ROUND_HALF_UP:
710715
case PHP_ROUND_HALF_DOWN:
@@ -716,7 +721,8 @@ PHP_FUNCTION(bcround)
716721
case PHP_ROUND_AWAY_FROM_ZERO:
717722
break;
718723
default:
719-
zend_argument_value_error(3, "must be a valid rounding mode (PHP_ROUND_*)");
724+
/* This is currently unreachable, but might become reachable when new modes are added. */
725+
zend_argument_value_error(3, " is a rounding mode that is not supported");
720726
return;
721727
}
722728

ext/bcmath/bcmath.stub.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,4 @@ function bcfloor(string $num): string {}
3737
function bcceil(string $num): string {}
3838

3939
/** @refcount 1 */
40-
function bcround(string $num, int $precision = 0, int $mode = PHP_ROUND_HALF_UP): string {}
40+
function bcround(string $num, int $precision = 0, RoundingMode $mode = RoundingMode::HalfAwayFromZero): string {}

ext/bcmath/bcmath_arginfo.h

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/bcmath/tests/bcround_away_from_zero.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
--TEST--
2-
bcround() function PHP_ROUND_AWAY_FROM_ZERO
2+
bcround() function AwayFromZero
33
--EXTENSIONS--
44
bcmath
55
--FILE--
66
<?php
77
require_once __DIR__ . '/bcround_test_helper.inc';
8-
run_round_test(PHP_ROUND_AWAY_FROM_ZERO);
8+
run_round_test(RoundingMode::AwayFromZero);
99
?>
1010
--EXPECT--
1111
========== non-boundary value ==========

ext/bcmath/tests/bcround_ceiling.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
--TEST--
2-
bcround() function PHP_ROUND_CEILING
2+
bcround() function PositiveInfinity
33
--EXTENSIONS--
44
bcmath
55
--FILE--
66
<?php
77
require_once __DIR__ . '/bcround_test_helper.inc';
8-
run_round_test(PHP_ROUND_CEILING);
8+
run_round_test(RoundingMode::PositiveInfinity);
99
?>
1010
--EXPECT--
1111
========== non-boundary value ==========

ext/bcmath/tests/bcround_early_return.phpt

Lines changed: 18 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,6 @@ bcround() function with early return
44
bcmath
55
--FILE--
66
<?php
7-
$otherModes = [
8-
'PHP_ROUND_HALF_DOWN',
9-
'PHP_ROUND_HALF_EVEN',
10-
'PHP_ROUND_HALF_ODD',
11-
'PHP_ROUND_FLOOR',
12-
'PHP_ROUND_CEILING',
13-
'PHP_ROUND_AWAY_FROM_ZERO',
14-
'PHP_ROUND_TOWARD_ZERO',
15-
];
167

178
$early_return_cases = [
189
['123', -4],
@@ -38,33 +29,27 @@ $early_return_cases = [
3829
];
3930

4031
$results = [
41-
'PHP_ROUND_HALF_UP' => [],
42-
'PHP_ROUND_HALF_DOWN' => [],
43-
'PHP_ROUND_HALF_EVEN' => [],
44-
'PHP_ROUND_HALF_ODD' => [],
45-
'PHP_ROUND_FLOOR' => [],
46-
'PHP_ROUND_CEIL' => [],
47-
'PHP_ROUND_AWAY_FROM_ZERO' => [],
48-
'PHP_ROUND_TOWARD_ZERO' => [],
32+
RoundingMode::HalfAwayFromZero->name => [],
4933
];
5034
foreach ($early_return_cases as [$num, $precision]) {
51-
$result = str_pad("[{$num}, {$precision}]", 33, ' ', STR_PAD_LEFT) . ' => ' . bcround($num, $precision, PHP_ROUND_HALF_UP) . "\n";
35+
$result = str_pad("[{$num}, {$precision}]", 33, ' ', STR_PAD_LEFT) . ' => ' . bcround($num, $precision, RoundingMode::HalfAwayFromZero) . "\n";
5236
echo $result;
53-
$results['PHP_ROUND_HALF_UP'][] = $result;
37+
$results[RoundingMode::HalfAwayFromZero->name][] = $result;
5438
}
5539

5640
echo "\n";
5741

58-
foreach ($otherModes as $mode) {
42+
foreach (RoundingMode::cases() as $mode) {
43+
$results[$mode->name] = [];
5944
foreach ($early_return_cases as [$num, $precision]) {
60-
$result = str_pad("[{$num}, {$precision}]", 33, ' ', STR_PAD_LEFT) . ' => ' . bcround($num, $precision, constant($mode)) . "\n";
61-
$results[$mode][] = $result;
45+
$result = str_pad("[{$num}, {$precision}]", 33, ' ', STR_PAD_LEFT) . ' => ' . bcround($num, $precision, $mode) . "\n";
46+
$results[$mode->name][] = $result;
6247
}
6348

64-
if ($results['PHP_ROUND_HALF_UP'] === $results[$mode]) {
65-
echo str_pad($mode, 24, ' ', STR_PAD_LEFT) . ": result is same to PHP_ROUND_HALF_UP\n";
49+
if ($results[RoundingMode::HalfAwayFromZero->name] === $results[$mode->name]) {
50+
echo str_pad($mode->name, 24, ' ', STR_PAD_LEFT) . ": result is same to HalfAwayFromZero\n";
6651
} else {
67-
echo str_pad($mode, 24, ' ', STR_PAD_LEFT) . ": result is not same to PHP_ROUND_HALF_UP, failed\n";
52+
echo str_pad($mode->name, 24, ' ', STR_PAD_LEFT) . ": result is not same to HalfAwayFromZero, failed\n";
6853
}
6954
}
7055
?>
@@ -90,10 +75,11 @@ foreach ($otherModes as $mode) {
9075
[-0.0, 0] => 0
9176
[-0.0000, 0] => 0
9277

93-
PHP_ROUND_HALF_DOWN: result is same to PHP_ROUND_HALF_UP
94-
PHP_ROUND_HALF_EVEN: result is same to PHP_ROUND_HALF_UP
95-
PHP_ROUND_HALF_ODD: result is same to PHP_ROUND_HALF_UP
96-
PHP_ROUND_FLOOR: result is same to PHP_ROUND_HALF_UP
97-
PHP_ROUND_CEILING: result is same to PHP_ROUND_HALF_UP
98-
PHP_ROUND_AWAY_FROM_ZERO: result is same to PHP_ROUND_HALF_UP
99-
PHP_ROUND_TOWARD_ZERO: result is same to PHP_ROUND_HALF_UP
78+
HalfAwayFromZero: result is same to HalfAwayFromZero
79+
HalfTowardsZero: result is same to HalfAwayFromZero
80+
HalfEven: result is same to HalfAwayFromZero
81+
HalfOdd: result is same to HalfAwayFromZero
82+
TowardsZero: result is same to HalfAwayFromZero
83+
AwayFromZero: result is same to HalfAwayFromZero
84+
NegativeInfinity: result is same to HalfAwayFromZero
85+
PositiveInfinity: result is same to HalfAwayFromZero

ext/bcmath/tests/bcround_error.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,4 @@ try {
2525
--EXPECT--
2626
bcround(): Argument #1 ($num) is not well-formed
2727
bcround(): Argument #1 ($num) is not well-formed
28-
bcround(): Argument #3 ($mode) must be a valid rounding mode (PHP_ROUND_*)
28+
bcround(): Argument #3 ($mode) must be of type RoundingMode, int given

ext/bcmath/tests/bcround_floor.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
--TEST--
2-
bcround() function PHP_ROUND_FLOOR
2+
bcround() function NegativeInfinity
33
--EXTENSIONS--
44
bcmath
55
--FILE--
66
<?php
77
require_once __DIR__ . '/bcround_test_helper.inc';
8-
run_round_test(PHP_ROUND_FLOOR);
8+
run_round_test(RoundingMode::NegativeInfinity);
99
?>
1010
--EXPECT--
1111
========== non-boundary value ==========

ext/bcmath/tests/bcround_half_down.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
--TEST--
2-
bcround() function PHP_ROUND_HALF_DOWN
2+
bcround() function HalfTowardsZero
33
--EXTENSIONS--
44
bcmath
55
--FILE--
66
<?php
77
require_once __DIR__ . '/bcround_test_helper.inc';
8-
run_round_test(PHP_ROUND_HALF_DOWN);
8+
run_round_test(RoundingMode::HalfTowardsZero);
99
?>
1010
--EXPECT--
1111
========== non-boundary value ==========

ext/bcmath/tests/bcround_half_even.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
--TEST--
2-
bcround() function PHP_ROUND_HALF_EVEN
2+
bcround() function HalfEven
33
--EXTENSIONS--
44
bcmath
55
--FILE--
66
<?php
77
require_once __DIR__ . '/bcround_test_helper.inc';
8-
run_round_test(PHP_ROUND_HALF_EVEN);
8+
run_round_test(RoundingMode::HalfEven);
99
?>
1010
--EXPECT--
1111
========== non-boundary value ==========

ext/bcmath/tests/bcround_half_odd.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
--TEST--
2-
bcround() function PHP_ROUND_HALF_ODD
2+
bcround() function HalfOdd
33
--EXTENSIONS--
44
bcmath
55
--FILE--
66
<?php
77
require_once __DIR__ . '/bcround_test_helper.inc';
8-
run_round_test(PHP_ROUND_HALF_ODD);
8+
run_round_test(RoundingMode::HalfOdd);
99
?>
1010
--EXPECT--
1111
========== non-boundary value ==========

ext/bcmath/tests/bcround_half_up.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
--TEST--
2-
bcround() function PHP_ROUND_HALF_UP
2+
bcround() function HalfAwayFromZero
33
--EXTENSIONS--
44
bcmath
55
--FILE--
66
<?php
77
require_once __DIR__ . '/bcround_test_helper.inc';
8-
run_round_test(PHP_ROUND_HALF_UP);
8+
run_round_test(RoundingMode::HalfAwayFromZero);
99
?>
1010
--EXPECT--
1111
========== non-boundary value ==========

ext/bcmath/tests/bcround_test_helper.inc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
<?php
22

3-
function printResult (array $cases, int $mode)
3+
function printResult (array $cases, RoundingMode $mode)
44
{
55
foreach ($cases as [$num, $precision]) {
66
echo str_pad("[{$num}, {$precision}]", 17, ' ', STR_PAD_LEFT), " => ", bcround($num, $precision, $mode), "\n";
77
}
88
echo "\n";
99
}
1010

11-
function run_round_test(int $mode)
11+
function run_round_test(RoundingMode $mode)
1212
{
1313
$non_boundary_value_cases = [
1414
['1.1', 0],

ext/bcmath/tests/bcround_toward_zero.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
--TEST--
2-
bcround() function PHP_ROUND_TOWARD_ZERO
2+
bcround() function TowardsZero
33
--EXTENSIONS--
44
bcmath
55
--FILE--
66
<?php
77
require_once __DIR__ . '/bcround_test_helper.inc';
8-
run_round_test(PHP_ROUND_TOWARD_ZERO);
8+
run_round_test(RoundingMode::TowardsZero);
99
?>
1010
--EXPECT--
1111
========== non-boundary value ==========

ext/reflection/tests/ReflectionExtension_getClassNames_basic.phpt

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,16 @@ Felix De Vliegher <felix.devliegher@gmail.com>
55
--FILE--
66
<?php
77
$standard = new ReflectionExtension('standard');
8-
var_dump($standard->getClassNames());
8+
$classNames = $standard->getClassNames();
9+
sort($classNames);
10+
foreach ($classNames as $className) {
11+
echo $className, PHP_EOL;
12+
}
913
?>
1014
--EXPECT--
11-
array(5) {
12-
[0]=>
13-
string(22) "__PHP_Incomplete_Class"
14-
[1]=>
15-
string(14) "AssertionError"
16-
[2]=>
17-
string(15) "php_user_filter"
18-
[3]=>
19-
string(12) "StreamBucket"
20-
[4]=>
21-
string(9) "Directory"
22-
}
15+
AssertionError
16+
Directory
17+
RoundingMode
18+
StreamBucket
19+
__PHP_Incomplete_Class
20+
php_user_filter

ext/standard/basic_functions.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "ext/session/php_session.h"
3535
#include "zend_exceptions.h"
3636
#include "zend_attributes.h"
37+
#include "zend_enum.h"
3738
#include "zend_ini.h"
3839
#include "zend_operators.h"
3940
#include "ext/standard/php_dns.h"
@@ -304,6 +305,8 @@ PHP_MINIT_FUNCTION(basic) /* {{{ */
304305

305306
assertion_error_ce = register_class_AssertionError(zend_ce_error);
306307

308+
rounding_mode_ce = register_class_RoundingMode();
309+
307310
BASIC_MINIT_SUBMODULE(var)
308311
BASIC_MINIT_SUBMODULE(file)
309312
BASIC_MINIT_SUBMODULE(pack)

ext/standard/basic_functions.stub.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3145,8 +3145,19 @@ function ceil(int|float $num): float {}
31453145
/** @compile-time-eval */
31463146
function floor(int|float $num): float {}
31473147

3148+
enum RoundingMode {
3149+
case HalfAwayFromZero;
3150+
case HalfTowardsZero;
3151+
case HalfEven;
3152+
case HalfOdd;
3153+
case TowardsZero;
3154+
case AwayFromZero;
3155+
case NegativeInfinity;
3156+
case PositiveInfinity;
3157+
}
3158+
31483159
/** @compile-time-eval */
3149-
function round(int|float $num, int $precision = 0, int $mode = PHP_ROUND_HALF_UP): float {}
3160+
function round(int|float $num, int $precision = 0, int|RoundingMode $mode = RoundingMode::HalfAwayFromZero): float {}
31503161

31513162
/** @compile-time-eval */
31523163
function sin(float $num): float {}

ext/standard/basic_functions_arginfo.h

Lines changed: 29 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)