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; +