@@ -93,19 +93,19 @@ static inline double php_intpow10(int power) {
93
93
/* {{{ php_round_helper
94
94
Actually performs the rounding of a value to integer in a certain mode */
95
95
static inline double php_round_helper (double value , int mode ) {
96
- double integral , fractional ;
97
96
98
97
/* Split the input value into the integral and fractional part.
99
98
*
100
99
* Both parts will have the same sign as the input value. We take
101
100
* the absolute value of the fractional part (which will not result
102
101
* in branches in the assembly) to make the following cases simpler.
103
102
*/
103
+ double integral ;
104
+ double fractional = modf (value , & integral );
104
105
105
106
switch (mode ) {
106
107
case PHP_ROUND_HALF_UP :
107
- fractional = fabs (modf (value , & integral ));
108
- if (fractional >= 0.5 ) {
108
+ if (fractional >= 0.5 || fractional <= -0.5 ) {
109
109
/* We must increase the magnitude of the integral part
110
110
* (rounding up / towards infinity). copysign(1.0, integral)
111
111
* will either result in 1.0 or -1.0 depending on the sign
@@ -120,40 +120,36 @@ static inline double php_round_helper(double value, int mode) {
120
120
return integral ;
121
121
122
122
case PHP_ROUND_HALF_DOWN :
123
- fractional = fabs (modf (value , & integral ));
124
- if (fractional > 0.5 ) {
123
+ if (fractional > 0.5 || fractional < -0.5 ) {
125
124
return integral + copysign (1.0 , integral );
126
125
}
127
126
128
127
return integral ;
129
128
130
129
case PHP_ROUND_CEILING :
131
- return ceil (value );
130
+ if (value > 0.0 ) {
131
+ return fractional == 0 ? integral : integral + 1.0 ;
132
+ }
133
+ return integral ;
132
134
133
135
case PHP_ROUND_FLOOR :
134
- return floor (value );
136
+ if (value < 0.0 ) {
137
+ return fractional == 0 ? integral : integral - 1.0 ;
138
+ }
139
+ return integral ;
135
140
136
141
case PHP_ROUND_TOWARD_ZERO :
137
- if (value >= 0.0 ) {
138
- return floor (value );
139
- } else {
140
- return ceil (value );
141
- }
142
+ return integral ;
142
143
143
144
case PHP_ROUND_AWAY_FROM_ZERO :
144
- if (value >= 0.0 ) {
145
- return ceil (value );
146
- } else {
147
- return floor (value );
148
- }
145
+ return fractional == 0 ? integral : integral + copysign (1.0 , integral );
149
146
150
147
case PHP_ROUND_HALF_EVEN :
151
- fractional = fabs (modf (value , & integral ));
152
- if (fractional > 0.5 ) {
148
+ if (fractional > 0.5 || fractional < -0.5 ) {
153
149
return integral + copysign (1.0 , integral );
154
150
}
155
151
156
- if (UNEXPECTED (fractional == 0.5 )) {
152
+ if (UNEXPECTED (fractional == 0.5 || fractional == -0.5 )) {
157
153
bool even = !fmod (integral , 2.0 );
158
154
159
155
/* If the integral part is not even we can make it even
@@ -167,12 +163,11 @@ static inline double php_round_helper(double value, int mode) {
167
163
return integral ;
168
164
169
165
case PHP_ROUND_HALF_ODD :
170
- fractional = fabs (modf (value , & integral ));
171
- if (fractional > 0.5 ) {
166
+ if (fractional > 0.5 || fractional < -0.5 ) {
172
167
return integral + copysign (1.0 , integral );
173
168
}
174
169
175
- if (UNEXPECTED (fractional == 0.5 )) {
170
+ if (UNEXPECTED (fractional == 0.5 || fractional == -0.5 )) {
176
171
bool even = !fmod (integral , 2.0 );
177
172
178
173
if (even ) {
0 commit comments