diff --git a/ext/bcmath/libbcmath/src/div.c b/ext/bcmath/libbcmath/src/div.c index 14477f35fb391..809d887f68b9d 100644 --- a/ext/bcmath/libbcmath/src/div.c +++ b/ext/bcmath/libbcmath/src/div.c @@ -478,8 +478,12 @@ bool bc_divide(bc_num numerator, bc_num divisor, bc_num *quot, size_t scale) /* do divide */ bc_do_div(numeratorend, numerator_readable_len, numerator_bottom_extension, divisorend, divisor_len, quot, quot_full_len); - (*quot)->n_sign = numerator->n_sign == divisor->n_sign ? PLUS : MINUS; _bc_rm_leading_zeros(*quot); + if (bc_is_zero(*quot)) { + (*quot)->n_sign = PLUS; + } else { + (*quot)->n_sign = numerator->n_sign == divisor->n_sign ? PLUS : MINUS; + } return true; } diff --git a/ext/bcmath/libbcmath/src/floor_or_ceil.c b/ext/bcmath/libbcmath/src/floor_or_ceil.c index b0ff811f0a223..98dc94601ac75 100644 --- a/ext/bcmath/libbcmath/src/floor_or_ceil.c +++ b/ext/bcmath/libbcmath/src/floor_or_ceil.c @@ -30,7 +30,7 @@ bc_num bc_floor_or_ceil(bc_num num, bool is_floor) /* If the number is positive and we are flooring, then nothing else needs to be done. * Similarly, if the number is negative and we are ceiling, then nothing else needs to be done. */ if (num->n_scale == 0 || result->n_sign == (is_floor ? PLUS : MINUS)) { - return result; + goto check_zero; } /* check fractional part. */ @@ -43,12 +43,19 @@ bc_num bc_floor_or_ceil(bc_num num, bool is_floor) /* If all digits past the decimal point are 0 */ if (count == 0) { - return result; + goto check_zero; } /* Increment the absolute value of the result by 1 and add sign information */ bc_num tmp = _bc_do_add(result, BCG(_one_)); tmp->n_sign = result->n_sign; bc_free_num(&result); - return tmp; + result = tmp; + +check_zero: + if (bc_is_zero(result)) { + result->n_sign = PLUS; + } + + return result; } diff --git a/ext/bcmath/libbcmath/src/round.c b/ext/bcmath/libbcmath/src/round.c index 7ece5ef6b85c4..3a4892cc7079e 100644 --- a/ext/bcmath/libbcmath/src/round.c +++ b/ext/bcmath/libbcmath/src/round.c @@ -76,7 +76,7 @@ void bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result) if (*nptr >= 5) { goto up; } else if (*nptr < 5) { - return; + goto check_zero; } break; @@ -86,14 +86,14 @@ void bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result) if (*nptr > 5) { goto up; } else if (*nptr < 5) { - return; + goto check_zero; } /* if *nptr == 5, we need to look-up further digits before making a decision. */ break; case PHP_ROUND_CEILING: if (num->n_sign != PLUS) { - return; + goto check_zero; } else if (*nptr > 0) { goto up; } @@ -102,7 +102,7 @@ void bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result) case PHP_ROUND_FLOOR: if (num->n_sign != MINUS) { - return; + goto check_zero; } else if (*nptr > 0) { goto up; } @@ -110,7 +110,7 @@ void bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result) break; case PHP_ROUND_TOWARD_ZERO: - return; + goto check_zero; case PHP_ROUND_AWAY_FROM_ZERO: if (*nptr > 0) { @@ -139,17 +139,17 @@ void bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result) case PHP_ROUND_CEILING: case PHP_ROUND_FLOOR: case PHP_ROUND_AWAY_FROM_ZERO: - return; + goto check_zero; case PHP_ROUND_HALF_EVEN: if (rounded_len == 0 || num->n_value[rounded_len - 1] % 2 == 0) { - return; + goto check_zero; } break; case PHP_ROUND_HALF_ODD: if (rounded_len != 0 && num->n_value[rounded_len - 1] % 2 == 1) { - return; + goto check_zero; } break; @@ -176,4 +176,9 @@ void bc_round(bc_num num, zend_long precision, zend_long mode, bc_num *result) bc_free_num(result); *result = tmp; } + +check_zero: + if (bc_is_zero(*result)) { + (*result)->n_sign = PLUS; + } }