diff --git a/BitFaster.Caching.UnitTests/BitOpsTests.cs b/BitFaster.Caching.UnitTests/BitOpsTests.cs
index bfc956c2..a1d94f3f 100644
--- a/BitFaster.Caching.UnitTests/BitOpsTests.cs
+++ b/BitFaster.Caching.UnitTests/BitOpsTests.cs
@@ -88,16 +88,29 @@ public void IntBitCount()
BitOps.BitCount(666).Should().Be(5);
}
+ [Theory]
+ [InlineData(0U, 0)]
+ [InlineData(666U, 5)]
+ [InlineData(uint.MaxValue, 32)]
+ public void UIntBitCount(uint input, int count)
+ {
+ BitOps.BitCount(input).Should().Be(count);
+ }
+
[Fact]
public void LongtBitCount()
{
BitOps.BitCount(666L).Should().Be(5);
}
- [Fact]
- public void ULongtBitCount()
+
+ [Theory]
+ [InlineData(0UL, 0)]
+ [InlineData(666UL, 5)]
+ [InlineData(ulong.MaxValue, 64)]
+ public void ULongtBitCount(ulong input, int count)
{
- BitOps.BitCount(666UL).Should().Be(5);
+ BitOps.BitCount(input).Should().Be(count);
}
}
}
diff --git a/BitFaster.Caching/BitOps.cs b/BitFaster.Caching/BitOps.cs
index 9c35873e..966f7119 100644
--- a/BitFaster.Caching/BitOps.cs
+++ b/BitFaster.Caching/BitOps.cs
@@ -43,6 +43,8 @@ public static uint CeilingPowerOfTwo(uint x)
x |= x >> 8;
x |= x >> 16;
return x + 1;
+#elif NET6_0_OR_GREATER
+ return BitOperations.RoundUpToPowerOf2(x);
#else
return 1u << -BitOperations.LeadingZeroCount(x - 1);
#endif
@@ -65,6 +67,8 @@ internal static ulong CeilingPowerOfTwo(ulong x)
x |= x >> 16;
x |= x >> 32;
return x + 1;
+#elif NET6_0_OR_GREATER
+ return BitOperations.RoundUpToPowerOf2(x);
#else
return 1ul << -BitOperations.LeadingZeroCount(x - 1);
#endif
@@ -113,14 +117,11 @@ public static int BitCount(int x)
public static int BitCount(uint x)
{
#if NETSTANDARD2_0
- var count = 0;
- while (x != 0)
- {
- count++;
- x &= x - 1; //walking through all the bits which are set to one
- }
+ x -= (x >> 1) & 0x_55555555u;
+ x = (x & 0x_33333333u) + ((x >> 2) & 0x_33333333u);
+ x = (((x + (x >> 4)) & 0x_0F0F0F0Fu) * 0x_01010101u) >> 24;
- return count;
+ return (int)x;
#else
return BitOperations.PopCount(x);
#endif
@@ -141,20 +142,17 @@ public static int BitCount(long x)
///
/// The input parameter.
/// The number of 1 bits.
+ // https://stackoverflow.com/questions/2709430/count-number-of-bits-in-a-64-bit-long-big-integer
public static int BitCount(ulong x)
{
#if NETSTANDARD2_0
- var count = 0;
- while (x != 0)
- {
- count++;
- x &= x - 1; //walking through all the bits which are set to one
- }
-
- return count;
+ x = x - ((x >> 1) & 0x5555555555555555ul);
+ x = (x & 0x3333333333333333ul) + ((x >> 2) & 0x3333333333333333ul);
+ return (int)((((x + (x >> 4)) & 0xF0F0F0F0F0F0F0Ful) * 0x101010101010101ul) >> 56);
#else
return BitOperations.PopCount(x);
#endif
+
}
///