diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/IBinaryInteger.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/IBinaryInteger.cs
index e6ef8ae8f9500..bc1be9b3569ff 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Numerics/IBinaryInteger.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/IBinaryInteger.cs
@@ -143,7 +143,7 @@ static virtual TSelf RotateLeft(TSelf value, int rotateAmount)
}
int bitCount = checked(value!.GetByteCount() * 8);
- return (value << rotateAmount) | (value >> (bitCount - rotateAmount));
+ return (value << rotateAmount) | (value >>> (bitCount - rotateAmount));
}
/// Rotates a value right by a given amount.
@@ -158,7 +158,7 @@ static virtual TSelf RotateRight(TSelf value, int rotateAmount)
}
int bitCount = checked(value!.GetByteCount() * 8);
- return (value >> rotateAmount) | (value << (bitCount - rotateAmount));
+ return (value >>> rotateAmount) | (value << (bitCount - rotateAmount));
}
/// Computes the number of trailing zero bits in a value.
diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Numerics/DimTests.GenericMath.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Numerics/DimTests.GenericMath.cs
new file mode 100644
index 0000000000000..dc6870e1f65a2
--- /dev/null
+++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Numerics/DimTests.GenericMath.cs
@@ -0,0 +1,398 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using Xunit;
+
+namespace System.Numerics.Tests
+{
+ public class DimTests_GenericMath
+ {
+ //
+ // IBinaryNumber
+ //
+
+ [Fact]
+ public static void AllBitsSetInt32Test()
+ {
+ Assert.Equal((BinaryIntegerWrapper)unchecked((int)0xFFFF_FFFF), BinaryNumberHelper>.AllBitsSet);
+ Assert.Equal((BinaryIntegerWrapper)0, ~BinaryNumberHelper>.AllBitsSet);
+ }
+
+ [Fact]
+ public static void AllBitsSetUInt32Test()
+ {
+ Assert.Equal((BinaryIntegerWrapper)0xFFFF_FFFF, BinaryNumberHelper>.AllBitsSet);
+ Assert.Equal((BinaryIntegerWrapper)0U, ~BinaryNumberHelper>.AllBitsSet);
+ }
+
+ //
+ // IBinaryInteger
+ //
+
+ [Fact]
+ public static void DivRemInt32Test()
+ {
+ Assert.Equal(((BinaryIntegerWrapper)0x00000000, (BinaryIntegerWrapper)0x00000000), BinaryIntegerHelper>.DivRem((int)0x00000000, 2));
+ Assert.Equal(((BinaryIntegerWrapper)0x00000000, (BinaryIntegerWrapper)0x00000001), BinaryIntegerHelper>.DivRem((int)0x00000001, 2));
+ Assert.Equal(((BinaryIntegerWrapper)0x3FFFFFFF, (BinaryIntegerWrapper)0x00000001), BinaryIntegerHelper>.DivRem((int)0x7FFFFFFF, 2));
+ Assert.Equal(((BinaryIntegerWrapper)unchecked((int)0xC0000000), (BinaryIntegerWrapper)0x00000000), BinaryIntegerHelper>.DivRem(unchecked((int)0x80000000), 2));
+ Assert.Equal(((BinaryIntegerWrapper)0x00000000, (BinaryIntegerWrapper)unchecked((int)0xFFFFFFFF)), BinaryIntegerHelper>.DivRem(unchecked((int)0xFFFFFFFF), 2));
+ }
+
+ [Fact]
+ public static void DivRemUInt32Test()
+ {
+ Assert.Equal(((BinaryIntegerWrapper)0x00000000, (BinaryIntegerWrapper)0x00000000), BinaryIntegerHelper>.DivRem((uint)0x00000000, 2));
+ Assert.Equal(((BinaryIntegerWrapper)0x00000000, (BinaryIntegerWrapper)0x00000001), BinaryIntegerHelper>.DivRem((uint)0x00000001, 2));
+ Assert.Equal(((BinaryIntegerWrapper)0x3FFFFFFF, (BinaryIntegerWrapper)0x00000001), BinaryIntegerHelper>.DivRem((uint)0x7FFFFFFF, 2));
+ Assert.Equal(((BinaryIntegerWrapper)0x40000000, (BinaryIntegerWrapper)0x00000000), BinaryIntegerHelper>.DivRem((uint)0x80000000, 2));
+ Assert.Equal(((BinaryIntegerWrapper)0x7FFFFFFF, (BinaryIntegerWrapper)0x00000001), BinaryIntegerHelper>.DivRem((uint)0xFFFFFFFF, 2));
+ }
+
+ [Fact]
+ public static void LeadingZeroCountInt32Test()
+ {
+ Assert.Equal((BinaryIntegerWrapper)0x00000020, BinaryIntegerHelper>.LeadingZeroCount((int)0x00000000));
+ Assert.Equal((BinaryIntegerWrapper)0x0000001F, BinaryIntegerHelper>.LeadingZeroCount((int)0x00000001));
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, BinaryIntegerHelper>.LeadingZeroCount((int)0x7FFFFFFF));
+ Assert.Equal((BinaryIntegerWrapper)0x00000000, BinaryIntegerHelper>.LeadingZeroCount(unchecked((int)0x80000000)));
+ Assert.Equal((BinaryIntegerWrapper)0x00000000, BinaryIntegerHelper>.LeadingZeroCount(unchecked((int)0xFFFFFFFF)));
+ }
+
+ [Fact]
+ public static void LeadingZeroCountUInt32Test()
+ {
+ Assert.Equal((BinaryIntegerWrapper)0x00000020, BinaryIntegerHelper>.LeadingZeroCount((uint)0x00000000));
+ Assert.Equal((BinaryIntegerWrapper)0x0000001F, BinaryIntegerHelper>.LeadingZeroCount((uint)0x00000001));
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, BinaryIntegerHelper>.LeadingZeroCount((uint)0x7FFFFFFF));
+ Assert.Equal((BinaryIntegerWrapper)0x00000000, BinaryIntegerHelper>.LeadingZeroCount((uint)0x80000000));
+ Assert.Equal((BinaryIntegerWrapper)0x00000000, BinaryIntegerHelper>.LeadingZeroCount((uint)0xFFFFFFFF));
+ }
+
+ [Fact]
+ public static void RotateLeftInt32Test()
+ {
+ Assert.Equal((BinaryIntegerWrapper)0x00000000, BinaryIntegerHelper>.RotateLeft((int)0x00000000, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x00000002, BinaryIntegerHelper>.RotateLeft((int)0x00000001, 1));
+ Assert.Equal((BinaryIntegerWrapper)unchecked((int)0xFFFFFFFE), BinaryIntegerHelper>.RotateLeft((int)0x7FFFFFFF, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, BinaryIntegerHelper>.RotateLeft(unchecked((int)0x80000000), 1));
+ Assert.Equal((BinaryIntegerWrapper)unchecked((int)0xFFFFFFFF), BinaryIntegerHelper>.RotateLeft(unchecked((int)0xFFFFFFFF), 1));
+ }
+
+ [Fact]
+ public static void RotateLeftUInt32Test()
+ {
+ Assert.Equal((BinaryIntegerWrapper)0x00000000, BinaryIntegerHelper>.RotateLeft((uint)0x00000000, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x00000002, BinaryIntegerHelper>.RotateLeft((uint)0x00000001, 1));
+ Assert.Equal((BinaryIntegerWrapper)0xFFFFFFFE, BinaryIntegerHelper>.RotateLeft((uint)0x7FFFFFFF, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, BinaryIntegerHelper>.RotateLeft((uint)0x80000000, 1));
+ Assert.Equal((BinaryIntegerWrapper)0xFFFFFFFF, BinaryIntegerHelper>.RotateLeft((uint)0xFFFFFFFF, 1));
+ }
+
+ [Fact]
+ public static void RotateRightInt32Test()
+ {
+ Assert.Equal((BinaryIntegerWrapper)0x00000000, BinaryIntegerHelper>.RotateRight((int)0x00000000, 1));
+ Assert.Equal((BinaryIntegerWrapper)unchecked((int)0x80000000), BinaryIntegerHelper>.RotateRight((int)0x00000001, 1));
+ Assert.Equal((BinaryIntegerWrapper)unchecked((int)0xBFFFFFFF), BinaryIntegerHelper>.RotateRight((int)0x7FFFFFFF, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x40000000, BinaryIntegerHelper>.RotateRight(unchecked((int)0x80000000), 1));
+ Assert.Equal((BinaryIntegerWrapper)unchecked((int)0xFFFFFFFF), BinaryIntegerHelper>.RotateRight(unchecked((int)0xFFFFFFFF), 1));
+ }
+
+ [Fact]
+ public static void RotateRightUInt32Test()
+ {
+ Assert.Equal((BinaryIntegerWrapper)0x00000000, BinaryIntegerHelper>.RotateRight((uint)0x00000000, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x80000000, BinaryIntegerHelper>.RotateRight((uint)0x00000001, 1));
+ Assert.Equal((BinaryIntegerWrapper)0xBFFFFFFF, BinaryIntegerHelper>.RotateRight((uint)0x7FFFFFFF, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x40000000, BinaryIntegerHelper>.RotateRight((uint)0x80000000, 1));
+ Assert.Equal((BinaryIntegerWrapper)0xFFFFFFFF, BinaryIntegerHelper>.RotateRight((uint)0xFFFFFFFF, 1));
+ }
+
+ //
+ // INumber
+ //
+
+ [Fact]
+ public static void ClampInt32Test()
+ {
+ Assert.Equal((BinaryIntegerWrapper)0x00000000, NumberHelper>.Clamp((int)0x00000000, unchecked((int)0xFFFFFFC0), 0x003F));
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, NumberHelper>.Clamp((int)0x00000001, unchecked((int)0xFFFFFFC0), 0x003F));
+ Assert.Equal((BinaryIntegerWrapper)0x0000003F, NumberHelper>.Clamp((int)0x7FFFFFFF, unchecked((int)0xFFFFFFC0), 0x003F));
+ Assert.Equal((BinaryIntegerWrapper)unchecked((int)0xFFFFFFC0), NumberHelper>.Clamp(unchecked((int)0x80000000), unchecked((int)0xFFFFFFC0), 0x003F));
+ Assert.Equal((BinaryIntegerWrapper)unchecked((int)0xFFFFFFFF), NumberHelper>.Clamp(unchecked((int)0xFFFFFFFF), unchecked((int)0xFFFFFFC0), 0x003F));
+ }
+
+ [Fact]
+ public static void ClampUInt32Test()
+ {
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, NumberHelper>.Clamp((uint)0x00000000, 0x0001, 0x003F));
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, NumberHelper>.Clamp((uint)0x00000001, 0x0001, 0x003F));
+ Assert.Equal((BinaryIntegerWrapper)0x0000003F, NumberHelper>.Clamp((uint)0x7FFFFFFF, 0x0001, 0x003F));
+ Assert.Equal((BinaryIntegerWrapper)0x0000003F, NumberHelper>.Clamp((uint)0x80000000, 0x0001, 0x003F));
+ Assert.Equal((BinaryIntegerWrapper)0x0000003F, NumberHelper>.Clamp((uint)0xFFFFFFFF, 0x0001, 0x003F));
+ }
+
+ [Fact]
+ public static void MaxInt32Test()
+ {
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, NumberHelper>.Max((int)0x00000000, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, NumberHelper>.Max((int)0x00000001, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x7FFFFFFF, NumberHelper>.Max((int)0x7FFFFFFF, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, NumberHelper>.Max(unchecked((int)0x80000000), 1));
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, NumberHelper>.Max(unchecked((int)0xFFFFFFFF), 1));
+ }
+
+ [Fact]
+ public static void MaxUInt32Test()
+ {
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, NumberHelper>.Max((uint)0x00000000, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, NumberHelper>.Max((uint)0x00000001, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x7FFFFFFF, NumberHelper>.Max((uint)0x7FFFFFFF, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x80000000, NumberHelper>.Max((uint)0x80000000, 1));
+ Assert.Equal((BinaryIntegerWrapper)0xFFFFFFFF, NumberHelper>.Max((uint)0xFFFFFFFF, 1));
+ }
+
+ [Fact]
+ public static void MaxNumberInt32Test()
+ {
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, NumberHelper>.MaxNumber((int)0x00000000, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, NumberHelper>.MaxNumber((int)0x00000001, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x7FFFFFFF, NumberHelper>.MaxNumber((int)0x7FFFFFFF, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, NumberHelper>.MaxNumber(unchecked((int)0x80000000), 1));
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, NumberHelper>.MaxNumber(unchecked((int)0xFFFFFFFF), 1));
+ }
+
+ [Fact]
+ public static void MaxNumberUInt32Test()
+ {
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, NumberHelper>.MaxNumber((uint)0x00000000, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, NumberHelper>.MaxNumber((uint)0x00000001, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x7FFFFFFF, NumberHelper>.MaxNumber((uint)0x7FFFFFFF, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x80000000, NumberHelper>.MaxNumber((uint)0x80000000, 1));
+ Assert.Equal((BinaryIntegerWrapper)0xFFFFFFFF, NumberHelper>.MaxNumber((uint)0xFFFFFFFF, 1));
+ }
+
+ [Fact]
+ public static void MinInt32Test()
+ {
+ Assert.Equal((BinaryIntegerWrapper)0x00000000, NumberHelper>.Min((int)0x00000000, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, NumberHelper>.Min((int)0x00000001, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, NumberHelper>.Min((int)0x7FFFFFFF, 1));
+ Assert.Equal((BinaryIntegerWrapper)unchecked((int)0x80000000), NumberHelper>.Min(unchecked((int)0x80000000), 1));
+ Assert.Equal((BinaryIntegerWrapper)unchecked((int)0xFFFFFFFF), NumberHelper>.Min(unchecked((int)0xFFFFFFFF), 1));
+ }
+
+ [Fact]
+ public static void MinUInt32Test()
+ {
+ Assert.Equal((BinaryIntegerWrapper)0x00000000, NumberHelper>.Min((uint)0x00000000, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, NumberHelper>.Min((uint)0x00000001, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, NumberHelper>.Min((uint)0x7FFFFFFF, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, NumberHelper>.Min((uint)0x80000000, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, NumberHelper>.Min((uint)0xFFFFFFFF, 1));
+ }
+
+ [Fact]
+ public static void MinNumberInt32Test()
+ {
+ Assert.Equal((BinaryIntegerWrapper)0x00000000, NumberHelper>.MinNumber((int)0x00000000, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, NumberHelper>.MinNumber((int)0x00000001, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, NumberHelper>.MinNumber((int)0x7FFFFFFF, 1));
+ Assert.Equal((BinaryIntegerWrapper)unchecked((int)0x80000000), NumberHelper>.MinNumber(unchecked((int)0x80000000), 1));
+ Assert.Equal((BinaryIntegerWrapper)unchecked((int)0xFFFFFFFF), NumberHelper>.MinNumber(unchecked((int)0xFFFFFFFF), 1));
+ }
+
+ [Fact]
+ public static void MinNumberUInt32Test()
+ {
+ Assert.Equal((BinaryIntegerWrapper)0x00000000, NumberHelper>.MinNumber((uint)0x00000000, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, NumberHelper>.MinNumber((uint)0x00000001, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, NumberHelper>.MinNumber((uint)0x7FFFFFFF, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, NumberHelper>.MinNumber((uint)0x80000000, 1));
+ Assert.Equal((BinaryIntegerWrapper)0x00000001, NumberHelper>.MinNumber((uint)0xFFFFFFFF, 1));
+ }
+
+ [Fact]
+ public static void SignInt32Test()
+ {
+ Assert.Equal(0, NumberHelper>.Sign((int)0x00000000));
+ Assert.Equal(1, NumberHelper>.Sign((int)0x00000001));
+ Assert.Equal(1, NumberHelper>.Sign((int)0x7FFFFFFF));
+ Assert.Equal(-1, NumberHelper>.Sign(unchecked((int)0x80000000)));
+ Assert.Equal(-1, NumberHelper>.Sign(unchecked((int)0xFFFFFFFF)));
+ }
+
+ [Fact]
+ public static void SignUInt32Test()
+ {
+ Assert.Equal(0, NumberHelper>.Sign((uint)0x00000000));
+ Assert.Equal(1, NumberHelper>.Sign((uint)0x00000001));
+ Assert.Equal(1, NumberHelper>.Sign((uint)0x7FFFFFFF));
+ Assert.Equal(1, NumberHelper>.Sign((uint)0x80000000));
+ Assert.Equal(1, NumberHelper>.Sign((uint)0xFFFFFFFF));
+ }
+
+ public struct BinaryIntegerWrapper : IBinaryInteger>
+ where T : IBinaryInteger
+ {
+ public T Value;
+
+ public BinaryIntegerWrapper(T value)
+ {
+ Value = value;
+ }
+
+ public static implicit operator BinaryIntegerWrapper(T value) => new BinaryIntegerWrapper(value);
+
+ public static implicit operator T(BinaryIntegerWrapper value) => value.Value;
+
+ // Required Generic Math Surface Area
+
+ public static BinaryIntegerWrapper One => T.One;
+
+ public static int Radix => T.Radix;
+
+ public static BinaryIntegerWrapper Zero => T.Zero;
+
+ public static BinaryIntegerWrapper AdditiveIdentity => T.AdditiveIdentity;
+
+ public static BinaryIntegerWrapper MultiplicativeIdentity => T.MultiplicativeIdentity;
+
+ public static BinaryIntegerWrapper Abs(BinaryIntegerWrapper value) => T.Abs(value);
+ public static bool IsCanonical(BinaryIntegerWrapper value) => T.IsCanonical(value);
+ public static bool IsComplexNumber(BinaryIntegerWrapper value) => T.IsComplexNumber(value);
+ public static bool IsEvenInteger(BinaryIntegerWrapper value) => T.IsEvenInteger(value);
+ public static bool IsFinite(BinaryIntegerWrapper value) => T.IsFinite(value);
+ public static bool IsImaginaryNumber(BinaryIntegerWrapper value) => T.IsImaginaryNumber(value);
+ public static bool IsInfinity(BinaryIntegerWrapper value) => T.IsInfinity(value);
+ public static bool IsInteger(BinaryIntegerWrapper value) => T.IsInteger(value);
+ public static bool IsNaN(BinaryIntegerWrapper value) => T.IsNaN(value);
+ public static bool IsNegative(BinaryIntegerWrapper value) => T.IsNegative(value);
+ public static bool IsNegativeInfinity(BinaryIntegerWrapper value) => T.IsNegativeInfinity(value);
+ public static bool IsNormal(BinaryIntegerWrapper value) => T.IsNormal(value);
+ public static bool IsOddInteger(BinaryIntegerWrapper value) => T.IsOddInteger(value);
+ public static bool IsPositive(BinaryIntegerWrapper value) => T.IsPositive(value);
+ public static bool IsPositiveInfinity(BinaryIntegerWrapper value) => T.IsPositiveInfinity(value);
+ public static bool IsPow2(BinaryIntegerWrapper value) => T.IsPow2(value);
+ public static bool IsRealNumber(BinaryIntegerWrapper value) => T.IsRealNumber(value);
+ public static bool IsSubnormal(BinaryIntegerWrapper value) => T.IsSubnormal(value);
+ public static bool IsZero(BinaryIntegerWrapper value) => T.IsZero(value);
+ public static BinaryIntegerWrapper Log2(BinaryIntegerWrapper value) => T.Log2(value);
+ public static BinaryIntegerWrapper MaxMagnitude(BinaryIntegerWrapper x, BinaryIntegerWrapper y) => T.MaxMagnitude(x, y);
+ public static BinaryIntegerWrapper MaxMagnitudeNumber(BinaryIntegerWrapper x, BinaryIntegerWrapper y) => T.MaxMagnitudeNumber(x, y);
+ public static BinaryIntegerWrapper MinMagnitude(BinaryIntegerWrapper x, BinaryIntegerWrapper y) => T.MinMagnitude(x, y);
+ public static BinaryIntegerWrapper MinMagnitudeNumber(BinaryIntegerWrapper x, BinaryIntegerWrapper y) => T.MinMagnitudeNumber(x, y);
+ public static BinaryIntegerWrapper Parse(ReadOnlySpan s, NumberStyles style, IFormatProvider? provider) => T.Parse(s, style, provider);
+ public static BinaryIntegerWrapper