Skip to content

Commit a21bf17

Browse files
committed
Add comment
1 parent aee797d commit a21bf17

File tree

1 file changed

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

1 file changed

+22
-8
lines changed

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

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3247,11 +3247,18 @@ public static BigInteger RotateLeft(BigInteger value, int rotateAmount)
32473247
{
32483248
bits = new ReadOnlySpan<uint>(in smallBits);
32493249
}
3250-
int xl = bits.Length;
32513250

3252-
if (negx && bits[^1] >= kuMaskHighBit
3253-
&& !(bits.IndexOfAnyExcept(0u) == bits.Length - 1 && bits[^1] == kuMaskHighBit))
3251+
int xl = bits.Length;
3252+
if (negx && (bits[^1] >= kuMaskHighBit) && ((bits[^1] != kuMaskHighBit) || bits.IndexOfAnyExcept(0u) != (bits.Length - 1)))
3253+
{
3254+
// For a shift of N x 32 bit,
3255+
// We check for a special case where its sign bit could be outside the uint array after 2's complement conversion.
3256+
// For example given [0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF], its 2's complement is [0x01, 0x00, 0x00]
3257+
// After a 32 bit right shift, it becomes [0x00, 0x00] which is [0x00, 0x00] when converted back.
3258+
// The expected result is [0x00, 0x00, 0xFFFFFFFF] (2's complement) or [0x00, 0x00, 0x01] when converted back
3259+
// If the 2's component's last element is a 0, we will track the sign externally
32543260
++xl;
3261+
}
32553262

32563263
int byteCount = xl * 4;
32573264

@@ -3396,11 +3403,18 @@ public static BigInteger RotateRight(BigInteger value, int rotateAmount)
33963403
{
33973404
bits = new ReadOnlySpan<uint>(in smallBits);
33983405
}
3399-
int xl = bits.Length;
34003406

3401-
if (negx && bits[^1] >= kuMaskHighBit
3402-
&& !(bits.IndexOfAnyExcept(0u) == bits.Length - 1 && bits[^1] == kuMaskHighBit))
3407+
int xl = bits.Length;
3408+
if (negx && (bits[^1] >= kuMaskHighBit) && ((bits[^1] != kuMaskHighBit) || bits.IndexOfAnyExcept(0u) != (bits.Length - 1)))
3409+
{
3410+
// For a shift of N x 32 bit,
3411+
// We check for a special case where its sign bit could be outside the uint array after 2's complement conversion.
3412+
// For example given [0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF], its 2's complement is [0x01, 0x00, 0x00]
3413+
// After a 32 bit right shift, it becomes [0x00, 0x00] which is [0x00, 0x00] when converted back.
3414+
// The expected result is [0x00, 0x00, 0xFFFFFFFF] (2's complement) or [0x00, 0x00, 0x01] when converted back
3415+
// If the 2's component's last element is a 0, we will track the sign externally
34033416
++xl;
3417+
}
34043418

34053419
int byteCount = xl * 4;
34063420

@@ -3489,11 +3503,11 @@ public static BigInteger RotateRight(BigInteger value, int rotateAmount)
34893503
dstIndex--;
34903504
srcIndex--;
34913505
}
3492-
while ((uint)srcIndex < (uint)xd.Length);
3506+
while ((uint)srcIndex < (uint)xd.Length); // is equivalent to (srcIndex >= 0 && srcIndex < xd.Length)
34933507

34943508
srcIndex = xd.Length - 1;
34953509

3496-
while ((uint)dstIndex < (uint)zd.Length)
3510+
while ((uint)dstIndex < (uint)zd.Length) // is equivalent to (dstIndex >= 0 && dstIndex < zd.Length)
34973511
{
34983512
uint part = xd[srcIndex];
34993513

0 commit comments

Comments
 (0)