Skip to content

Commit 1b41af8

Browse files
committed
Compatible with new modes
1 parent 5bfcbe5 commit 1b41af8

File tree

1 file changed

+26
-9
lines changed

1 file changed

+26
-9
lines changed

ext/standard/math.c

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,21 +46,32 @@ static inline double php_intpow10(int power) {
4646
}
4747
/* }}} */
4848

49+
#define PHP_ROUND_GET_EDGE_CASE(adjusted_value, value_abs, integral, exponent) do {\
50+
if (fabs(adjusted_value) >= value_abs) {\
51+
edge_case = fabs((integral + copysign(0.5, integral)) / exponent);\
52+
} else {\
53+
edge_case = fabs((integral + copysign(0.5, integral)) * exponent);\
54+
}\
55+
} while(0);
56+
57+
#define PHP_ROUND_GET_ZERO_EDGE_CASE(adjusted_value, value_abs, integral, exponent) do {\
58+
if (fabs(adjusted_value) >= value_abs) {\
59+
edge_case = fabs((integral) / exponent);\
60+
} else {\
61+
edge_case = fabs((integral) * exponent);\
62+
}\
63+
} while(0);
64+
4965
/* {{{ php_round_helper
5066
Actually performs the rounding of a value to integer in a certain mode */
5167
static inline double php_round_helper(double adjusted_value, double value, double exponent, int mode) {
5268
double integral = adjusted_value >= 0.0 ? floor(adjusted_value) : ceil(adjusted_value);
5369
double value_abs = fabs(value);
5470
double edge_case;
5571

56-
if (fabs(adjusted_value) >= value_abs) {
57-
edge_case = fabs((integral + copysign(0.5, integral)) / exponent);
58-
} else {
59-
edge_case = fabs((integral + copysign(0.5, integral)) * exponent);
60-
}
61-
6272
switch (mode) {
6373
case PHP_ROUND_HALF_UP:
74+
PHP_ROUND_GET_EDGE_CASE(adjusted_value, value_abs, integral, exponent);
6475
if (value_abs >= edge_case) {
6576
/* We must increase the magnitude of the integral part
6677
* (rounding up / towards infinity). copysign(1.0, integral)
@@ -76,21 +87,24 @@ static inline double php_round_helper(double adjusted_value, double value, doubl
7687
return integral;
7788

7889
case PHP_ROUND_HALF_DOWN:
90+
PHP_ROUND_GET_EDGE_CASE(adjusted_value, value_abs, integral, exponent);
7991
if (value_abs > edge_case) {
8092
return integral + copysign(1.0, integral);
8193
}
8294

8395
return integral;
8496

8597
case PHP_ROUND_CEILING:
86-
if (value > 0.0 && fractional > 0.0) {
98+
PHP_ROUND_GET_ZERO_EDGE_CASE(adjusted_value, value_abs, integral, exponent);
99+
if (value > 0.0 && value_abs > edge_case) {
87100
return integral + 1.0;
88101
}
89102

90103
return integral;
91104

92105
case PHP_ROUND_FLOOR:
93-
if (value < 0.0 && fractional > 0.0) {
106+
PHP_ROUND_GET_ZERO_EDGE_CASE(adjusted_value, value_abs, integral, exponent);
107+
if (value < 0.0 && value_abs > edge_case) {
94108
return integral - 1.0;
95109
}
96110

@@ -100,13 +114,15 @@ static inline double php_round_helper(double adjusted_value, double value, doubl
100114
return integral;
101115

102116
case PHP_ROUND_AWAY_FROM_ZERO:
103-
if (fractional > 0.0) {
117+
PHP_ROUND_GET_ZERO_EDGE_CASE(adjusted_value, value_abs, integral, exponent);
118+
if (value_abs > edge_case) {
104119
return integral + copysign(1.0, integral);
105120
}
106121

107122
return integral;
108123

109124
case PHP_ROUND_HALF_EVEN:
125+
PHP_ROUND_GET_EDGE_CASE(adjusted_value, value_abs, integral, exponent);
110126
if (value_abs > edge_case) {
111127
return integral + copysign(1.0, integral);
112128
} else if (UNEXPECTED(value_abs == edge_case)) {
@@ -123,6 +139,7 @@ static inline double php_round_helper(double adjusted_value, double value, doubl
123139
return integral;
124140

125141
case PHP_ROUND_HALF_ODD:
142+
PHP_ROUND_GET_EDGE_CASE(adjusted_value, value_abs, integral, exponent);
126143
if (value_abs > edge_case) {
127144
return integral + copysign(1.0, integral);
128145
} else if (UNEXPECTED(value_abs == edge_case)) {

0 commit comments

Comments
 (0)