Skip to content

BigInteger unsigned right shift operation is poorly designed and exposes implementation details #91169

@LEI-Hongfaan

Description

@LEI-Hongfaan

Description

I found a problem with the BigInteger unsigned right shift operation (>>>) when the BigInteger is negative.

BigInteger represents an infinite-precision signed binary integer in two's complement form, but it does not have a predefined bit length. Therefore, it should not be treated as a fixed-length integer and subjected to unsigned right shift with some arbitrary or randomly chosen bit length.

Unsigned right shift can be seen as performing a signed right shift (>>) after masking the bits with ((1 << N) - 1). The current implementation incorrectly uses the total number of bits in the minimum number of UInt32 units needed to store the BigInteger as the fixed length N, which is inappropriate because it is unnatural and exposes implementation details. (Note that we may consider upgrading BigInteger to use UInt64 units instead.)

We observe that the larger N is, the more bits are preserved, so for BigInteger, the limiting case is that all bits are preserved, which means that the natural definition of unsigned right shift in infinite precision is the same as signed right shift, because the masking operation does not change any bits. (Although BigInteger has a GetBitLength() value, using it (or its variant) as the fixed length for unsigned right shift is also not very natural.)

Reproduction Steps

.

Expected behavior

The BigInteger unsigned right shift operation should behave exactly the same as the signed right shift operation, regardless of the internal representation of the BigInteger.

Actual behavior

The BigInteger unsigned right shift operation is based on the internal representation of the BigInteger, and produces unexpected results when the BigInteger is negative.

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions