I want to determine the number of bits needed for a generic integral binary data type (a nice new feature of .NET 7 -- see IBinaryInteger<T>) inside a method. I don't want to use "sizeof" because it requires unsafe compilation. I've come up with a solution (actually several), but have a tough time believing there's not a better answer.
Here's one solution, along with a test program:
using System.Numerics;
namespace BitCountApp {
internal class Program {
static void Main(string[] args) {
Console.WriteLine("Bits in byte = " + CountBits<byte>());
Console.WriteLine("Bits in ushort = " + CountBits<ushort>());
Console.WriteLine("Bits in uint = " + CountBits<uint>());
Console.WriteLine("Bits in ulong = " + CountBits<ulong>());
Console.WriteLine("Bits in UInt128 = " + CountBits<UInt128>());
}
static private int CountBits<T>() where T : IBinaryInteger<T> {
return T.AllBitsSet.GetByteCount() * 8;
}
}
}
This solution works, and it's nice and compact, but it works only for data sizes that are multiples of 8. This may be more theoretical than practical, but it would fail for a "UInt7" datatype that implemented IBinaryInteger with a 7-bit unsigned integer.
"Ah! PopCount!" I hear you cry. Well, there's a problem. If I try to implement CountBits using PopCount ...
static private int BitsForType<T>() where T : IBinaryInteger<T> {
return (int)(T.PopCount(T.AllBitsSet));
}
... I find that I cannot cast the value of PopCount, which returns a "T", to "int" (even though T is a binary integer type).
There is a solution that works correctly -- counting the number of bits for myself, like this ...
static private int CountBits<T>() where T : IBinaryInteger<T> {
var ones = T.AllBitsSet;
int count = 0;
while (ones != T.Zero) {
count++;
ones >>= 1;
};
return count;
}
... but, Yuk!
Is there a way to do this without counting the bits myself? I'm sort of shocked there isn't a built-in property or method for this.