diff --git a/src/Functions/bitCount.cpp b/src/Functions/bitCount.cpp
index 566a11481be..f1a3ac897c1 100644
--- a/src/Functions/bitCount.cpp
+++ b/src/Functions/bitCount.cpp
@@ -1,6 +1,7 @@
#include
#include
#include
+#include
namespace DB
@@ -21,19 +22,19 @@ struct BitCountImpl
{
ResultType res = 0;
for (auto item : a.items)
- res += __builtin_popcountll(item);
+ res += std::popcount(item);
return res;
}
if constexpr (std::is_same_v || std::is_same_v)
- return __builtin_popcountll(a);
+ return std::popcount(static_cast(a));
if constexpr (std::is_same_v || std::is_same_v || std::is_unsigned_v)
- return __builtin_popcount(a);
+ return std::popcount(static_cast(a));
if constexpr (std::is_same_v)
- return __builtin_popcount(static_cast(a));
+ return std::popcount(static_cast(a));
if constexpr (std::is_same_v)
- return __builtin_popcount(static_cast(a));
+ return std::popcount(static_cast(a));
else
- return __builtin_popcountll(bit_cast(a));
+ return std::popcount(bit_cast(a));
}
#if USE_EMBEDDED_COMPILER
diff --git a/src/Functions/bitHammingDistance.cpp b/src/Functions/bitHammingDistance.cpp
index 2eaa397dd04..f00f38b61af 100644
--- a/src/Functions/bitHammingDistance.cpp
+++ b/src/Functions/bitHammingDistance.cpp
@@ -2,20 +2,44 @@
#include
#include
+
namespace DB
{
+
+namespace ErrorCodes
+{
+ extern const int ILLEGAL_COLUMN;
+}
+
template
struct BitHammingDistanceImpl
{
- using ResultType = UInt8;
+ using ResultType = std::conditional_t<(sizeof(A) * 8 >= 256), UInt16, UInt8>;
static constexpr bool allow_fixed_string = true;
static constexpr bool allow_string_integer = false;
template
static inline NO_SANITIZE_UNDEFINED Result apply(A a, B b)
{
- UInt64 res = static_cast(a) ^ static_cast(b);
- return std::popcount(res);
+ /// Note: it's unspecified if signed integers should be promoted with sign-extension or with zero-fill.
+ /// This behavior can change in the future.
+
+ if constexpr (sizeof(A) <= sizeof(UInt64) && sizeof(B) <= sizeof(UInt64))
+ {
+ UInt64 res = static_cast(a) ^ static_cast(b);
+ return std::popcount(res);
+ }
+ else if constexpr (is_big_int_v && is_big_int_v)
+ {
+ auto xored = a ^ b;
+
+ ResultType res = 0;
+ for (auto item : xored.items)
+ res += std::popcount(item);
+ return res;
+ }
+ else
+ throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Unsupported data type combination in function 'bitHammingDistance'");
}
#if USE_EMBEDDED_COMPILER
diff --git a/tests/queries/0_stateless/02921_bit_hamming_distance_big_int.reference b/tests/queries/0_stateless/02921_bit_hamming_distance_big_int.reference
new file mode 100644
index 00000000000..62245f5d176
--- /dev/null
+++ b/tests/queries/0_stateless/02921_bit_hamming_distance_big_int.reference
@@ -0,0 +1,9 @@
+314776434768051644139306697240981192872 0 74 74
+14776434768051644139306697240981192872314776434768051644139306697240981192872 0 141 141
+314776434768051644139306697240981192872 14776434768051644139306697240981192872314776434768051644139306697240981192872 115 115
+-25505932152886819324067910190787018584 0 74 74
+14776434768051644139306697240981192872314776434768051644139306697240981192872 0 141 141
+-25505932152886819324067910190787018584 14776434768051644139306697240981192872314776434768051644139306697240981192872 99 99
+314776434768051644139306697240981192872 0 74 74
+14776434768051644139306697240981192872314776434768051644139306697240981192872 0 141 141
+314776434768051644139306697240981192872 14776434768051644139306697240981192872314776434768051644139306697240981192872 115 115
diff --git a/tests/queries/0_stateless/02921_bit_hamming_distance_big_int.sql b/tests/queries/0_stateless/02921_bit_hamming_distance_big_int.sql
new file mode 100644
index 00000000000..6f241e104b6
--- /dev/null
+++ b/tests/queries/0_stateless/02921_bit_hamming_distance_big_int.sql
@@ -0,0 +1,12 @@
+SELECT 314776434768051644139306697240981192872::UInt128 AS x, 0::UInt128 AS y, bitCount(bitXor(x, y)) AS a, bitHammingDistance(x, y) AS b;
+SELECT 14776434768051644139306697240981192872314776434768051644139306697240981192872::UInt256 AS x, 0::UInt128 AS y, bitCount(bitXor(x, y)) AS a, bitHammingDistance(x, y) AS b;
+SELECT 314776434768051644139306697240981192872::UInt128 AS x, 14776434768051644139306697240981192872314776434768051644139306697240981192872::UInt256 AS y, bitCount(bitXor(x, y)) AS a, bitHammingDistance(x, y) AS b;
+
+SELECT 314776434768051644139306697240981192872::Int128 AS x, 0::UInt128 AS y, bitCount(bitXor(x, y)) AS a, bitHammingDistance(x, y) AS b;
+SELECT 14776434768051644139306697240981192872314776434768051644139306697240981192872::Int256 AS x, 0::UInt128 AS y, bitCount(bitXor(x, y)) AS a, bitHammingDistance(x, y) AS b;
+SELECT 314776434768051644139306697240981192872::Int128 AS x, 14776434768051644139306697240981192872314776434768051644139306697240981192872::UInt256 AS y, bitCount(bitXor(x, y)) AS a, bitHammingDistance(x, y) AS b;
+
+SELECT 314776434768051644139306697240981192872::UInt128 AS x, 0::Int128 AS y, bitCount(bitXor(x, y)) AS a, bitHammingDistance(x, y) AS b;
+SELECT 14776434768051644139306697240981192872314776434768051644139306697240981192872::UInt256 AS x, 0::Int128 AS y, bitCount(bitXor(x, y)) AS a, bitHammingDistance(x, y) AS b;
+SELECT 314776434768051644139306697240981192872::UInt128 AS x, 14776434768051644139306697240981192872314776434768051644139306697240981192872::Int256 AS y, bitCount(bitXor(x, y)) AS a, bitHammingDistance(x, y) AS b;
+