Skip to content

RFC: Add 4 new rounding modes to round() function #12056

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 25 commits into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
5b89dd2
Add 4 new rounding modes to round() function
jorgsowa Aug 25, 2023
d0d76a0
Added tests for consistency with ceil() and floor() functions
jorgsowa Sep 4, 2023
2c853a8
Extend test cases for round modes
jorgsowa Sep 7, 2023
087ebba
Fix returning rounded number for switch
jorgsowa Oct 3, 2023
5be2200
Clear the code after rebase
jorgsowa Oct 4, 2023
40b9369
Add aliases and deprecate constants ROUND_DOWN and ROUND_UP
jorgsowa Oct 4, 2023
962f752
Added information about constants from Intl extension to NEWS
jorgsowa Oct 4, 2023
823025d
Undeprecate the constants
jorgsowa Oct 5, 2023
6790846
Refactored rounding function
jorgsowa Oct 5, 2023
8844699
Generate stubs
jorgsowa Nov 14, 2023
f4fa18c
use fabs method for specific rounding modes
jorgsowa Nov 14, 2023
8b774e7
Revert logic of fabs in rounding function
jorgsowa Nov 15, 2023
fd1ee38
Revert formatting of the math.c
jorgsowa Nov 15, 2023
76ab816
Removed indentation of switch branches
jorgsowa Nov 15, 2023
c085eee
Removed unnecessary formatting changes
jorgsowa Dec 18, 2023
b8e3933
Updated stub for basic_functions
jorgsowa Dec 18, 2023
7acc226
Merged if conditions
jorgsowa Dec 18, 2023
2a53d44
Used if condition for PHP_ROUND_AWAY_FROM_ZERO mode
jorgsowa Dec 19, 2023
4b919d8
Replaced missing colon
jorgsowa Dec 19, 2023
17eda27
[ci skip] Formatting
TimWolla Dec 19, 2023
db8ffaa
[skip ci] Renamed title of test round_modes_ceiling_and_floor.phpt
jorgsowa Dec 19, 2023
f2484f6
Added tests of round() for zeroes
jorgsowa Dec 20, 2023
be9e7ec
Removed zeroes from round() standard tests
jorgsowa Dec 20, 2023
7f8b0a3
Re-add 7/-7 to round_modes.phpt
TimWolla Dec 21, 2023
fd82487
UPGRADING / NEWS
TimWolla Dec 21, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ Intl:
. Added IntlDateFormatter::PATTERN constant. (David Carlier)
. Fixed Numberformatter::__construct when the locale is invalid, now
throws an exception. (David Carlier)
. Added NumberFormatter::ROUND_TOWARD_ZERO and ::ROUND_AWAY_FROM_ZERO as
aliases for ::ROUND_DOWN and ::ROUND_UP. (Jorg Sowa)

MBString:
. Added mb_trim, mb_ltrim and mb_rtrim. (Yuya Hamada)
Expand Down Expand Up @@ -106,7 +108,8 @@ Standard:
(nielsdos)
. Removed the deprecated inet_ntoa call support. (David Carlier)
. Cast large floats that are within int range to int in number_format so
the precision is not lost. (Marc Bennewitz)
the precision is not lost. (Marc Bennewitz)
. Add support for 4 new rounding modes to the round() function. (Jorg Sowa)

XML:
. Added XML_OPTION_PARSE_HUGE parser option. (nielsdos)
Expand Down
9 changes: 9 additions & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,11 @@ PHP 8.4 UPGRADE NOTES
- Intl:
. IntlDateFormatter::__construct() throws a ValueError if the locale is invalid.
. NumberFormatter::__construct() throws a ValueError if the locale is invalid.
. NumberFormatter::ROUND_TOWARD_ZERO and NumberFormatter::ROUND_AWAY_FROM_ZERO
have been added as aliases for NumberFormatter::ROUND_DOWN and
NumberFormatter::ROUND_UP to be consistent with the new PHP_ROUND_* modes.

RFC: https://wiki.php.net/rfc/new_rounding_modes_to_round_function

- MBString:
. The behavior of mb_strcut is more consistent now on invalid UTF-8 and UTF-16
Expand Down Expand Up @@ -250,6 +255,10 @@ PHP 8.4 UPGRADE NOTES
has been increased from '10' to '12'.

RFC: https://wiki.php.net/rfc/bcrypt_cost_2023
. Four new modes have been added to the round() function: PHP_ROUND_CEILING,
PHP_ROUND_FLOOR, PHP_ROUND_TOWARD_ZERO, PHP_ROUND_AWAY_FROM_ZERO.

RFC: https://wiki.php.net/rfc/new_rounding_modes_to_round_function

========================================
6. New Functions
Expand Down
4 changes: 4 additions & 0 deletions ext/intl/formatter/formatter.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ class NumberFormatter
public const int ROUND_DOWN = UNKNOWN;
/** @cvalue UNUM_ROUND_UP */
public const int ROUND_UP = UNKNOWN;
/** @cvalue UNUM_ROUND_DOWN */
public const int ROUND_TOWARD_ZERO = UNKNOWN;
/** @cvalue UNUM_ROUND_UP */
public const int ROUND_AWAY_FROM_ZERO = UNKNOWN;
/** @cvalue UNUM_ROUND_HALFEVEN */
public const int ROUND_HALFEVEN = UNKNOWN;
/** @cvalue UNUM_ROUND_HALFDOWN */
Expand Down
14 changes: 13 additions & 1 deletion ext/intl/formatter/formatter_arginfo.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 33 additions & 0 deletions ext/intl/tests/formatter/rounding_modes.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
--TEST--
NumberFormatter: rounding modes
--EXTENSIONS--
intl
--FILE--
<?php
ini_set("intl.error_level", E_WARNING);

var_dump(NumberFormatter::ROUND_CEILING);
var_dump(NumberFormatter::ROUND_FLOOR);
var_dump(NumberFormatter::ROUND_DOWN);
var_dump(NumberFormatter::ROUND_TOWARD_ZERO);
var_dump(NumberFormatter::ROUND_UP);
var_dump(NumberFormatter::ROUND_AWAY_FROM_ZERO);
var_dump(NumberFormatter::ROUND_HALFEVEN);
var_dump(NumberFormatter::ROUND_HALFDOWN);
var_dump(NumberFormatter::ROUND_HALFUP);

var_dump(NumberFormatter::ROUND_DOWN === NumberFormatter::ROUND_TOWARD_ZERO);
var_dump(NumberFormatter::ROUND_UP === NumberFormatter::ROUND_AWAY_FROM_ZERO);
?>
--EXPECTF--
int(0)
int(1)
int(2)
int(2)
int(3)
int(3)
int(4)
int(5)
int(6)
bool(true)
bool(true)
20 changes: 20 additions & 0 deletions ext/standard/basic_functions.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,26 @@
* @cvalue PHP_ROUND_HALF_ODD
*/
const PHP_ROUND_HALF_ODD = UNKNOWN;
/**
* @var int
* @cvalue PHP_ROUND_CEILING
*/
const PHP_ROUND_CEILING = UNKNOWN;
/**
* @var int
* @cvalue PHP_ROUND_FLOOR
*/
const PHP_ROUND_FLOOR = UNKNOWN;
/**
* @var int
* @cvalue PHP_ROUND_TOWARD_ZERO
*/
const PHP_ROUND_TOWARD_ZERO = UNKNOWN;
/**
* @var int
* @cvalue PHP_ROUND_AWAY_FROM_ZERO
*/
const PHP_ROUND_AWAY_FROM_ZERO = UNKNOWN;

/* crypt.c */

Expand Down
6 changes: 5 additions & 1 deletion ext/standard/basic_functions_arginfo.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 30 additions & 0 deletions ext/standard/math.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,30 @@ static inline double php_round_helper(double value, int mode) {

return integral;

case PHP_ROUND_CEILING:
if (value > 0.0 && fractional > 0.0) {
return integral + 1.0;
}

return integral;

case PHP_ROUND_FLOOR:
if (value < 0.0 && fractional > 0.0) {
return integral - 1.0;
}

return integral;

case PHP_ROUND_TOWARD_ZERO:
return integral;

case PHP_ROUND_AWAY_FROM_ZERO:
if (fractional > 0.0) {
return integral + copysign(1.0, integral);
}

return integral;

case PHP_ROUND_HALF_EVEN:
if (fractional > 0.5) {
return integral + copysign(1.0, integral);
Expand All @@ -143,6 +167,7 @@ static inline double php_round_helper(double value, int mode) {
}

return integral;

case PHP_ROUND_HALF_ODD:
if (fractional > 0.5) {
return integral + copysign(1.0, integral);
Expand All @@ -157,6 +182,7 @@ static inline double php_round_helper(double value, int mode) {
}

return integral;

EMPTY_SWITCH_DEFAULT_CASE();
}
// FIXME: GCC bug, branch is considered reachable.
Expand Down Expand Up @@ -340,6 +366,10 @@ PHP_FUNCTION(round)
case PHP_ROUND_HALF_DOWN:
case PHP_ROUND_HALF_EVEN:
case PHP_ROUND_HALF_ODD:
case PHP_ROUND_AWAY_FROM_ZERO:
case PHP_ROUND_TOWARD_ZERO:
case PHP_ROUND_CEILING:
case PHP_ROUND_FLOOR:
break;
default:
zend_argument_value_error(3, "must be a valid rounding mode (PHP_ROUND_*)");
Expand Down
18 changes: 17 additions & 1 deletion ext/standard/php_math.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ PHPAPI zend_string * _php_math_zvaltobase(zval *arg, int base);
#endif

#ifndef PHP_ROUND_HALF_DOWN
#define PHP_ROUND_HALF_DOWN 0x02 /* Down == towards zero */
#define PHP_ROUND_HALF_DOWN 0x02 /* Arithmetic rounding, down == towards zero */
#endif

#ifndef PHP_ROUND_HALF_EVEN
Expand All @@ -114,4 +114,20 @@ PHPAPI zend_string * _php_math_zvaltobase(zval *arg, int base);
#define PHP_ROUND_HALF_ODD 0x04
#endif

#ifndef PHP_ROUND_CEILING
#define PHP_ROUND_CEILING 0x05
#endif

#ifndef PHP_ROUND_FLOOR
#define PHP_ROUND_FLOOR 0x06
#endif

#ifndef PHP_ROUND_TOWARD_ZERO
#define PHP_ROUND_TOWARD_ZERO 0x07
#endif

#ifndef PHP_ROUND_AWAY_FROM_ZERO
#define PHP_ROUND_AWAY_FROM_ZERO 0x08
#endif

#endif /* PHP_MATH_H */
Loading