From cacdf148d5a1d8b9477899ce78658dc924512504 Mon Sep 17 00:00:00 2001 From: Oliver Booth Date: Fri, 29 Apr 2022 23:16:37 +0100 Subject: [PATCH] Add RotateLeft and RotateRight for integer types --- X10D.Tests/src/Numerics/ByteTests.cs | 42 ++++++++++++ X10D.Tests/src/Numerics/Int16Tests.cs | 44 +++++++++++++ X10D.Tests/src/Numerics/Int32Tests.cs | 42 ++++++++++++ X10D.Tests/src/Numerics/Int64Tests.cs | 42 ++++++++++++ X10D.Tests/src/Numerics/SByteTests.cs | 43 +++++++++++++ X10D.Tests/src/Numerics/UInt16Tests.cs | 45 +++++++++++++ X10D.Tests/src/Numerics/UInt32Tests.cs | 43 +++++++++++++ X10D.Tests/src/Numerics/UInt64Tests.cs | 43 +++++++++++++ X10D/src/Int32Extensions/Int32Extensions.cs | 71 --------------------- X10D/src/Numerics/ByteExtensions.cs | 43 +++++++++++++ X10D/src/Numerics/Int16Extensions.cs | 42 ++++++++++++ X10D/src/Numerics/Int32Extensions.cs | 42 ++++++++++++ X10D/src/Numerics/Int64Extensions.cs | 42 ++++++++++++ X10D/src/Numerics/SByteExtensions.cs | 43 +++++++++++++ X10D/src/Numerics/UInt16Extensions.cs | 42 ++++++++++++ X10D/src/Numerics/UInt32Extensions.cs | 42 ++++++++++++ X10D/src/Numerics/UInt64Extensions.cs | 42 ++++++++++++ 17 files changed, 682 insertions(+), 71 deletions(-) create mode 100644 X10D.Tests/src/Numerics/ByteTests.cs create mode 100644 X10D.Tests/src/Numerics/Int16Tests.cs create mode 100644 X10D.Tests/src/Numerics/Int32Tests.cs create mode 100644 X10D.Tests/src/Numerics/Int64Tests.cs create mode 100644 X10D.Tests/src/Numerics/SByteTests.cs create mode 100644 X10D.Tests/src/Numerics/UInt16Tests.cs create mode 100644 X10D.Tests/src/Numerics/UInt32Tests.cs create mode 100644 X10D.Tests/src/Numerics/UInt64Tests.cs delete mode 100644 X10D/src/Int32Extensions/Int32Extensions.cs create mode 100644 X10D/src/Numerics/ByteExtensions.cs create mode 100644 X10D/src/Numerics/Int16Extensions.cs create mode 100644 X10D/src/Numerics/Int32Extensions.cs create mode 100644 X10D/src/Numerics/Int64Extensions.cs create mode 100644 X10D/src/Numerics/SByteExtensions.cs create mode 100644 X10D/src/Numerics/UInt16Extensions.cs create mode 100644 X10D/src/Numerics/UInt32Extensions.cs create mode 100644 X10D/src/Numerics/UInt64Extensions.cs diff --git a/X10D.Tests/src/Numerics/ByteTests.cs b/X10D.Tests/src/Numerics/ByteTests.cs new file mode 100644 index 0000000..d4890b2 --- /dev/null +++ b/X10D.Tests/src/Numerics/ByteTests.cs @@ -0,0 +1,42 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using X10D.Numerics; + +namespace X10D.Tests.Numerics; + +[TestClass] +public class ByteTests +{ + [TestMethod] + public void RotateLeft_ShouldRotateCorrectly() + { + const byte value = 181; // 10110101 + const byte expected = 91; // 01011011 + + Assert.AreEqual(value, value.RotateLeft(0)); + Assert.AreEqual(expected, value.RotateLeft(4)); + } + + [TestMethod] + public void RotateLeft_ShouldModForLargeCount() + { + const byte value = 181; // 10110101 + Assert.AreEqual(value, value.RotateLeft(8)); + } + + [TestMethod] + public void RotateRight_ShouldRotateCorrectly() + { + const byte value = 181; // 10110101 + const byte expected = 91; // 01011011 + + Assert.AreEqual(value, value.RotateRight(0)); + Assert.AreEqual(expected, value.RotateRight(4)); + } + + [TestMethod] + public void RotateRight_ShouldModForLargeCount() + { + const byte value = 181; // 10110101 + Assert.AreEqual(value, value.RotateRight(8)); + } +} diff --git a/X10D.Tests/src/Numerics/Int16Tests.cs b/X10D.Tests/src/Numerics/Int16Tests.cs new file mode 100644 index 0000000..11a4a3d --- /dev/null +++ b/X10D.Tests/src/Numerics/Int16Tests.cs @@ -0,0 +1,44 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using X10D.Numerics; + +namespace X10D.Tests.Numerics; + +[TestClass] +public class Int16Tests +{ + [TestMethod] + public void RotateLeft_ShouldRotateCorrectly() + { + const short value = 2896; // 00001011 01010000 + const short expected = 27137; // 01101010 00000001 + + Assert.AreEqual(value, value.RotateLeft(0)); + Assert.AreEqual(expected, value.RotateLeft(5)); + Assert.AreEqual(value, value.RotateLeft(16)); + } + + [TestMethod] + public void RotateLeft_ShouldModForLargeCount() + { + const short value = 2896; // 00001011 01010000 + Assert.AreEqual(value, value.RotateLeft(16)); + } + + [TestMethod] + public void RotateRight_ShouldRotateCorrectly() + { + const short value = 2896; // 00001011 01010000 + const short expected = -32678; // 01111111 10100110 + + Assert.AreEqual(value, value.RotateRight(0)); + Assert.AreEqual(expected, value.RotateRight(5)); + Assert.AreEqual(value, value.RotateRight(16)); + } + + [TestMethod] + public void RotateRight_ShouldModForLargeCount() + { + const short value = 2896; // 00001011 01010000 + Assert.AreEqual(value, value.RotateRight(16)); + } +} diff --git a/X10D.Tests/src/Numerics/Int32Tests.cs b/X10D.Tests/src/Numerics/Int32Tests.cs new file mode 100644 index 0000000..874b5af --- /dev/null +++ b/X10D.Tests/src/Numerics/Int32Tests.cs @@ -0,0 +1,42 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using X10D.Numerics; + +namespace X10D.Tests.Numerics; + +[TestClass] +public class Int32Tests +{ + [TestMethod] + public void RotateLeft_ShouldRotateCorrectly() + { + const int value = 284719; // 00000000 00000100 01011000 00101111 + const int expected = -1336016888; // 10110000 01011110 00000000 00001000 + + Assert.AreEqual(value, value.RotateLeft(0)); + Assert.AreEqual(expected, value.RotateLeft(17)); + } + + [TestMethod] + public void RotateLeft_ShouldModForLargeCount() + { + const int value = 284719; // 00000000 00000100 01011000 00101111 + Assert.AreEqual(value, value.RotateLeft(32)); + } + + [TestMethod] + public void RotateRight_ShouldRotateCorrectly() + { + const int value = 284719; // 00000000 00000100 01011000 00101111 + const int expected = 739737602; // 00101100 00010111 10000000 00000010 + + Assert.AreEqual(value, value.RotateRight(0)); + Assert.AreEqual(expected, value.RotateRight(17)); + } + + [TestMethod] + public void RotateRight_ShouldModForLargeCount() + { + const int value = 284719; // 00000000 00000100 01011000 00101111 + Assert.AreEqual(value, value.RotateRight(32)); + } +} diff --git a/X10D.Tests/src/Numerics/Int64Tests.cs b/X10D.Tests/src/Numerics/Int64Tests.cs new file mode 100644 index 0000000..2dff9cf --- /dev/null +++ b/X10D.Tests/src/Numerics/Int64Tests.cs @@ -0,0 +1,42 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using X10D.Numerics; + +namespace X10D.Tests.Numerics; + +[TestClass] +public class Int64Tests +{ + [TestMethod] + public void RotateLeft_ShouldRotateCorrectly() + { + const long value = 5972019251303316844; // 01010010 11100000 11011111 11011110 00110001 10111010 01111101 01101100 + const long expected = -1588168355691398970; // 11101001 11110101 10110001 01001011 10000011 01111111 01111000 11000110 + + Assert.AreEqual(value, value.RotateLeft(0)); + Assert.AreEqual(expected, value.RotateLeft(42)); + } + + [TestMethod] + public void RotateLeft_ShouldModForLargeCount() + { + const long value = 5972019251303316844; // 01010010 11100000 11011111 11011110 00110001 10111010 01111101 01101100 + Assert.AreEqual(value, value.RotateLeft(64)); + } + + [TestMethod] + public void RotateRight_ShouldRotateCorrectly() + { + const long value = 5972019251303316844; // 01010010 11100000 11011111 11011110 00110001 10111010 01111101 01101100 + const long expected = -608990218894919625; // 11110111 10001100 01101110 10011111 01011011 00010100 10111000 00110111 + + Assert.AreEqual(value, value.RotateRight(0)); + Assert.AreEqual(expected, value.RotateRight(42)); + } + + [TestMethod] + public void RotateRight_ShouldModForLargeCount() + { + const long value = 5972019251303316844; // 01010010 11100000 11011111 11011110 00110001 10111010 01111101 01101100 + Assert.AreEqual(value, value.RotateRight(64)); + } +} diff --git a/X10D.Tests/src/Numerics/SByteTests.cs b/X10D.Tests/src/Numerics/SByteTests.cs new file mode 100644 index 0000000..c24ebcf --- /dev/null +++ b/X10D.Tests/src/Numerics/SByteTests.cs @@ -0,0 +1,43 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using X10D.Numerics; + +namespace X10D.Tests.Numerics; + +[TestClass] +[CLSCompliant(false)] +public class SByteTests +{ + [TestMethod] + public void RotateLeft_ShouldRotateCorrectly() + { + const sbyte value = 117; // 01110101 + const sbyte expected = 87; // 01010111 + + Assert.AreEqual(value, value.RotateLeft(0)); + Assert.AreEqual(expected, value.RotateLeft(4)); + } + + [TestMethod] + public void RotateLeft_ShouldModForLargeCount() + { + const sbyte value = 117; // 01110101 + Assert.AreEqual(value, value.RotateLeft(8)); + } + + [TestMethod] + public void RotateRight_ShouldRotateCorrectly() + { + const sbyte value = 117; // 01110101 + const sbyte expected = 87; // 01010111 + + Assert.AreEqual(value, value.RotateRight(0)); + Assert.AreEqual(expected, value.RotateRight(4)); + } + + [TestMethod] + public void RotateRight_ShouldModForLargeCount() + { + const sbyte value = 117; // 01110101 + Assert.AreEqual(value, value.RotateRight(8)); + } +} diff --git a/X10D.Tests/src/Numerics/UInt16Tests.cs b/X10D.Tests/src/Numerics/UInt16Tests.cs new file mode 100644 index 0000000..23a5d39 --- /dev/null +++ b/X10D.Tests/src/Numerics/UInt16Tests.cs @@ -0,0 +1,45 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using X10D.Numerics; + +namespace X10D.Tests.Numerics; + +[TestClass] +[CLSCompliant(false)] +public class UInt16Tests +{ + [TestMethod] + public void RotateLeft_ShouldRotateCorrectly() + { + const ushort value = 2896; // 00001011 01010000 + const ushort expected = 27137; // 01101010 00000001 + + Assert.AreEqual(value, value.RotateLeft(0)); + Assert.AreEqual(expected, value.RotateLeft(5)); + Assert.AreEqual(value, value.RotateLeft(16)); + } + + [TestMethod] + public void RotateLeft_ShouldModForLargeCount() + { + const ushort value = 2896; // 00001011 01010000 + Assert.AreEqual(value, value.RotateLeft(16)); + } + + [TestMethod] + public void RotateRight_ShouldRotateCorrectly() + { + const ushort value = 2896; // 00001011 01010000 + const ushort expected = 32858; // 10000000 01011010 + + Assert.AreEqual(value, value.RotateRight(0)); + Assert.AreEqual(expected, value.RotateRight(5)); + Assert.AreEqual(value, value.RotateRight(16)); + } + + [TestMethod] + public void RotateRight_ShouldModForLargeCount() + { + const ushort value = 2896; // 00001011 01010000 + Assert.AreEqual(value, value.RotateRight(16)); + } +} diff --git a/X10D.Tests/src/Numerics/UInt32Tests.cs b/X10D.Tests/src/Numerics/UInt32Tests.cs new file mode 100644 index 0000000..5686953 --- /dev/null +++ b/X10D.Tests/src/Numerics/UInt32Tests.cs @@ -0,0 +1,43 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using X10D.Numerics; + +namespace X10D.Tests.Numerics; + +[TestClass] +[CLSCompliant(false)] +public class UInt32Tests +{ + [TestMethod] + public void RotateLeft_ShouldRotateCorrectly() + { + const uint value = 284719; // 00000000 00000100 01011000 00101111 + const uint expected = 2958950408; // 10110000 01011110 00000000 00001000 + + Assert.AreEqual(value, value.RotateLeft(0)); + Assert.AreEqual(expected, value.RotateLeft(17)); + } + + [TestMethod] + public void RotateLeft_ShouldModForLargeCount() + { + const uint value = 284719; // 00000000 00000100 01011000 00101111 + Assert.AreEqual(value, value.RotateLeft(32)); + } + + [TestMethod] + public void RotateRight_ShouldRotateCorrectly() + { + const uint value = 284719; // 00000000 00000100 01011000 00101111 + const uint expected = 739737602; // 00101100 00010111 10000000 00000010 + + Assert.AreEqual(value, value.RotateRight(0)); + Assert.AreEqual(expected, value.RotateRight(17)); + } + + [TestMethod] + public void RotateRight_ShouldModForLargeCount() + { + const uint value = 284719; // 00000000 00000100 01011000 00101111 + Assert.AreEqual(value, value.RotateRight(32)); + } +} diff --git a/X10D.Tests/src/Numerics/UInt64Tests.cs b/X10D.Tests/src/Numerics/UInt64Tests.cs new file mode 100644 index 0000000..7d2f026 --- /dev/null +++ b/X10D.Tests/src/Numerics/UInt64Tests.cs @@ -0,0 +1,43 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using X10D.Numerics; + +namespace X10D.Tests.Numerics; + +[TestClass] +[CLSCompliant(false)] +public class UInt64Tests +{ + [TestMethod] + public void RotateLeft_ShouldRotateCorrectly() + { + const ulong value = 5972019251303316844; // 01010010 11100000 11011111 11011110 00110001 10111010 01111101 01101100 + const ulong expected = 16858575718018152646; // 11101001 11110101 10110001 01001011 10000011 01111111 01111000 11000110 + + Assert.AreEqual(value, value.RotateLeft(0)); + Assert.AreEqual(expected, value.RotateLeft(42)); + } + + [TestMethod] + public void RotateLeft_ShouldModForLargeCount() + { + const ulong value = 5972019251303316844; // 01010010 11100000 11011111 11011110 00110001 10111010 01111101 01101100 + Assert.AreEqual(value, value.RotateLeft(64)); + } + + [TestMethod] + public void RotateRight_ShouldRotateCorrectly() + { + const ulong value = 5972019251303316844; // 01010010 11100000 11011111 11011110 00110001 10111010 01111101 01101100 + const ulong expected = 17837753854814631991; // 11110111 10001100 01101110 10011111 01011011 00010100 10111000 00110111 + + Assert.AreEqual(value, value.RotateRight(0)); + Assert.AreEqual(expected, value.RotateRight(42)); + } + + [TestMethod] + public void RotateRight_ShouldModForLargeCount() + { + const ulong value = 5972019251303316844; // 01010010 11100000 11011111 11011110 00110001 10111010 01111101 01101100 + Assert.AreEqual(value, value.RotateRight(64)); + } +} diff --git a/X10D/src/Int32Extensions/Int32Extensions.cs b/X10D/src/Int32Extensions/Int32Extensions.cs deleted file mode 100644 index ff14a94..0000000 --- a/X10D/src/Int32Extensions/Int32Extensions.cs +++ /dev/null @@ -1,71 +0,0 @@ -using X10D.Math; - -namespace X10D; - -/// -/// Extension methods for . -/// -public static class Int32Extensions -{ - /// - /// Performs a circular bitwise left-shift on an integer, such that the most-significant bits that are truncated occupy - /// the least-significant bits. - /// - /// The value to shift. - /// The shift amount. - /// The result of the shift. - public static int CircularLeftShift(this int value, int shift) - { - shift = shift.Mod(32); - if (shift == 0) - { - return value; - } - - var pattern = 0; - for (var i = 0; i < shift; i++) - { - pattern |= 1 << (32 - i); - } - - int cache = value & pattern; - cache >>= 32 - shift; - return (value << shift) | cache; - } - - /// - /// Performs a circular bitwise right-shift on an integer, such that the least-significant bits that are truncated occupy - /// the most-significant bits. - /// - /// The value to shift. - /// The shift amount. - /// The result of the shift. - public static int CircularRightShift(this int value, int shift) - { - shift = shift.Mod(32); - if (shift == 0) - { - return value; - } - - var pattern = 0; - for (var i = 0; i < shift; i++) - { - pattern |= 1 << i; - } - - int cache = value & pattern; - cache <<= 32 - shift; - return (value >> shift) | cache; - } - - /// - /// Converts the current angle in degrees to its equivalent represented in radians. - /// - /// The angle in degrees to convert. - /// The result of π * / 180. - public static float DegreesToRadians(this int value) - { - return ((float)value).DegreesToRadians(); - } -} diff --git a/X10D/src/Numerics/ByteExtensions.cs b/X10D/src/Numerics/ByteExtensions.cs new file mode 100644 index 0000000..ccd97a3 --- /dev/null +++ b/X10D/src/Numerics/ByteExtensions.cs @@ -0,0 +1,43 @@ +using System.Diagnostics.Contracts; +using System.Runtime.CompilerServices; +using X10D.Math; + +namespace X10D.Numerics; + +/// +/// Numeric-related extension methods for . +/// +public static class ByteExtensions +{ + /// + /// Rotates the current value left by the specified number of bits. + /// + /// The value to rotate. + /// + /// The number of bits by which to rotate. Any value outside the range [0..7] is treated as congruent mod 8. + /// + /// The rotated value. + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static byte RotateLeft(this byte value, int count) + { + count = count.Mod(8); + return (byte)((value << count) | (value >> (8 - count))); + } + + /// + /// Rotates the current value right by the specified number of bits. + /// + /// The value to rotate. + /// + /// The number of bits by which to rotate. Any value outside the range [0..7] is treated as congruent mod 8. + /// + /// The rotated value. + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static byte RotateRight(this byte value, int count) + { + count = count.Mod(8); + return (byte)((value >> count) | (value << (8 - count))); + } +} diff --git a/X10D/src/Numerics/Int16Extensions.cs b/X10D/src/Numerics/Int16Extensions.cs new file mode 100644 index 0000000..789eeb5 --- /dev/null +++ b/X10D/src/Numerics/Int16Extensions.cs @@ -0,0 +1,42 @@ +using System.Diagnostics.Contracts; +using System.Runtime.CompilerServices; + +namespace X10D.Numerics; + +/// +/// Numeric-related extension methods for . +/// +public static class Int16Extensions +{ + /// + /// Rotates the current value left by the specified number of bits. + /// + /// The value to rotate. + /// + /// The number of bits by which to rotate. Any value outside the range [0..15] is treated as congruent mod 16. + /// + /// The rotated value. + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static short RotateLeft(this short value, int count) + { + var unsigned = unchecked((ushort)value); + return unchecked((short)unsigned.RotateLeft(count)); + } + + /// + /// Rotates the current value right by the specified number of bits. + /// + /// The value to rotate. + /// + /// The number of bits by which to rotate. Any value outside the range [0..15] is treated as congruent mod 16. + /// + /// The rotated value. + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static short RotateRight(this short value, int count) + { + var unsigned = unchecked((ushort)value); + return unchecked((short)unsigned.RotateRight(count)); + } +} diff --git a/X10D/src/Numerics/Int32Extensions.cs b/X10D/src/Numerics/Int32Extensions.cs new file mode 100644 index 0000000..75dfea8 --- /dev/null +++ b/X10D/src/Numerics/Int32Extensions.cs @@ -0,0 +1,42 @@ +using System.Diagnostics.Contracts; +using System.Runtime.CompilerServices; + +namespace X10D.Numerics; + +/// +/// Numeric-related extension methods for . +/// +public static class Int32Extensions +{ + /// + /// Rotates the current value left by the specified number of bits. + /// + /// The value to rotate. + /// + /// The number of bits by which to rotate. Any value outside the range [0..31] is treated as congruent mod 32. + /// + /// The rotated value. + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static int RotateLeft(this int value, int count) + { + var unsigned = unchecked((uint)value); + return unchecked((int)unsigned.RotateLeft(count)); + } + + /// + /// Rotates the current value right by the specified number of bits. + /// + /// The value to rotate. + /// + /// The number of bits by which to rotate. Any value outside the range [0..31] is treated as congruent mod 32. + /// + /// The rotated value. + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static int RotateRight(this int value, int count) + { + var unsigned = unchecked((uint)value); + return unchecked((int)unsigned.RotateRight(count)); + } +} diff --git a/X10D/src/Numerics/Int64Extensions.cs b/X10D/src/Numerics/Int64Extensions.cs new file mode 100644 index 0000000..5f25a59 --- /dev/null +++ b/X10D/src/Numerics/Int64Extensions.cs @@ -0,0 +1,42 @@ +using System.Diagnostics.Contracts; +using System.Runtime.CompilerServices; + +namespace X10D.Numerics; + +/// +/// Numeric-related extension methods for . +/// +public static class Int64Extensions +{ + /// + /// Rotates the current value left by the specified number of bits. + /// + /// The value to rotate. + /// + /// The number of bits by which to rotate. Any value outside the range [0..63] is treated as congruent mod 64. + /// + /// The rotated value. + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static long RotateLeft(this long value, int count) + { + var unsigned = unchecked((ulong)value); + return unchecked((long)unsigned.RotateLeft(count)); + } + + /// + /// Rotates the current value right by the specified number of bits. + /// + /// The value to rotate. + /// + /// The number of bits by which to rotate. Any value outside the range [0..63] is treated as congruent mod 64. + /// + /// The rotated value. + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static long RotateRight(this long value, int count) + { + var unsigned = unchecked((ulong)value); + return unchecked((long)unsigned.RotateRight(count)); + } +} diff --git a/X10D/src/Numerics/SByteExtensions.cs b/X10D/src/Numerics/SByteExtensions.cs new file mode 100644 index 0000000..e3d9d24 --- /dev/null +++ b/X10D/src/Numerics/SByteExtensions.cs @@ -0,0 +1,43 @@ +using System.Diagnostics.Contracts; +using System.Runtime.CompilerServices; + +namespace X10D.Numerics; + +/// +/// Numeric-related extension methods for . +/// +[CLSCompliant(false)] +public static class SByteExtensions +{ + /// + /// Rotates the current value left by the specified number of bits. + /// + /// The value to rotate. + /// + /// The number of bits by which to rotate. Any value outside the range [0..7] is treated as congruent mod 8. + /// + /// The rotated value. + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static sbyte RotateLeft(this sbyte value, int count) + { + var signed = unchecked((byte)value); + return unchecked((sbyte)signed.RotateLeft(count)); + } + + /// + /// Rotates the current value right by the specified number of bits. + /// + /// The value to rotate. + /// + /// The number of bits by which to rotate. Any value outside the range [0..7] is treated as congruent mod 8. + /// + /// The rotated value. + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static sbyte RotateRight(this sbyte value, int count) + { + var signed = unchecked((byte)value); + return unchecked((sbyte)signed.RotateRight(count)); + } +} diff --git a/X10D/src/Numerics/UInt16Extensions.cs b/X10D/src/Numerics/UInt16Extensions.cs new file mode 100644 index 0000000..4798deb --- /dev/null +++ b/X10D/src/Numerics/UInt16Extensions.cs @@ -0,0 +1,42 @@ +using System.Diagnostics.Contracts; +using System.Numerics; +using System.Runtime.CompilerServices; + +namespace X10D.Numerics; + +/// +/// Numeric-related extension methods for . +/// +[CLSCompliant(false)] +public static class UInt16Extensions +{ + /// + /// Rotates the current value left by the specified number of bits. + /// + /// The value to rotate. + /// + /// The number of bits by which to rotate. Any value outside the range [0..15] is treated as congruent mod 16. + /// + /// The rotated value. + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static ushort RotateLeft(this ushort value, int count) + { + return (ushort)((ushort)(value << count) | (ushort)(value >> (16 - count))); + } + + /// + /// Rotates the current value right by the specified number of bits. + /// + /// The value to rotate. + /// + /// The number of bits by which to rotate. Any value outside the range [0..15] is treated as congruent mod 16. + /// + /// The rotated value. + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static ushort RotateRight(this ushort value, int count) + { + return (ushort)((ushort)(value >> count) | (ushort)(value << (16 - count))); + } +} diff --git a/X10D/src/Numerics/UInt32Extensions.cs b/X10D/src/Numerics/UInt32Extensions.cs new file mode 100644 index 0000000..d5b619c --- /dev/null +++ b/X10D/src/Numerics/UInt32Extensions.cs @@ -0,0 +1,42 @@ +using System.Diagnostics.Contracts; +using System.Numerics; +using System.Runtime.CompilerServices; + +namespace X10D.Numerics; + +/// +/// Numeric-related extension methods for . +/// +[CLSCompliant(false)] +public static class UInt32Extensions +{ + /// + /// Rotates the current value left by the specified number of bits. + /// + /// The value to rotate. + /// + /// The number of bits by which to rotate. Any value outside the range [0..31] is treated as congruent mod 32. + /// + /// The rotated value. + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static uint RotateLeft(this uint value, int count) + { + return BitOperations.RotateLeft(value, count); + } + + /// + /// Rotates the current value right by the specified number of bits. + /// + /// The value to rotate. + /// + /// The number of bits by which to rotate. Any value outside the range [0..31] is treated as congruent mod 32. + /// + /// The rotated value. + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static uint RotateRight(this uint value, int count) + { + return BitOperations.RotateRight(value, count); + } +} diff --git a/X10D/src/Numerics/UInt64Extensions.cs b/X10D/src/Numerics/UInt64Extensions.cs new file mode 100644 index 0000000..709ca93 --- /dev/null +++ b/X10D/src/Numerics/UInt64Extensions.cs @@ -0,0 +1,42 @@ +using System.Diagnostics.Contracts; +using System.Numerics; +using System.Runtime.CompilerServices; + +namespace X10D.Numerics; + +/// +/// Numeric-related extension methods for . +/// +[CLSCompliant(false)] +public static class UInt64Extensions +{ + /// + /// Rotates the current value left by the specified number of bits. + /// + /// The value to rotate. + /// + /// The number of bits by which to rotate. Any value outside the range [0..63] is treated as congruent mod 64. + /// + /// The rotated value. + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static ulong RotateLeft(this ulong value, int count) + { + return BitOperations.RotateLeft(value, count); + } + + /// + /// Rotates the current value right by the specified number of bits. + /// + /// The value to rotate. + /// + /// The number of bits by which to rotate. Any value outside the range [0..63] is treated as congruent mod 64. + /// + /// The rotated value. + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static ulong RotateRight(this ulong value, int count) + { + return BitOperations.RotateRight(value, count); + } +}