Skip to content

Commit 3116fd0

Browse files
committed
Add 4 new rounding modes to round() function
1 parent 4dea42a commit 3116fd0

File tree

6 files changed

+428
-18
lines changed

6 files changed

+428
-18
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? ????, PHP 8.4.0alpha1
44

5+
- Standard:
6+
. Added 4 new rounding modes to the round(). (Jorg Sowa)
7+
58
<<< NOTE: Insert NEWS from last stable release here prior to actual release! >>>

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: 69 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -95,22 +95,75 @@ static inline double php_intpow10(int power) {
9595
static inline double php_round_helper(double value, int mode) {
9696
double tmp_value;
9797

98-
if (value >= 0.0) {
99-
tmp_value = floor(value + 0.5);
100-
if ((mode == PHP_ROUND_HALF_DOWN && value == (-0.5 + tmp_value)) ||
101-
(mode == PHP_ROUND_HALF_EVEN && value == (0.5 + 2 * floor(tmp_value/2.0))) ||
102-
(mode == PHP_ROUND_HALF_ODD && value == (0.5 + 2 * floor(tmp_value/2.0) - 1.0)))
103-
{
104-
tmp_value = tmp_value - 1.0;
105-
}
106-
} else {
107-
tmp_value = ceil(value - 0.5);
108-
if ((mode == PHP_ROUND_HALF_DOWN && value == (0.5 + tmp_value)) ||
109-
(mode == PHP_ROUND_HALF_EVEN && value == (-0.5 + 2 * ceil(tmp_value/2.0))) ||
110-
(mode == PHP_ROUND_HALF_ODD && value == (-0.5 + 2 * ceil(tmp_value/2.0) + 1.0)))
111-
{
112-
tmp_value = tmp_value + 1.0;
113-
}
98+
switch (mode) {
99+
case PHP_ROUND_HALF_UP:
100+
if (value >= 0.0) {
101+
tmp_value = floor(value + 0.5);
102+
} else {
103+
tmp_value = ceil(value - 0.5);
104+
}
105+
break;
106+
case PHP_ROUND_HALF_DOWN:
107+
if (value >= 0.0 ) {
108+
tmp_value = floor(value + 0.5);
109+
if(value + 0.5 == tmp_value) {
110+
tmp_value = tmp_value - 1;
111+
}
112+
} else {
113+
tmp_value = ceil(value - 0.5);
114+
if(value - 0.5 == tmp_value) {
115+
tmp_value = tmp_value + 1.0;
116+
}
117+
}
118+
break;
119+
case PHP_ROUND_CEILING:
120+
tmp_value = ceil(value);
121+
break;
122+
case PHP_ROUND_FLOOR:
123+
tmp_value = floor(value);
124+
break;
125+
case PHP_ROUND_TOWARD_ZERO:
126+
if (value >= 0.0) {
127+
tmp_value = floor(value);
128+
} else {
129+
tmp_value = ceil(value);
130+
}
131+
break;
132+
case PHP_ROUND_AWAY_FROM_ZERO:
133+
if (value >= 0.0) {
134+
tmp_value = ceil(value);
135+
} else {
136+
tmp_value = floor(value);
137+
}
138+
break;
139+
case PHP_ROUND_HALF_EVEN:
140+
if (value >= 0.0) {
141+
tmp_value = floor(value + 0.5);
142+
if (value == (0.5 + 2 * floor(tmp_value / 2.0))) {
143+
tmp_value = tmp_value - 1.0;
144+
}
145+
} else {
146+
tmp_value = ceil(value - 0.5);
147+
if (value == (-0.5 + 2 * ceil(tmp_value / 2.0))) {
148+
tmp_value = tmp_value + 1.0;
149+
}
150+
}
151+
break;
152+
case PHP_ROUND_HALF_ODD:
153+
if(value >= 0.0) {
154+
tmp_value = floor(value + 0.5);
155+
if (value == (-0.5 + 2 * floor(tmp_value/2.0))) {
156+
tmp_value = tmp_value - 1.0;
157+
}
158+
} else {
159+
tmp_value = ceil(value - 0.5);
160+
if (value == (0.5 + 2 * ceil(tmp_value/2.0))) {
161+
tmp_value = tmp_value + 1.0;
162+
}
163+
}
164+
break;
165+
default:
166+
ZEND_ASSERT(0 && "Unexpected type");
114167
}
115168

116169
return tmp_value;

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)