From 1db35384d969f9239de84563927494148100c6d5 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Mon, 15 May 2023 03:30:03 +0200 Subject: [PATCH] Support `bitCount` for big integers --- src/Functions/bitCount.cpp | 9 ++++++++- .../02736_bit_count_big_int.reference | 13 +++++++++++++ .../0_stateless/02736_bit_count_big_int.sql | 19 +++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 tests/queries/0_stateless/02736_bit_count_big_int.reference create mode 100644 tests/queries/0_stateless/02736_bit_count_big_int.sql diff --git a/src/Functions/bitCount.cpp b/src/Functions/bitCount.cpp index 984f33b7001..566a11481be 100644 --- a/src/Functions/bitCount.cpp +++ b/src/Functions/bitCount.cpp @@ -9,7 +9,7 @@ namespace DB template 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) + { + ResultType res = 0; + for (auto item : a.items) + res += __builtin_popcountll(item); + return res; + } if constexpr (std::is_same_v || std::is_same_v) return __builtin_popcountll(a); if constexpr (std::is_same_v || std::is_same_v || std::is_unsigned_v) diff --git a/tests/queries/0_stateless/02736_bit_count_big_int.reference b/tests/queries/0_stateless/02736_bit_count_big_int.reference new file mode 100644 index 00000000000..a3a725ace69 --- /dev/null +++ b/tests/queries/0_stateless/02736_bit_count_big_int.reference @@ -0,0 +1,13 @@ +128 +256 +128 +256 +127 +255 +126 +255 +64 +UInt8 +UInt16 +UInt8 +UInt16 diff --git a/tests/queries/0_stateless/02736_bit_count_big_int.sql b/tests/queries/0_stateless/02736_bit_count_big_int.sql new file mode 100644 index 00000000000..35a4a641606 --- /dev/null +++ b/tests/queries/0_stateless/02736_bit_count_big_int.sql @@ -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));