rd-net/Test.Lifetimes/Utils/BitHacksTest.cs (141 lines of code) (raw):

using System; using JetBrains.Util; using NUnit.Framework; namespace Test.Lifetimes.Utils { public class BitHacksTest { [TestCase(0, 0)] [TestCase(1, 0)] [TestCase(2, 1)] [TestCase(3, 1)] [TestCase(4, 2)] [TestCase(5, 2)] [TestCase(7, 2)] [TestCase(8, 3)] [TestCase(9, 3)] [TestCase(15, 3)] [TestCase(16, 4)] [TestCase(byte.MaxValue, 7)] [TestCase(ushort.MaxValue, 15)] public static void Log2FloorInt32(int n, int expected) { int actual = BitHacks.Log2Floor(n); Assert.AreEqual(expected, actual); } [TestCase(0, 0)] [TestCase(1, 0)] [TestCase(2, 1)] [TestCase(3, 1)] [TestCase(4, 2)] [TestCase(5, 2)] [TestCase(7, 2)] [TestCase(8, 3)] [TestCase(9, 3)] [TestCase(15, 3)] [TestCase(16, 4)] [TestCase(byte.MaxValue, 7)] [TestCase(ushort.MaxValue, 15)] [TestCase(uint.MaxValue, 31)] public static void Log2FloorInt64(long n, int expected) { int actual = BitHacks.Log2Floor(n); Assert.AreEqual(expected, actual); } [TestCase(0, 0)] [TestCase(1, 0)] [TestCase(2, 1)] [TestCase(3, 2)] [TestCase(4, 2)] [TestCase(5, 3)] [TestCase(7, 3)] [TestCase(8, 3)] [TestCase(9, 4)] [TestCase(15, 4)] [TestCase(16, 4)] [TestCase(byte.MaxValue, 8)] [TestCase(ushort.MaxValue, 16)] public static void Log2CeilInt32(int n, int expected) { int actual = BitHacks.Log2Ceil(n); Assert.AreEqual(expected, actual); } [TestCase(0, 0)] [TestCase(1, 0)] [TestCase(2, 1)] [TestCase(3, 2)] [TestCase(4, 2)] [TestCase(5, 3)] [TestCase(7, 3)] [TestCase(8, 3)] [TestCase(9, 4)] [TestCase(15, 4)] [TestCase(16, 4)] [TestCase(byte.MaxValue, 8)] [TestCase(ushort.MaxValue, 16)] [TestCase(uint.MaxValue, 32)] public static void Log2CeilInt64(long n, int expected) { int actual = BitHacks.Log2Ceil(n); Assert.AreEqual(expected, actual); } [Test] public static void ThrowsOnNegativeArgument() { Assert.Throws<ArgumentException>(() => BitHacks.Log2Floor(-1)); Assert.Throws<ArgumentException>(() => BitHacks.Log2Floor(-1L)); Assert.Throws<ArgumentException>(() => BitHacks.Log2Ceil(-1)); Assert.Throws<ArgumentException>(() => BitHacks.Log2Ceil(-1L)); } [Test] public static void NumberOfBitSet_Int32() { Assert.AreEqual(0, BitHacks.NumberOfBitSet(0)); Assert.AreEqual(1, BitHacks.NumberOfBitSet(1)); Assert.AreEqual(1, BitHacks.NumberOfBitSet(2)); Assert.AreEqual(2, BitHacks.NumberOfBitSet(3)); Assert.AreEqual(4, BitHacks.NumberOfBitSet(0b_1111)); Assert.AreEqual(16, BitHacks.NumberOfBitSet(0x0F0F0F0F)); // 00001111 pattern repeated Assert.AreEqual(32, BitHacks.NumberOfBitSet(-1)); Assert.AreEqual(1, BitHacks.NumberOfBitSet(int.MinValue)); } [Test] public static void PopCount_UInt32() { Assert.AreEqual(0, BitHacks.PopCount(0u)); Assert.AreEqual(1, BitHacks.PopCount(1u)); Assert.AreEqual(1, BitHacks.PopCount(2u)); Assert.AreEqual(2, BitHacks.PopCount(3u)); Assert.AreEqual(16, BitHacks.PopCount(0xF0F0F0F0u)); Assert.AreEqual(32, BitHacks.PopCount(uint.MaxValue)); } [Test] public static void PopCount_UInt64() { Assert.AreEqual(0, BitHacks.PopCount(0ul)); Assert.AreEqual(1, BitHacks.PopCount(1ul)); Assert.AreEqual(1, BitHacks.PopCount(2ul)); Assert.AreEqual(2, BitHacks.PopCount(3ul)); Assert.AreEqual(32, BitHacks.PopCount(0xF0F0F0F0F0F0F0F0ul)); Assert.AreEqual(64, BitHacks.PopCount(ulong.MaxValue)); } [Test] public static void Log2Floor_UInt64_specific() { Assert.AreEqual(0, BitHacks.Log2Floor(0ul)); Assert.AreEqual(0, BitHacks.Log2Floor(1ul)); Assert.AreEqual(1, BitHacks.Log2Floor(2ul)); Assert.AreEqual(63, BitHacks.Log2Floor(1ul << 63)); Assert.AreEqual(63, BitHacks.Log2Floor(ulong.MaxValue)); } [Test] public static void Log2Ceil_UInt32_specific() { Assert.AreEqual(0, BitHacks.Log2Ceil(0u)); Assert.AreEqual(0, BitHacks.Log2Ceil(1u)); Assert.AreEqual(1, BitHacks.Log2Ceil(2u)); Assert.AreEqual(2, BitHacks.Log2Ceil(3u)); Assert.AreEqual(32, BitHacks.Log2Ceil(uint.MaxValue)); } } }