Repository navigation
fix: normalize sign when imuln multiplies by zero - #321
Merged
Merged
Conversation
Multiplying a negative number by the plain number 0 zeroed the words but left the negative flag set, producing a negative zero. That value reported isNeg() as true, was not eq() to zero, compared as less than zero, and printed as -0. Clear the sign along with the length when the factor is zero so the result is a plain zero.
fanatid
added a commit
that referenced
this pull request
Jul 9, 2026
* fix: correct divRound rounding for negative operands divRound computed the half-way threshold and the round-up direction from the raw operands, which only works when both are positive. With a negative dividend or divisor it compared a signed remainder against a value derived from the signed divisor, rounded in the wrong direction, and lost the sign when the truncated quotient was zero. Compare the magnitude of the remainder against half of the absolute divisor and step the quotient away from zero using the sign of the result, so rounding matches the positive case for every sign. * fix: normalize sign when imuln multiplies by zero (#321) * fix: normalize sign when imuln multiplies by zero Multiplying a negative number by the plain number 0 zeroed the words but left the negative flag set, producing a negative zero. That value reported isNeg() as true, was not eq() to zero, compared as less than zero, and printed as -0. Clear the sign along with the length when the factor is zero so the result is a plain zero. * use _normSign() --------- Co-authored-by: Kirill Fomichev <fanatid@ya.ru> * add more tests --------- Co-authored-by: Kirill Fomichev <fanatid@ya.ru>
fanatid
added a commit
that referenced
this pull request
Jul 9, 2026
* fix: normalize sign when imuln multiplies by zero Multiplying a negative number by the plain number 0 zeroed the words but left the negative flag set, producing a negative zero. That value reported isNeg() as true, was not eq() to zero, compared as less than zero, and printed as -0. Clear the sign along with the length when the factor is zero so the result is a plain zero. * use _normSign() --------- Co-authored-by: Kirill Fomichev <fanatid@ya.ru> (cherry picked from commit dd84df8)
fanatid
added a commit
that referenced
this pull request
Jul 9, 2026
* fix: correct divRound rounding for negative operands divRound computed the half-way threshold and the round-up direction from the raw operands, which only works when both are positive. With a negative dividend or divisor it compared a signed remainder against a value derived from the signed divisor, rounded in the wrong direction, and lost the sign when the truncated quotient was zero. Compare the magnitude of the remainder against half of the absolute divisor and step the quotient away from zero using the sign of the result, so rounding matches the positive case for every sign. * fix: normalize sign when imuln multiplies by zero (#321) * fix: normalize sign when imuln multiplies by zero Multiplying a negative number by the plain number 0 zeroed the words but left the negative flag set, producing a negative zero. That value reported isNeg() as true, was not eq() to zero, compared as less than zero, and printed as -0. Clear the sign along with the length when the factor is zero so the result is a plain zero. * use _normSign() --------- Co-authored-by: Kirill Fomichev <fanatid@ya.ru> * add more tests --------- Co-authored-by: Kirill Fomichev <fanatid@ya.ru> (cherry picked from commit 73fb9a4)
Collaborator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Multiplying a negative number by the plain number 0 zeroed the words but left the negative flag set, producing a negative zero. That value reported
isNeg()as true, was noteq()to zero, compared as less than zero, and printed as-0.new BN(-5).mul(new BN(0))correctly gives0; only theimuln/mulnpath diverged.This clears the sign along with the length when the factor is zero so the result is a plain zero. The existing zero-multiplication test only checked
isZero(), which is true even for a negative zero, so the added test asserts the sign directly.