From da1b51a4969d17c0c1bd23e330cde1864cb9c51e Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Fri, 17 Jan 2020 22:57:03 +0300 Subject: [PATCH] Added function bitCount #8702 --- dbms/src/Functions/bitCount.cpp | 42 +++++++++++++++++++ .../Functions/registerFunctionsArithmetic.cpp | 2 + .../0_stateless/01066_bit_count.reference | 21 ++++++++++ .../queries/0_stateless/01066_bit_count.sql | 13 ++++++ 4 files changed, 78 insertions(+) create mode 100644 dbms/src/Functions/bitCount.cpp create mode 100644 dbms/tests/queries/0_stateless/01066_bit_count.reference create mode 100644 dbms/tests/queries/0_stateless/01066_bit_count.sql diff --git a/dbms/src/Functions/bitCount.cpp b/dbms/src/Functions/bitCount.cpp new file mode 100644 index 00000000000..13225031a8e --- /dev/null +++ b/dbms/src/Functions/bitCount.cpp @@ -0,0 +1,42 @@ +#include +#include +#include + + +namespace DB +{ + +template +struct BitCountImpl +{ + using ResultType = UInt8; + + static inline ResultType apply(A a) + { + return __builtin_popcountll(ext::bit_cast(a)); + } + +#if USE_EMBEDDED_COMPILER + static constexpr bool compilable = false; +#endif +}; + +struct NameBitCount { static constexpr auto name = "bitCount"; }; +using FunctionBitCount = FunctionUnaryArithmetic; + +/// The function has no ranges of monotonicity. +template <> struct FunctionUnaryArithmeticMonotonicity +{ + static bool has() { return false; } + static IFunction::Monotonicity get(const Field &, const Field &) + { + return {}; + } +}; + +void registerFunctionBitCount(FunctionFactory & factory) +{ + factory.registerFunction(); +} + +} diff --git a/dbms/src/Functions/registerFunctionsArithmetic.cpp b/dbms/src/Functions/registerFunctionsArithmetic.cpp index eb68fc32fa1..88350b4fac7 100644 --- a/dbms/src/Functions/registerFunctionsArithmetic.cpp +++ b/dbms/src/Functions/registerFunctionsArithmetic.cpp @@ -20,6 +20,7 @@ void registerFunctionBitShiftLeft(FunctionFactory & factory); void registerFunctionBitShiftRight(FunctionFactory & factory); void registerFunctionBitRotateLeft(FunctionFactory & factory); void registerFunctionBitRotateRight(FunctionFactory & factory); +void registerFunctionBitCount(FunctionFactory & factory); void registerFunctionLeast(FunctionFactory & factory); void registerFunctionGreatest(FunctionFactory & factory); void registerFunctionBitTest(FunctionFactory & factory); @@ -58,6 +59,7 @@ void registerFunctionsArithmetic(FunctionFactory & factory) registerFunctionBitShiftRight(factory); registerFunctionBitRotateLeft(factory); registerFunctionBitRotateRight(factory); + registerFunctionBitCount(factory); registerFunctionLeast(factory); registerFunctionGreatest(factory); registerFunctionBitTest(factory); diff --git a/dbms/tests/queries/0_stateless/01066_bit_count.reference b/dbms/tests/queries/0_stateless/01066_bit_count.reference new file mode 100644 index 00000000000..4a3b084b4a2 --- /dev/null +++ b/dbms/tests/queries/0_stateless/01066_bit_count.reference @@ -0,0 +1,21 @@ +0 +1 +1 +2 +1 +2 +2 +3 +1 +2 +4 +0 +1 +8 +64 +32 +16 +8 +1 10 000000000000F03F +-1 11 000000000000F0BF +inf 11 000000000000F07F diff --git a/dbms/tests/queries/0_stateless/01066_bit_count.sql b/dbms/tests/queries/0_stateless/01066_bit_count.sql new file mode 100644 index 00000000000..d50b2657542 --- /dev/null +++ b/dbms/tests/queries/0_stateless/01066_bit_count.sql @@ -0,0 +1,13 @@ +SELECT bitCount(number) FROM numbers(10); +SELECT avg(bitCount(number)) FROM numbers(256); + +SELECT bitCount(0); +SELECT bitCount(1); +SELECT bitCount(-1); + +SELECT bitCount(toInt64(-1)); +SELECT bitCount(toInt32(-1)); +SELECT bitCount(toInt16(-1)); +SELECT bitCount(toInt8(-1)); + +SELECT x, bitCount(x), hex(reinterpretAsString(x)) FROM VALUES ('x Float64', (1), (-1), (inf));