Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix incorrect results of right shifting huge BigIntegers error reported in Issue #65633 #67867

Merged
merged 7 commits into from
Apr 19, 2022

Conversation

dakersnar
Copy link
Contributor

@dakersnar dakersnar commented Apr 11, 2022

Fixes #65633

This bug was caused by a multiplication overflow leading to an incorrect early exit from the right shift operation (returning MinusOne). The immediate solution is to cast one of the operands from int to long before multiplying, as is done elsewhere in this file.

Notably, this is just a short-term fix for this specific bug. As discussed with @tannergooding, a larger overhaul is planned for this class. For example, usage of this class should be validated based on the size constraints of the internal implementation of BigInteger (the current implementation does not truly support arbitrary sizes, due to storing the BigInteger as a uint array, which has a maximum length).

Also included is a test case reproducing the bug, which now passes thanks to the change.

@ghost ghost added the community-contribution Indicates that the PR has been added by a community member label Apr 11, 2022
@dotnet-issue-labeler dotnet-issue-labeler bot added area-System.Numerics and removed community-contribution Indicates that the PR has been added by a community member labels Apr 11, 2022
@ghost
Copy link

ghost commented Apr 11, 2022

Tagging subscribers to this area: @dotnet/area-system-numerics
See info in area-owners.md if you want to be subscribed.

Issue Details

This bug was caused by a multiplication overflow leading to an incorrect early exit from the right shift operation (returning MinusOne). The immediate solution is to cast one of the operands from int to long before multiplying, as is done elsewhere in this file.

Notably, this is just a short-term fix for this specific bug. As discussed with @tannergooding, a larger overhaul is planned for this class. For example, usage of this class should be validated based on the size constraints of the internal implementation of BigInteger (the current implementation does not truly support arbitrary sizes, due to storing the BigInteger as a uint array, which has a maximum length).

Also included is a test case reproducing the bug, which now passes thanks to the change.

Author: dakersnar
Assignees: -
Labels:

area-System.Numerics

Milestone: -

@dnfadmin
Copy link

dnfadmin commented Apr 11, 2022

CLA assistant check
All CLA requirements met.

Copy link
Member

@jeffhandley jeffhandley left a comment

Choose a reason for hiding this comment

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

Looks OK to me, but I'd like to get @tannergooding's review since he's familiar with this implementation.

// Right shift the BigInteger and ensure the operation behaves as expected
BigInteger shiftedBigInt = bigInt >> 1;
Assert.Equal(2147483646, shiftedBigInt.GetBitLength());
Assert.True(shiftedBigInt != new BigInteger(-1));
Copy link
Member

Choose a reason for hiding this comment

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

Should we verify the new value? How do we know it's not all zero..

Copy link
Member

Choose a reason for hiding this comment

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

Would be great to validate the result is equal as well here (might be worth a quick check that any other tests are also validating result and not just "shape"). Otherwise LGTM.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good suggestion, taking a look at this now.

@dakersnar
Copy link
Contributor Author

@tannergooding, @danmoseley, @jeffhandley, I added a commit to expand on the LargeNegativeBigIntegerShiftTest. If there are any style changes you recommend, let me know.

Copy link
Member

@tannergooding tannergooding left a comment

Choose a reason for hiding this comment

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

LGTM. Just a minor nit on the code style for consistency purposes

@tannergooding
Copy link
Member

Looks like there is a x86 test failure as well

dakersnar and others added 2 commits April 14, 2022 13:03
Co-authored-by: Dan Moseley <danmose@microsoft.com>
@dakersnar dakersnar merged commit f5455d3 into dotnet:main Apr 19, 2022
directhex pushed a commit to directhex/runtime that referenced this pull request Apr 21, 2022
…ed in Issue dotnet#65633 (dotnet#67867)

* Fix dotnet#65633, multiplication overflow causing incorrect right shift results

* Add unit test reproducing incorrect right shift results for BigInteger (dotnet#65633)

* Fix inconsistent formatting

* Expand LargeNegativeBigIntegerShiftTest to validate values, expose private BigInteger members to tests

* Apply suggestions from code review

Co-authored-by: Tanner Gooding <tagoo@outlook.com>

* Restrict unit test to 64-bit processors

* Document reasoning for restricting the test to 64-bit

Co-authored-by: Dan Moseley <danmose@microsoft.com>

Co-authored-by: Tanner Gooding <tagoo@outlook.com>
Co-authored-by: Dan Moseley <danmose@microsoft.com>
@ghost ghost locked as resolved and limited conversation to collaborators Jun 5, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Incorrect results of right shifting huge BigIntegers
5 participants