Support bitCount for big integers

This commit is contained in:
Alexey Milovidov 2023-05-15 03:30:03 +02:00
parent bec4edad65
commit 1db35384d9
3 changed files with 40 additions and 1 deletions

View File

@ -9,7 +9,7 @@ namespace DB
template <typename A>
struct BitCountImpl
{
using ResultType = UInt8;
using ResultType = std::conditional_t<(sizeof(A) * 8 >= 256), UInt16, UInt8>;
static constexpr bool allow_string_or_fixed_string = true;
static inline ResultType apply(A a)
@ -17,6 +17,13 @@ struct BitCountImpl
/// We count bits in the value representation in memory. For example, we support floats.
/// We need to avoid sign-extension when converting signed numbers to larger type. So, uint8_t(-1) has 8 bits.
if constexpr (is_big_int_v<A>)
{
ResultType res = 0;
for (auto item : a.items)
res += __builtin_popcountll(item);
return res;
}
if constexpr (std::is_same_v<A, UInt64> || std::is_same_v<A, Int64>)
return __builtin_popcountll(a);
if constexpr (std::is_same_v<A, UInt32> || std::is_same_v<A, Int32> || std::is_unsigned_v<A>)

View File

@ -0,0 +1,13 @@
128
256
128
256
127
255
126
255
64
UInt8
UInt16
UInt8
UInt16

View File

@ -0,0 +1,19 @@
SELECT bitCount(CAST(-1 AS UInt128));
SELECT bitCount(CAST(-1 AS UInt256));
SELECT bitCount(CAST(-1 AS Int128));
SELECT bitCount(CAST(-1 AS Int256));
SELECT bitCount(CAST(-1 AS UInt128) - 1);
SELECT bitCount(CAST(-1 AS UInt256) - 2);
SELECT bitCount(CAST(-1 AS Int128) - 3);
SELECT bitCount(CAST(-1 AS Int256) - 4);
SELECT bitCount(CAST(0xFFFFFFFFFFFFFFFF AS Int256));
SELECT toTypeName(bitCount(1::UInt128));
SELECT toTypeName(bitCount(1::UInt256));
SELECT toTypeName(bitCount(1::Int128));
SELECT toTypeName(bitCount(1::Int256));