diff --git a/X10D/src/Int32Extensions/Int32Extensions.cs b/X10D/src/Int32Extensions/Int32Extensions.cs index 77b6820..ce22e97 100644 --- a/X10D/src/Int32Extensions/Int32Extensions.cs +++ b/X10D/src/Int32Extensions/Int32Extensions.cs @@ -8,6 +8,58 @@ namespace X10D /// 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); + } + + var 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; + } + + var cache = value & pattern; + cache <<= 32 - shift; + return (value >> shift) | cache; + } + /// /// Converts a Unix time expressed as the number of milliseconds that have elapsed since 1970-01-01T00:00:00Z to a /// value. @@ -176,6 +228,18 @@ namespace X10D return MathUtils.Lerp(value, target, alpha); } + /// + /// Performs a modulo operation which supports a negative dividend. + /// + /// The dividend. + /// The divisor. + /// The result of dividend % divisor. + public static int Mod(this int dividend, int divisor) + { + int r = dividend % divisor; + return r < 0 ? r + divisor : r; + } + /// /// Converts the value of the current 32-bit signed integer to an equivalent value. ///