@@ -46,21 +46,32 @@ static inline double php_intpow10(int power) {
46
46
}
47
47
/* }}} */
48
48
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
+
49
65
/* {{{ php_round_helper
50
66
Actually performs the rounding of a value to integer in a certain mode */
51
67
static inline double php_round_helper (double adjusted_value , double value , double exponent , int mode ) {
52
68
double integral = adjusted_value >= 0.0 ? floor (adjusted_value ) : ceil (adjusted_value );
53
69
double value_abs = fabs (value );
54
70
double edge_case ;
55
71
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
-
62
72
switch (mode ) {
63
73
case PHP_ROUND_HALF_UP :
74
+ PHP_ROUND_GET_EDGE_CASE (adjusted_value , value_abs , integral , exponent );
64
75
if (value_abs >= edge_case ) {
65
76
/* We must increase the magnitude of the integral part
66
77
* (rounding up / towards infinity). copysign(1.0, integral)
@@ -76,21 +87,24 @@ static inline double php_round_helper(double adjusted_value, double value, doubl
76
87
return integral ;
77
88
78
89
case PHP_ROUND_HALF_DOWN :
90
+ PHP_ROUND_GET_EDGE_CASE (adjusted_value , value_abs , integral , exponent );
79
91
if (value_abs > edge_case ) {
80
92
return integral + copysign (1.0 , integral );
81
93
}
82
94
83
95
return integral ;
84
96
85
97
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 ) {
87
100
return integral + 1.0 ;
88
101
}
89
102
90
103
return integral ;
91
104
92
105
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 ) {
94
108
return integral - 1.0 ;
95
109
}
96
110
@@ -100,13 +114,15 @@ static inline double php_round_helper(double adjusted_value, double value, doubl
100
114
return integral ;
101
115
102
116
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 ) {
104
119
return integral + copysign (1.0 , integral );
105
120
}
106
121
107
122
return integral ;
108
123
109
124
case PHP_ROUND_HALF_EVEN :
125
+ PHP_ROUND_GET_EDGE_CASE (adjusted_value , value_abs , integral , exponent );
110
126
if (value_abs > edge_case ) {
111
127
return integral + copysign (1.0 , integral );
112
128
} else if (UNEXPECTED (value_abs == edge_case )) {
@@ -123,6 +139,7 @@ static inline double php_round_helper(double adjusted_value, double value, doubl
123
139
return integral ;
124
140
125
141
case PHP_ROUND_HALF_ODD :
142
+ PHP_ROUND_GET_EDGE_CASE (adjusted_value , value_abs , integral , exponent );
126
143
if (value_abs > edge_case ) {
127
144
return integral + copysign (1.0 , integral );
128
145
} else if (UNEXPECTED (value_abs == edge_case )) {
0 commit comments