Skip to content

Commit 94ddc74

Browse files
jorgsowaTimWolla
andauthored
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 <[email protected]>
1 parent 9267ebc commit 94ddc74

12 files changed

+1025
-22
lines changed

NEWS

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ Intl:
3030
. Added IntlDateFormatter::PATTERN constant. (David Carlier)
3131
. Fixed Numberformatter::__construct when the locale is invalid, now
3232
throws an exception. (David Carlier)
33+
. Added NumberFormatter::ROUND_TOWARD_ZERO and ::ROUND_AWAY_FROM_ZERO as
34+
aliases for ::ROUND_DOWN and ::ROUND_UP. (Jorg Sowa)
3335

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

111114
XML:
112115
. Added XML_OPTION_PARSE_HUGE parser option. (nielsdos)

UPGRADING

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,11 @@ PHP 8.4 UPGRADE NOTES
216216
- Intl:
217217
. IntlDateFormatter::__construct() throws a ValueError if the locale is invalid.
218218
. NumberFormatter::__construct() throws a ValueError if the locale is invalid.
219+
. NumberFormatter::ROUND_TOWARD_ZERO and NumberFormatter::ROUND_AWAY_FROM_ZERO
220+
have been added as aliases for NumberFormatter::ROUND_DOWN and
221+
NumberFormatter::ROUND_UP to be consistent with the new PHP_ROUND_* modes.
222+
223+
RFC: https://wiki.php.net/rfc/new_rounding_modes_to_round_function
219224

220225
- MBString:
221226
. 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
252257
has been increased from '10' to '12'.
253258

254259
RFC: https://wiki.php.net/rfc/bcrypt_cost_2023
260+
. Four new modes have been added to the round() function: PHP_ROUND_CEILING,
261+
PHP_ROUND_FLOOR, PHP_ROUND_TOWARD_ZERO, PHP_ROUND_AWAY_FROM_ZERO.
262+
263+
RFC: https://wiki.php.net/rfc/new_rounding_modes_to_round_function
255264

256265
========================================
257266
6. New Functions

ext/intl/formatter/formatter.stub.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ class NumberFormatter
4444
public const int ROUND_DOWN = UNKNOWN;
4545
/** @cvalue UNUM_ROUND_UP */
4646
public const int ROUND_UP = UNKNOWN;
47+
/** @cvalue UNUM_ROUND_DOWN */
48+
public const int ROUND_TOWARD_ZERO = UNKNOWN;
49+
/** @cvalue UNUM_ROUND_UP */
50+
public const int ROUND_AWAY_FROM_ZERO = UNKNOWN;
4751
/** @cvalue UNUM_ROUND_HALFEVEN */
4852
public const int ROUND_HALFEVEN = UNKNOWN;
4953
/** @cvalue UNUM_ROUND_HALFDOWN */

ext/intl/formatter/formatter_arginfo.h

Lines changed: 13 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
NumberFormatter: rounding modes
3+
--EXTENSIONS--
4+
intl
5+
--FILE--
6+
<?php
7+
ini_set("intl.error_level", E_WARNING);
8+
9+
var_dump(NumberFormatter::ROUND_CEILING);
10+
var_dump(NumberFormatter::ROUND_FLOOR);
11+
var_dump(NumberFormatter::ROUND_DOWN);
12+
var_dump(NumberFormatter::ROUND_TOWARD_ZERO);
13+
var_dump(NumberFormatter::ROUND_UP);
14+
var_dump(NumberFormatter::ROUND_AWAY_FROM_ZERO);
15+
var_dump(NumberFormatter::ROUND_HALFEVEN);
16+
var_dump(NumberFormatter::ROUND_HALFDOWN);
17+
var_dump(NumberFormatter::ROUND_HALFUP);
18+
19+
var_dump(NumberFormatter::ROUND_DOWN === NumberFormatter::ROUND_TOWARD_ZERO);
20+
var_dump(NumberFormatter::ROUND_UP === NumberFormatter::ROUND_AWAY_FROM_ZERO);
21+
?>
22+
--EXPECTF--
23+
int(0)
24+
int(1)
25+
int(2)
26+
int(2)
27+
int(3)
28+
int(3)
29+
int(4)
30+
int(5)
31+
int(6)
32+
bool(true)
33+
bool(true)

ext/standard/basic_functions.stub.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,26 @@
375375
* @cvalue PHP_ROUND_HALF_ODD
376376
*/
377377
const PHP_ROUND_HALF_ODD = UNKNOWN;
378+
/**
379+
* @var int
380+
* @cvalue PHP_ROUND_CEILING
381+
*/
382+
const PHP_ROUND_CEILING = UNKNOWN;
383+
/**
384+
* @var int
385+
* @cvalue PHP_ROUND_FLOOR
386+
*/
387+
const PHP_ROUND_FLOOR = UNKNOWN;
388+
/**
389+
* @var int
390+
* @cvalue PHP_ROUND_TOWARD_ZERO
391+
*/
392+
const PHP_ROUND_TOWARD_ZERO = UNKNOWN;
393+
/**
394+
* @var int
395+
* @cvalue PHP_ROUND_AWAY_FROM_ZERO
396+
*/
397+
const PHP_ROUND_AWAY_FROM_ZERO = UNKNOWN;
378398

379399
/* crypt.c */
380400

ext/standard/basic_functions_arginfo.h

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

ext/standard/math.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,30 @@ static inline double php_round_helper(double value, int mode) {
126126

127127
return integral;
128128

129+
case PHP_ROUND_CEILING:
130+
if (value > 0.0 && fractional > 0.0) {
131+
return integral + 1.0;
132+
}
133+
134+
return integral;
135+
136+
case PHP_ROUND_FLOOR:
137+
if (value < 0.0 && fractional > 0.0) {
138+
return integral - 1.0;
139+
}
140+
141+
return integral;
142+
143+
case PHP_ROUND_TOWARD_ZERO:
144+
return integral;
145+
146+
case PHP_ROUND_AWAY_FROM_ZERO:
147+
if (fractional > 0.0) {
148+
return integral + copysign(1.0, integral);
149+
}
150+
151+
return integral;
152+
129153
case PHP_ROUND_HALF_EVEN:
130154
if (fractional > 0.5) {
131155
return integral + copysign(1.0, integral);
@@ -143,6 +167,7 @@ static inline double php_round_helper(double value, int mode) {
143167
}
144168

145169
return integral;
170+
146171
case PHP_ROUND_HALF_ODD:
147172
if (fractional > 0.5) {
148173
return integral + copysign(1.0, integral);
@@ -157,6 +182,7 @@ static inline double php_round_helper(double value, int mode) {
157182
}
158183

159184
return integral;
185+
160186
EMPTY_SWITCH_DEFAULT_CASE();
161187
}
162188
// FIXME: GCC bug, branch is considered reachable.
@@ -340,6 +366,10 @@ PHP_FUNCTION(round)
340366
case PHP_ROUND_HALF_DOWN:
341367
case PHP_ROUND_HALF_EVEN:
342368
case PHP_ROUND_HALF_ODD:
369+
case PHP_ROUND_AWAY_FROM_ZERO:
370+
case PHP_ROUND_TOWARD_ZERO:
371+
case PHP_ROUND_CEILING:
372+
case PHP_ROUND_FLOOR:
343373
break;
344374
default:
345375
zend_argument_value_error(3, "must be a valid rounding mode (PHP_ROUND_*)");

ext/standard/php_math.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ PHPAPI zend_string * _php_math_zvaltobase(zval *arg, int base);
103103
#endif
104104

105105
#ifndef PHP_ROUND_HALF_DOWN
106-
#define PHP_ROUND_HALF_DOWN 0x02 /* Down == towards zero */
106+
#define PHP_ROUND_HALF_DOWN 0x02 /* Arithmetic rounding, down == towards zero */
107107
#endif
108108

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

117+
#ifndef PHP_ROUND_CEILING
118+
#define PHP_ROUND_CEILING 0x05
119+
#endif
120+
121+
#ifndef PHP_ROUND_FLOOR
122+
#define PHP_ROUND_FLOOR 0x06
123+
#endif
124+
125+
#ifndef PHP_ROUND_TOWARD_ZERO
126+
#define PHP_ROUND_TOWARD_ZERO 0x07
127+
#endif
128+
129+
#ifndef PHP_ROUND_AWAY_FROM_ZERO
130+
#define PHP_ROUND_AWAY_FROM_ZERO 0x08
131+
#endif
132+
117133
#endif /* PHP_MATH_H */

0 commit comments

Comments
 (0)