Skip to content

Commit

Permalink
Add TrailingZeroCount and LongCeilingPowerOfTwo (#517)
Browse files Browse the repository at this point in the history
  • Loading branch information
bitfaster authored Nov 25, 2023
1 parent dadfabd commit fc969c8
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 0 deletions.
51 changes: 51 additions & 0 deletions BitFaster.Caching.UnitTests/BitOpsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,17 @@ public void IntCeilingPowerOfTwo(int input, int power)
BitOps.CeilingPowerOfTwo(input).Should().Be(power);
}

[Theory]
[InlineData(3, 4)]
[InlineData(7, 8)]
[InlineData(15, 16)]
[InlineData(536870913, 1073741824)]
[InlineData(34359738368, 34359738368)]
public void LongCeilingPowerOfTwo(long input, long power)
{
BitOps.CeilingPowerOfTwo(input).Should().Be(power);
}

[Theory]
[InlineData(3, 4)]
[InlineData(7, 8)]
Expand All @@ -31,6 +42,46 @@ public void UIntCeilingPowerOfTwo(uint input, uint power)
BitOps.CeilingPowerOfTwo(input).Should().Be(power);
}

[Theory]
[InlineData(3, 4)]
[InlineData(7, 8)]
[InlineData(15, 16)]
[InlineData(536870913, 1073741824)]
[InlineData(34359738368, 34359738368)]

public void UlongCeilingPowerOfTwo(ulong input, ulong power)
{
BitOps.CeilingPowerOfTwo(input).Should().Be(power);
}

[Theory]
[InlineData(0, 64)]
[InlineData(1, 0)]
[InlineData(2, 1)]
[InlineData(1_000_000, 6)]
[InlineData(34359738368, 35)]
[InlineData(4611686018427387904, 62)]
[InlineData(long.MaxValue, 0)]

public void LongTrailingZeroCount(long input, int count)
{
BitOps.TrailingZeroCount(input).Should().Be(count);
}

[Theory]
[InlineData(0, 64)]
[InlineData(1, 0)]
[InlineData(2, 1)]
[InlineData(1_000_000, 6)]
[InlineData(34359738368, 35)]
[InlineData(9223372036854775808, 63)]
[InlineData(ulong.MaxValue, 0)]

public void ULongTrailingZeroCount(ulong input, int count)
{
BitOps.TrailingZeroCount(input).Should().Be(count);
}

[Fact]
public void IntBitCount()
{
Expand Down
56 changes: 56 additions & 0 deletions BitFaster.Caching/BitOps.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ public static int CeilingPowerOfTwo(int x)
return (int)CeilingPowerOfTwo((uint)x);
}

/// <summary>
/// Calculate the smallest power of 2 greater than the input parameter.
/// </summary>
/// <param name="x">The input parameter.</param>
/// <returns>Smallest power of two greater than or equal to x.</returns>
internal static long CeilingPowerOfTwo(long x)
{
return (long)CeilingPowerOfTwo((ulong)x);
}

/// <summary>
/// Calculate the smallest power of 2 greater than the input parameter.
/// </summary>
Expand All @@ -36,7 +46,53 @@ public static uint CeilingPowerOfTwo(uint x)
#else
return 1u << -BitOperations.LeadingZeroCount(x - 1);
#endif
}

/// <summary>
/// Calculate the smallest power of 2 greater than the input parameter.
/// </summary>
/// <param name="x">The input parameter.</param>
/// <returns>Smallest power of two greater than or equal to x.</returns>
internal static ulong CeilingPowerOfTwo(ulong x)
{
#if NETSTANDARD2_0
// https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
--x;
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
x |= x >> 32;
return x + 1;
#else
return 1ul << -BitOperations.LeadingZeroCount(x - 1);
#endif
}

/// <summary>
/// Counts the number of trailing zero bits in the input parameter.
/// </summary>
/// <param name="x">The input parameter.</param>
/// <returns>The number of trailing zero bits.</returns>
internal static int TrailingZeroCount(long x)
{
return TrailingZeroCount((ulong)x);
}

/// <summary>
/// Counts the number of trailing zero bits in the input parameter.
/// </summary>
/// <param name="x">The input parameter.</param>
/// <returns>The number of trailing zero bits.</returns>
internal static int TrailingZeroCount(ulong x)
{
#if NETSTANDARD2_0
// https://codereview.stackexchange.com/questions/288007/c-bit-utility-functions-popcount-trailing-zeros-count-reverse-all-bits
return BitCount(~x & (x - 1));
#else
return BitOperations.TrailingZeroCount(x);
#endif
}

/// <summary>
Expand Down

0 comments on commit fc969c8

Please sign in to comment.