diff --git a/NEWS b/NEWS index b815dd441ea2c..e6c3ea5522f97 100644 --- a/NEWS +++ b/NEWS @@ -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) diff --git a/UPGRADING b/UPGRADING index 27504fc5c9850..f202e8cb5399f 100644 --- a/UPGRADING +++ b/UPGRADING @@ -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 @@ -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 diff --git a/ext/intl/formatter/formatter.stub.php b/ext/intl/formatter/formatter.stub.php index 430c02bd60a67..4e31b7dc22c01 100644 --- a/ext/intl/formatter/formatter.stub.php +++ b/ext/intl/formatter/formatter.stub.php @@ -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 */ diff --git a/ext/intl/formatter/formatter_arginfo.h b/ext/intl/formatter/formatter_arginfo.h index 8d406350aef5f..fc50aadeb9496 100644 --- a/ext/intl/formatter/formatter_arginfo.h +++ b/ext/intl/formatter/formatter_arginfo.h @@ -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); diff --git a/ext/intl/tests/formatter/rounding_modes.phpt b/ext/intl/tests/formatter/rounding_modes.phpt new file mode 100644 index 0000000000000..9edde4ac7fbd6 --- /dev/null +++ b/ext/intl/tests/formatter/rounding_modes.phpt @@ -0,0 +1,33 @@ +--TEST-- +NumberFormatter: rounding modes +--EXTENSIONS-- +intl +--FILE-- + +--EXPECTF-- +int(0) +int(1) +int(2) +int(2) +int(3) +int(3) +int(4) +int(5) +int(6) +bool(true) +bool(true) diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 8592d7c0b8810..851fc0ade4191 100755 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -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 */ diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 48202e78079ac..966ab01b0f73b 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -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); diff --git a/ext/standard/math.c b/ext/standard/math.c index 377c573033f69..4ee5f9482909d 100644 --- a/ext/standard/math.c +++ b/ext/standard/math.c @@ -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_*)"); diff --git a/ext/standard/php_math.h b/ext/standard/php_math.h index 1cdba0fe9d0a6..6ff895cce3c8d 100644 --- a/ext/standard/php_math.h +++ b/ext/standard/php_math.h @@ -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 */ diff --git a/ext/standard/tests/math/round_modes.phpt b/ext/standard/tests/math/round_modes.phpt index 61a697bc2d73b..06a793211b3a7 100644 --- a/ext/standard/tests/math/round_modes.phpt +++ b/ext/standard/tests/math/round_modes.phpt @@ -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,12 +422,320 @@ 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.65 => 0.65 + -0.65 => -0.65 + 1.9999 => 2 + -1.9999 => -2 + 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_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 => 0 + 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 @@ -278,9 +745,115 @@ 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.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 => 0 + 0.65 => 0.65 + -0.65 => -0.65 1.9999 => 1.9999 -1.9999 => -1.9999 0.0001 => 0.0001 diff --git a/ext/standard/tests/math/round_modes_ceiling_and_floor.phpt b/ext/standard/tests/math/round_modes_ceiling_and_floor.phpt new file mode 100644 index 0000000000000..1b3a34f0f98ec --- /dev/null +++ b/ext/standard/tests/math/round_modes_ceiling_and_floor.phpt @@ -0,0 +1,69 @@ +--TEST-- +round() with modes PHP_ROUND_CEILING and PHP_ROUND_FLOOR +--FILE-- + +--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) diff --git a/ext/standard/tests/math/round_modes_zeros.phpt b/ext/standard/tests/math/round_modes_zeros.phpt new file mode 100644 index 0000000000000..cdf97395dd9bf --- /dev/null +++ b/ext/standard/tests/math/round_modes_zeros.phpt @@ -0,0 +1,230 @@ +--TEST-- +round() with different rounding modes for zeros +--FILE-- + 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