Skip to content

Commit 3364573

Browse files
kzrnmgithub-actions
authored and
github-actions
committed
Add comment
1 parent faf6fb8 commit 3364573

File tree

1 file changed

+20
-8
lines changed
  • src/libraries/System.Runtime.Numerics/src/System/Numerics

1 file changed

+20
-8
lines changed

src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3263,11 +3263,17 @@ public static BigInteger RotateLeft(BigInteger value, int rotateAmount)
32633263
{
32643264
bits = new ReadOnlySpan<uint>(in smallBits);
32653265
}
3266-
int xl = bits.Length;
32673266

3268-
if (negx && bits[^1] >= kuMaskHighBit
3269-
&& !(bits.IndexOfAnyExcept(0u) == bits.Length - 1 && bits[^1] == kuMaskHighBit))
3267+
int xl = bits.Length;
3268+
if (negx && (bits[^1] >= kuMaskHighBit) && ((bits[^1] != kuMaskHighBit) || bits.IndexOfAnyExcept(0u) != (bits.Length - 1)))
3269+
{
3270+
// We check for a special case where its sign bit could be outside the uint array after 2's complement conversion.
3271+
// For example given [0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF], its 2's complement is [0x01, 0x00, 0x00]
3272+
// After a 32 bit right shift, it becomes [0x00, 0x00] which is [0x00, 0x00] when converted back.
3273+
// The expected result is [0x00, 0x00, 0xFFFFFFFF] (2's complement) or [0x00, 0x00, 0x01] when converted back
3274+
// If the 2's component's last element is a 0, we will track the sign externally
32703275
++xl;
3276+
}
32713277

32723278
int byteCount = xl * 4;
32733279

@@ -3412,11 +3418,17 @@ public static BigInteger RotateRight(BigInteger value, int rotateAmount)
34123418
{
34133419
bits = new ReadOnlySpan<uint>(in smallBits);
34143420
}
3415-
int xl = bits.Length;
34163421

3417-
if (negx && bits[^1] >= kuMaskHighBit
3418-
&& !(bits.IndexOfAnyExcept(0u) == bits.Length - 1 && bits[^1] == kuMaskHighBit))
3422+
int xl = bits.Length;
3423+
if (negx && (bits[^1] >= kuMaskHighBit) && ((bits[^1] != kuMaskHighBit) || bits.IndexOfAnyExcept(0u) != (bits.Length - 1)))
3424+
{
3425+
// We check for a special case where its sign bit could be outside the uint array after 2's complement conversion.
3426+
// For example given [0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF], its 2's complement is [0x01, 0x00, 0x00]
3427+
// After a 32 bit right shift, it becomes [0x00, 0x00] which is [0x00, 0x00] when converted back.
3428+
// The expected result is [0x00, 0x00, 0xFFFFFFFF] (2's complement) or [0x00, 0x00, 0x01] when converted back
3429+
// If the 2's component's last element is a 0, we will track the sign externally
34193430
++xl;
3431+
}
34203432

34213433
int byteCount = xl * 4;
34223434

@@ -3505,11 +3517,11 @@ public static BigInteger RotateRight(BigInteger value, int rotateAmount)
35053517
dstIndex--;
35063518
srcIndex--;
35073519
}
3508-
while ((uint)srcIndex < (uint)xd.Length);
3520+
while ((uint)srcIndex < (uint)xd.Length); // is equivalent to (srcIndex >= 0 && srcIndex < xd.Length)
35093521

35103522
srcIndex = xd.Length - 1;
35113523

3512-
while ((uint)dstIndex < (uint)zd.Length)
3524+
while ((uint)dstIndex < (uint)zd.Length) // is equivalent to (dstIndex >= 0 && dstIndex < zd.Length)
35133525
{
35143526
uint part = xd[srcIndex];
35153527

0 commit comments

Comments
 (0)