Skip to content

ext/bcmath: Clear the sign of BcMath\Number results that truncate to zero - #23967

Closed
iliaal wants to merge 1 commit into
php:PHP-8.4from
iliaal:fix/aph-bcmath-signed-zero-ikd-84-work
Closed

iliaal wants to merge 1 commit into
php:PHP-8.4from
iliaal:fix/aph-bcmath-signed-zero-ikd-84-work

Conversation

@iliaal

@iliaal iliaal commented Sep 28, 2026

Copy link
Copy Markdown
Member

Several BcMath\Number operations kept the operand's negative sign when the result truncated to zero at the requested scale: the bc_divide() fast paths for a divisor of 1, -1 or a power of ten, bc_raise() with a positive exponent, and the add/sub/mul helpers. (new BcMath\Number('-0.001'))->div(1, 0) then compares less than 0, is not equal to 0, and makes sqrt() throw. String output already drops the sign of a zero, so the procedural functions are not affected.

memcpy(qptr, numerator->n_value, numerator->n_len + quot_scale);
(*quot)->n_sign = numerator->n_sign == divisor->n_sign ? PLUS : MINUS;
_bc_rm_leading_zeros(*quot);
if (bc_is_zero(*quot)) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put the other n_sign assignment in this else branch

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

*qptr++ = 0;
}
(*quot)->n_sign = numerator->n_sign == divisor->n_sign ? PLUS : MINUS;
if (bc_is_zero(*quot)) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

…zero

A bc_num that is zero must carry PLUS, since bc_compare() orders by sign
first. The bc_divide() fast paths for a divisor of +/-1 or a power of ten,
bc_raise() with a positive exponent, and the Number add/sub/mul helpers
truncate to the requested scale and keep the operand sign, so
(new BcMath\Number('-0.001'))->div(1, 0) compares less than 0, is not
equal to 0, and makes sqrt() throw.
@iliaal
iliaal force-pushed the fix/aph-bcmath-signed-zero-ikd-84-work branch from 95f2d36 to 2277e57 Compare September 29, 2026 12:25
@iliaal
iliaal requested a review from ndossche September 29, 2026 12:26
@iliaal iliaal closed this in 8184e9e Sep 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants