@@ -33,10 +33,54 @@ void bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result)
3333 * - If the fractional part ends with zeros, the zeros are omitted and the number of digits in num is reduced.
3434 * Meaning we might end up in the previous case.
3535 */
36+
37+ /* e.g. value is 0.1 and precision is -3, ret is 0 or 1000 */
3638 if (precision < 0 && num -> n_len < (size_t ) (- (precision + Z_L (1 ))) + 1 ) {
37- * result = bc_copy_num (BCG (_zero_ ));
39+ switch (mode ) {
40+ case PHP_ROUND_HALF_UP :
41+ case PHP_ROUND_HALF_DOWN :
42+ case PHP_ROUND_HALF_EVEN :
43+ case PHP_ROUND_HALF_ODD :
44+ case PHP_ROUND_TOWARD_ZERO :
45+ * result = bc_copy_num (BCG (_zero_ ));
46+ return ;
47+
48+ case PHP_ROUND_CEILING :
49+ if (num -> n_sign == MINUS ) {
50+ * result = bc_copy_num (BCG (_zero_ ));
51+ return ;
52+ }
53+ break ;
54+
55+ case PHP_ROUND_FLOOR :
56+ if (num -> n_sign == PLUS ) {
57+ * result = bc_copy_num (BCG (_zero_ ));
58+ return ;
59+ }
60+ break ;
61+
62+ case PHP_ROUND_AWAY_FROM_ZERO :
63+ break ;
64+
65+ EMPTY_SWITCH_DEFAULT_CASE ()
66+ }
67+
68+ if (bc_is_zero (num )) {
69+ * result = bc_copy_num (BCG (_zero_ ));
70+ return ;
71+ }
72+
73+ /* If precision is -3, it becomes 1000. */
74+ if (UNEXPECTED (precision == ZEND_LONG_MIN )) {
75+ * result = bc_new_num ((size_t ) ZEND_LONG_MAX + 2 , 0 );
76+ } else {
77+ * result = bc_new_num (- precision + 1 , 0 );
78+ }
79+ (* result )-> n_value [0 ] = 1 ;
80+ (* result )-> n_sign = num -> n_sign ;
3881 return ;
3982 }
83+
4084 /* Just like bcadd('1', '1', 4) becomes '2.0000', it pads with zeros at the end if necessary. */
4185 if (precision >= 0 && num -> n_scale <= precision ) {
4286 if (num -> n_scale == precision ) {
@@ -61,7 +105,7 @@ void bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result)
61105 * If the result of rounding is carried over, it will be added later, so first set it to 0 here.
62106 */
63107 if (rounded_len == 0 ) {
64- * result = bc_copy_num ( BCG ( _zero_ ) );
108+ * result = bc_new_num ( 1 , 0 );
65109 } else {
66110 * result = bc_new_num (num -> n_len , precision > 0 ? precision : 0 );
67111 memcpy ((* result )-> n_value , num -> n_value , rounded_len );
0 commit comments