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

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

Co-authored-by: Tim Düsterhus <tim@bastelstu.be>
This commit is contained in:
Jorg Adam Sowa 2023-12-21 13:28:05 +01:00 committed by GitHub
parent 9267ebccfc
commit 94ddc74c9a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 1025 additions and 22 deletions

5
NEWS
View File

@ -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)
@ -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)

View File

@ -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
@ -252,6 +257,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

View File

@ -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 */

View File

@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 6178ab530b85aca5c90fb7369c5019bb5cbfe8a7 */
* Stub hash: 5d5421c72894a77894872efdf060ec058d275c13 */
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_NumberFormatter___construct, 0, 0, 2)
ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 0)
@ -226,6 +226,18 @@ static zend_class_entry *register_class_NumberFormatter(void)
zend_declare_typed_class_constant(class_entry, const_ROUND_UP_name, &const_ROUND_UP_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
zend_string_release(const_ROUND_UP_name);
zval const_ROUND_TOWARD_ZERO_value;
ZVAL_LONG(&const_ROUND_TOWARD_ZERO_value, UNUM_ROUND_DOWN);
zend_string *const_ROUND_TOWARD_ZERO_name = zend_string_init_interned("ROUND_TOWARD_ZERO", sizeof("ROUND_TOWARD_ZERO") - 1, 1);
zend_declare_typed_class_constant(class_entry, const_ROUND_TOWARD_ZERO_name, &const_ROUND_TOWARD_ZERO_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
zend_string_release(const_ROUND_TOWARD_ZERO_name);
zval const_ROUND_AWAY_FROM_ZERO_value;
ZVAL_LONG(&const_ROUND_AWAY_FROM_ZERO_value, UNUM_ROUND_UP);
zend_string *const_ROUND_AWAY_FROM_ZERO_name = zend_string_init_interned("ROUND_AWAY_FROM_ZERO", sizeof("ROUND_AWAY_FROM_ZERO") - 1, 1);
zend_declare_typed_class_constant(class_entry, const_ROUND_AWAY_FROM_ZERO_name, &const_ROUND_AWAY_FROM_ZERO_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG));
zend_string_release(const_ROUND_AWAY_FROM_ZERO_name);
zval const_ROUND_HALFEVEN_value;
ZVAL_LONG(&const_ROUND_HALFEVEN_value, UNUM_ROUND_HALFEVEN);
zend_string *const_ROUND_HALFEVEN_name = zend_string_init_interned("ROUND_HALFEVEN", sizeof("ROUND_HALFEVEN") - 1, 1);

View File

@ -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)

View File

@ -375,6 +375,26 @@ const PHP_ROUND_HALF_EVEN = UNKNOWN;
* @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 */

View File

@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: c9edbe45bb7a2b00b413fb3c56683bb8377a725f */
* Stub hash: 7b14f7e9eb57bc1f2aff20097fddd14d1fe0494e */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0)
ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0)
@ -3569,6 +3569,10 @@ static void register_basic_functions_symbols(int module_number)
REGISTER_LONG_CONSTANT("PHP_ROUND_HALF_DOWN", PHP_ROUND_HALF_DOWN, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PHP_ROUND_HALF_EVEN", PHP_ROUND_HALF_EVEN, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PHP_ROUND_HALF_ODD", PHP_ROUND_HALF_ODD, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PHP_ROUND_CEILING", PHP_ROUND_CEILING, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PHP_ROUND_FLOOR", PHP_ROUND_FLOOR, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PHP_ROUND_TOWARD_ZERO", PHP_ROUND_TOWARD_ZERO, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PHP_ROUND_AWAY_FROM_ZERO", PHP_ROUND_AWAY_FROM_ZERO, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("CRYPT_SALT_LENGTH", PHP_MAX_SALT_LEN, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("CRYPT_STD_DES", 1, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("CRYPT_EXT_DES", 1, CONST_PERSISTENT);

View File

@ -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);
@ -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);
@ -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.
@ -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_*)");

View File

@ -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
@ -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 */

View File

@ -7,6 +7,10 @@ $modes = [
"PHP_ROUND_HALF_DOWN" => PHP_ROUND_HALF_DOWN,
"PHP_ROUND_HALF_EVEN" => PHP_ROUND_HALF_EVEN,
"PHP_ROUND_HALF_ODD" => PHP_ROUND_HALF_ODD,
"PHP_ROUND_CEILING" => PHP_ROUND_CEILING,
"PHP_ROUND_FLOOR" => PHP_ROUND_FLOOR,
"PHP_ROUND_TOWARD_ZERO" => PHP_ROUND_TOWARD_ZERO,
"PHP_ROUND_AWAY_FROM_ZERO" => PHP_ROUND_AWAY_FROM_ZERO,
];
$numbers = [
@ -16,15 +20,20 @@ $numbers = [
-3.5,
7,
-7,
15.51,
-15.51,
5,
-5,
0.61,
0.69,
0,
0.65,
-0.65,
1.9999,
-1.9999,
0.0001,
-0.0001,
];
$precisions = [0, 1, 2, 10];
$precisions = [-1, 0, 1, 2, 10];
foreach ($modes as $modeKey => $mode) {
echo "mode: $modeKey\n";
@ -43,6 +52,26 @@ foreach ($modes as $modeKey => $mode) {
?>
--EXPECT--
mode: PHP_ROUND_HALF_UP
precision: -1
2.5 => 0
-2.5 => -0
3.5 => 0
-3.5 => -0
7 => 10
-7 => -10
15.51 => 20
-15.51 => -20
5 => 10
-5 => -10
0.61 => 0
0.69 => 0
0.65 => 0
-0.65 => -0
1.9999 => 0
-1.9999 => -0
0.0001 => 0
-0.0001 => -0
precision: 0
2.5 => 3
-2.5 => -3
@ -50,9 +79,14 @@ mode: PHP_ROUND_HALF_UP
-3.5 => -4
7 => 7
-7 => -7
15.51 => 16
-15.51 => -16
5 => 5
-5 => -5
0.61 => 1
0.69 => 1
0 => 0
0.65 => 1
-0.65 => -1
1.9999 => 2
-1.9999 => -2
0.0001 => 0
@ -65,9 +99,14 @@ mode: PHP_ROUND_HALF_UP
-3.5 => -3.5
7 => 7
-7 => -7
15.51 => 15.5
-15.51 => -15.5
5 => 5
-5 => -5
0.61 => 0.6
0.69 => 0.7
0 => 0
0.65 => 0.7
-0.65 => -0.7
1.9999 => 2
-1.9999 => -2
0.0001 => 0
@ -80,9 +119,14 @@ mode: PHP_ROUND_HALF_UP
-3.5 => -3.5
7 => 7
-7 => -7
15.51 => 15.51
-15.51 => -15.51
5 => 5
-5 => -5
0.61 => 0.61
0.69 => 0.69
0 => 0
0.65 => 0.65
-0.65 => -0.65
1.9999 => 2
-1.9999 => -2
0.0001 => 0
@ -95,15 +139,40 @@ mode: PHP_ROUND_HALF_UP
-3.5 => -3.5
7 => 7
-7 => -7
15.51 => 15.51
-15.51 => -15.51
5 => 5
-5 => -5
0.61 => 0.61
0.69 => 0.69
0 => 0
0.65 => 0.65
-0.65 => -0.65
1.9999 => 1.9999
-1.9999 => -1.9999
0.0001 => 0.0001
-0.0001 => -0.0001
mode: PHP_ROUND_HALF_DOWN
precision: -1
2.5 => 0
-2.5 => -0
3.5 => 0
-3.5 => -0
7 => 10
-7 => -10
15.51 => 20
-15.51 => -20
5 => 0
-5 => -0
0.61 => 0
0.69 => 0
0.65 => 0
-0.65 => -0
1.9999 => 0
-1.9999 => -0
0.0001 => 0
-0.0001 => -0
precision: 0
2.5 => 2
-2.5 => -2
@ -111,9 +180,14 @@ mode: PHP_ROUND_HALF_DOWN
-3.5 => -3
7 => 7
-7 => -7
15.51 => 16
-15.51 => -16
5 => 5
-5 => -5
0.61 => 1
0.69 => 1
0 => 0
0.65 => 1
-0.65 => -1
1.9999 => 2
-1.9999 => -2
0.0001 => 0
@ -126,9 +200,14 @@ mode: PHP_ROUND_HALF_DOWN
-3.5 => -3.5
7 => 7
-7 => -7
15.51 => 15.5
-15.51 => -15.5
5 => 5
-5 => -5
0.61 => 0.6
0.69 => 0.7
0 => 0
0.65 => 0.6
-0.65 => -0.6
1.9999 => 2
-1.9999 => -2
0.0001 => 0
@ -141,9 +220,14 @@ mode: PHP_ROUND_HALF_DOWN
-3.5 => -3.5
7 => 7
-7 => -7
15.51 => 15.51
-15.51 => -15.51
5 => 5
-5 => -5
0.61 => 0.61
0.69 => 0.69
0 => 0
0.65 => 0.65
-0.65 => -0.65
1.9999 => 2
-1.9999 => -2
0.0001 => 0
@ -156,15 +240,40 @@ mode: PHP_ROUND_HALF_DOWN
-3.5 => -3.5
7 => 7
-7 => -7
15.51 => 15.51
-15.51 => -15.51
5 => 5
-5 => -5
0.61 => 0.61
0.69 => 0.69
0 => 0
0.65 => 0.65
-0.65 => -0.65
1.9999 => 1.9999
-1.9999 => -1.9999
0.0001 => 0.0001
-0.0001 => -0.0001
mode: PHP_ROUND_HALF_EVEN
precision: -1
2.5 => 0
-2.5 => -0
3.5 => 0
-3.5 => -0
7 => 10
-7 => -10
15.51 => 20
-15.51 => -20
5 => 0
-5 => -0
0.61 => 0
0.69 => 0
0.65 => 0
-0.65 => -0
1.9999 => 0
-1.9999 => -0
0.0001 => 0
-0.0001 => -0
precision: 0
2.5 => 2
-2.5 => -2
@ -172,9 +281,14 @@ mode: PHP_ROUND_HALF_EVEN
-3.5 => -4
7 => 7
-7 => -7
15.51 => 16
-15.51 => -16
5 => 5
-5 => -5
0.61 => 1
0.69 => 1
0 => 0
0.65 => 1
-0.65 => -1
1.9999 => 2
-1.9999 => -2
0.0001 => 0
@ -187,9 +301,14 @@ mode: PHP_ROUND_HALF_EVEN
-3.5 => -3.5
7 => 7
-7 => -7
15.51 => 15.5
-15.51 => -15.5
5 => 5
-5 => -5
0.61 => 0.6
0.69 => 0.7
0 => 0
0.65 => 0.6
-0.65 => -0.6
1.9999 => 2
-1.9999 => -2
0.0001 => 0
@ -202,9 +321,14 @@ mode: PHP_ROUND_HALF_EVEN
-3.5 => -3.5
7 => 7
-7 => -7
15.51 => 15.51
-15.51 => -15.51
5 => 5
-5 => -5
0.61 => 0.61
0.69 => 0.69
0 => 0
0.65 => 0.65
-0.65 => -0.65
1.9999 => 2
-1.9999 => -2
0.0001 => 0
@ -217,15 +341,40 @@ mode: PHP_ROUND_HALF_EVEN
-3.5 => -3.5
7 => 7
-7 => -7
15.51 => 15.51
-15.51 => -15.51
5 => 5
-5 => -5
0.61 => 0.61
0.69 => 0.69
0 => 0
0.65 => 0.65
-0.65 => -0.65
1.9999 => 1.9999
-1.9999 => -1.9999
0.0001 => 0.0001
-0.0001 => -0.0001
mode: PHP_ROUND_HALF_ODD
precision: -1
2.5 => 0
-2.5 => -0
3.5 => 0
-3.5 => -0
7 => 10
-7 => -10
15.51 => 20
-15.51 => -20
5 => 10
-5 => -10
0.61 => 0
0.69 => 0
0.65 => 0
-0.65 => -0
1.9999 => 0
-1.9999 => -0
0.0001 => 0
-0.0001 => -0
precision: 0
2.5 => 3
-2.5 => -3
@ -233,9 +382,14 @@ mode: PHP_ROUND_HALF_ODD
-3.5 => -3
7 => 7
-7 => -7
15.51 => 16
-15.51 => -16
5 => 5
-5 => -5
0.61 => 1
0.69 => 1
0 => 0
0.65 => 1
-0.65 => -1
1.9999 => 2
-1.9999 => -2
0.0001 => 0
@ -248,9 +402,14 @@ mode: PHP_ROUND_HALF_ODD
-3.5 => -3.5
7 => 7
-7 => -7
15.51 => 15.5
-15.51 => -15.5
5 => 5
-5 => -5
0.61 => 0.6
0.69 => 0.7
0 => 0
0.65 => 0.7
-0.65 => -0.7
1.9999 => 2
-1.9999 => -2
0.0001 => 0
@ -263,9 +422,14 @@ mode: PHP_ROUND_HALF_ODD
-3.5 => -3.5
7 => 7
-7 => -7
15.51 => 15.51
-15.51 => -15.51
5 => 5
-5 => -5
0.61 => 0.61
0.69 => 0.69
0 => 0
0.65 => 0.65
-0.65 => -0.65
1.9999 => 2
-1.9999 => -2
0.0001 => 0
@ -278,9 +442,418 @@ mode: PHP_ROUND_HALF_ODD
-3.5 => -3.5
7 => 7
-7 => -7
15.51 => 15.51
-15.51 => -15.51
5 => 5
-5 => -5
0.61 => 0.61
0.69 => 0.69
0 => 0
0.65 => 0.65
-0.65 => -0.65
1.9999 => 1.9999
-1.9999 => -1.9999
0.0001 => 0.0001
-0.0001 => -0.0001
mode: PHP_ROUND_CEILING
precision: -1
2.5 => 10
-2.5 => -0
3.5 => 10
-3.5 => -0
7 => 10
-7 => -0
15.51 => 20
-15.51 => -10
5 => 10
-5 => -0
0.61 => 10
0.69 => 10
0.65 => 10
-0.65 => -0
1.9999 => 10
-1.9999 => -0
0.0001 => 10
-0.0001 => -0
precision: 0
2.5 => 3
-2.5 => -2
3.5 => 4
-3.5 => -3
7 => 7
-7 => -7
15.51 => 16
-15.51 => -15
5 => 5
-5 => -5
0.61 => 1
0.69 => 1
0.65 => 1
-0.65 => -0
1.9999 => 2
-1.9999 => -1
0.0001 => 1
-0.0001 => -0
precision: 1
2.5 => 2.5
-2.5 => -2.5
3.5 => 3.5
-3.5 => -3.5
7 => 7
-7 => -7
15.51 => 15.6
-15.51 => -15.5
5 => 5
-5 => -5
0.61 => 0.7
0.69 => 0.7
0.65 => 0.7
-0.65 => -0.6
1.9999 => 2
-1.9999 => -1.9
0.0001 => 0.1
-0.0001 => -0
precision: 2
2.5 => 2.5
-2.5 => -2.5
3.5 => 3.5
-3.5 => -3.5
7 => 7
-7 => -7
15.51 => 15.51
-15.51 => -15.51
5 => 5
-5 => -5
0.61 => 0.61
0.69 => 0.69
0.65 => 0.65
-0.65 => -0.65
1.9999 => 2
-1.9999 => -1.99
0.0001 => 0.01
-0.0001 => -0
precision: 10
2.5 => 2.5
-2.5 => -2.5
3.5 => 3.5
-3.5 => -3.5
7 => 7
-7 => -7
15.51 => 15.51
-15.51 => -15.51
5 => 5
-5 => -5
0.61 => 0.61
0.69 => 0.69
0.65 => 0.65
-0.65 => -0.65
1.9999 => 1.9999
-1.9999 => -1.9999
0.0001 => 0.0001
-0.0001 => -0.0001
mode: PHP_ROUND_FLOOR
precision: -1
2.5 => 0
-2.5 => -10
3.5 => 0
-3.5 => -10
7 => 0
-7 => -10
15.51 => 10
-15.51 => -20
5 => 0
-5 => -10
0.61 => 0
0.69 => 0
0.65 => 0
-0.65 => -10
1.9999 => 0
-1.9999 => -10
0.0001 => 0
-0.0001 => -10
precision: 0
2.5 => 2
-2.5 => -3
3.5 => 3
-3.5 => -4
7 => 7
-7 => -7
15.51 => 15
-15.51 => -16
5 => 5
-5 => -5
0.61 => 0
0.69 => 0
0.65 => 0
-0.65 => -1
1.9999 => 1
-1.9999 => -2
0.0001 => 0
-0.0001 => -1
precision: 1
2.5 => 2.5
-2.5 => -2.5
3.5 => 3.5
-3.5 => -3.5
7 => 7
-7 => -7
15.51 => 15.5
-15.51 => -15.6
5 => 5
-5 => -5
0.61 => 0.6
0.69 => 0.6
0.65 => 0.6
-0.65 => -0.7
1.9999 => 1.9
-1.9999 => -2
0.0001 => 0
-0.0001 => -0.1
precision: 2
2.5 => 2.5
-2.5 => -2.5
3.5 => 3.5
-3.5 => -3.5
7 => 7
-7 => -7
15.51 => 15.51
-15.51 => -15.51
5 => 5
-5 => -5
0.61 => 0.61
0.69 => 0.69
0.65 => 0.65
-0.65 => -0.65
1.9999 => 1.99
-1.9999 => -2
0.0001 => 0
-0.0001 => -0.01
precision: 10
2.5 => 2.5
-2.5 => -2.5
3.5 => 3.5
-3.5 => -3.5
7 => 7
-7 => -7
15.51 => 15.51
-15.51 => -15.51
5 => 5
-5 => -5
0.61 => 0.61
0.69 => 0.69
0.65 => 0.65
-0.65 => -0.65
1.9999 => 1.9999
-1.9999 => -1.9999
0.0001 => 0.0001
-0.0001 => -0.0001
mode: PHP_ROUND_TOWARD_ZERO
precision: -1
2.5 => 0
-2.5 => -0
3.5 => 0
-3.5 => -0
7 => 0
-7 => -0
15.51 => 10
-15.51 => -10
5 => 0
-5 => -0
0.61 => 0
0.69 => 0
0.65 => 0
-0.65 => -0
1.9999 => 0
-1.9999 => -0
0.0001 => 0
-0.0001 => -0
precision: 0
2.5 => 2
-2.5 => -2
3.5 => 3
-3.5 => -3
7 => 7
-7 => -7
15.51 => 15
-15.51 => -15
5 => 5
-5 => -5
0.61 => 0
0.69 => 0
0.65 => 0
-0.65 => -0
1.9999 => 1
-1.9999 => -1
0.0001 => 0
-0.0001 => -0
precision: 1
2.5 => 2.5
-2.5 => -2.5
3.5 => 3.5
-3.5 => -3.5
7 => 7
-7 => -7
15.51 => 15.5
-15.51 => -15.5
5 => 5
-5 => -5
0.61 => 0.6
0.69 => 0.6
0.65 => 0.6
-0.65 => -0.6
1.9999 => 1.9
-1.9999 => -1.9
0.0001 => 0
-0.0001 => -0
precision: 2
2.5 => 2.5
-2.5 => -2.5
3.5 => 3.5
-3.5 => -3.5
7 => 7
-7 => -7
15.51 => 15.51
-15.51 => -15.51
5 => 5
-5 => -5
0.61 => 0.61
0.69 => 0.69
0.65 => 0.65
-0.65 => -0.65
1.9999 => 1.99
-1.9999 => -1.99
0.0001 => 0
-0.0001 => -0
precision: 10
2.5 => 2.5
-2.5 => -2.5
3.5 => 3.5
-3.5 => -3.5
7 => 7
-7 => -7
15.51 => 15.51
-15.51 => -15.51
5 => 5
-5 => -5
0.61 => 0.61
0.69 => 0.69
0.65 => 0.65
-0.65 => -0.65
1.9999 => 1.9999
-1.9999 => -1.9999
0.0001 => 0.0001
-0.0001 => -0.0001
mode: PHP_ROUND_AWAY_FROM_ZERO
precision: -1
2.5 => 10
-2.5 => -10
3.5 => 10
-3.5 => -10
7 => 10
-7 => -10
15.51 => 20
-15.51 => -20
5 => 10
-5 => -10
0.61 => 10
0.69 => 10
0.65 => 10
-0.65 => -10
1.9999 => 10
-1.9999 => -10
0.0001 => 10
-0.0001 => -10
precision: 0
2.5 => 3
-2.5 => -3
3.5 => 4
-3.5 => -4
7 => 7
-7 => -7
15.51 => 16
-15.51 => -16
5 => 5
-5 => -5
0.61 => 1
0.69 => 1
0.65 => 1
-0.65 => -1
1.9999 => 2
-1.9999 => -2
0.0001 => 1
-0.0001 => -1
precision: 1
2.5 => 2.5
-2.5 => -2.5
3.5 => 3.5
-3.5 => -3.5
7 => 7
-7 => -7
15.51 => 15.6
-15.51 => -15.6
5 => 5
-5 => -5
0.61 => 0.7
0.69 => 0.7
0.65 => 0.7
-0.65 => -0.7
1.9999 => 2
-1.9999 => -2
0.0001 => 0.1
-0.0001 => -0.1
precision: 2
2.5 => 2.5
-2.5 => -2.5
3.5 => 3.5
-3.5 => -3.5
7 => 7
-7 => -7
15.51 => 15.51
-15.51 => -15.51
5 => 5
-5 => -5
0.61 => 0.61
0.69 => 0.69
0.65 => 0.65
-0.65 => -0.65
1.9999 => 2
-1.9999 => -2
0.0001 => 0.01
-0.0001 => -0.01
precision: 10
2.5 => 2.5
-2.5 => -2.5
3.5 => 3.5
-3.5 => -3.5
7 => 7
-7 => -7
15.51 => 15.51
-15.51 => -15.51
5 => 5
-5 => -5
0.61 => 0.61
0.69 => 0.69
0.65 => 0.65
-0.65 => -0.65
1.9999 => 1.9999
-1.9999 => -1.9999
0.0001 => 0.0001

View File

@ -0,0 +1,69 @@
--TEST--
round() with modes PHP_ROUND_CEILING and PHP_ROUND_FLOOR
--FILE--
<?php
$modes = [
PHP_ROUND_CEILING, PHP_ROUND_FLOOR,
];
$numbers = [
2.5,
-2.5,
3.5,
-3.5,
7,
-7,
0.61,
0.69,
0,
-0,
1.9999,
-1.9999,
0.0001,
-0.0001,
];
echo "mode PHP_ROUND_CEILING\n";
foreach($numbers as $number) {
var_dump(ceil($number) === round($number, 0, PHP_ROUND_CEILING));
}
echo "\n";
echo "mode PHP_ROUND_FLOOR\n";
foreach($numbers as $number) {
var_dump(floor($number) === round($number, 0, PHP_ROUND_FLOOR));
}
?>
--EXPECT--
mode PHP_ROUND_CEILING
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
mode PHP_ROUND_FLOOR
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)

View File

@ -0,0 +1,230 @@
--TEST--
round() with different rounding modes for zeros
--FILE--
<?php
$modes = [
"PHP_ROUND_HALF_UP" => PHP_ROUND_HALF_UP,
"PHP_ROUND_HALF_DOWN" => PHP_ROUND_HALF_DOWN,
"PHP_ROUND_HALF_EVEN" => PHP_ROUND_HALF_EVEN,
"PHP_ROUND_HALF_ODD" => PHP_ROUND_HALF_ODD,
"PHP_ROUND_CEILING" => PHP_ROUND_CEILING,
"PHP_ROUND_FLOOR" => PHP_ROUND_FLOOR,
"PHP_ROUND_TOWARD_ZERO" => PHP_ROUND_TOWARD_ZERO,
"PHP_ROUND_AWAY_FROM_ZERO" => PHP_ROUND_AWAY_FROM_ZERO,
];
$precisions = [-1, 0, 1, 2];
foreach ($modes as $modeKey => $mode) {
echo "mode: $modeKey\n";
foreach ($precisions as $precision) {
echo "\tprecision: $precision\n";
echo "\t\t 0 => " . round(0, $precision, $mode) . "\n";
echo "\t\t -0 => " . round(-0, $precision, $mode) . "\n";
echo "\t\t 0.0 => " . round(0.0, $precision, $mode) . "\n";
echo "\t\t -0.0 => " . round(-0.0, $precision, $mode) . "\n";
echo "\n";
}
}
?>
--EXPECT--
mode: PHP_ROUND_HALF_UP
precision: -1
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
precision: 0
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
precision: 1
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
precision: 2
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
mode: PHP_ROUND_HALF_DOWN
precision: -1
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
precision: 0
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
precision: 1
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
precision: 2
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
mode: PHP_ROUND_HALF_EVEN
precision: -1
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
precision: 0
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
precision: 1
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
precision: 2
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
mode: PHP_ROUND_HALF_ODD
precision: -1
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
precision: 0
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
precision: 1
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
precision: 2
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
mode: PHP_ROUND_CEILING
precision: -1
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
precision: 0
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
precision: 1
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
precision: 2
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
mode: PHP_ROUND_FLOOR
precision: -1
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
precision: 0
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
precision: 1
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
precision: 2
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
mode: PHP_ROUND_TOWARD_ZERO
precision: -1
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
precision: 0
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
precision: 1
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
precision: 2
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
mode: PHP_ROUND_AWAY_FROM_ZERO
precision: -1
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
precision: 0
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
precision: 1
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0
precision: 2
0 => 0
-0 => 0
0.0 => 0
-0.0 => -0