From dd72a8e3fd90184c050240f8d6b5d79f8ce5af38 Mon Sep 17 00:00:00 2001 From: thejinchao Date: Thu, 7 Aug 2025 22:35:10 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=87=BD=E6=95=B0=20MathUtil?= =?UTF-8?q?::popcount=EF=BC=8C=E7=94=A8=E4=BA=8E=E8=AE=A1=E7=AE=97?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E6=95=B0=E5=AD=97=E4=B8=AD=E4=BA=8C=E8=BF=9B?= =?UTF-8?q?=E5=88=B61=E7=9A=84=E4=B8=AA=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/core/include/math/dvc_math_util.h | 5 +++++ source/core/source/math/dvc_math_util.cpp | 25 +++++++++++++++++++++++ test/unit/dvt_unit_math_util.cpp | 22 ++++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/source/core/include/math/dvc_math_util.h b/source/core/include/math/dvc_math_util.h index a99f227..2a0144a 100644 --- a/source/core/include/math/dvc_math_util.h +++ b/source/core/include/math/dvc_math_util.h @@ -10,6 +10,11 @@ class MathUtil public: static size_t ComponentSize(ComponentType ct); static size_t DataTypeSize(DataType dt); + + //count the number of bits set in v + static DV_CORE_API uint32_t popcount(uint8_t v); + static DV_CORE_API uint32_t popcount(uint16_t v); + static DV_CORE_API uint32_t popcount(uint32_t v); static bool floatEqual(float a, float b, float tolerance = std::numeric_limits::epsilon()) { diff --git a/source/core/source/math/dvc_math_util.cpp b/source/core/source/math/dvc_math_util.cpp index cbf0d5e..73e7af0 100644 --- a/source/core/source/math/dvc_math_util.cpp +++ b/source/core/source/math/dvc_math_util.cpp @@ -11,6 +11,31 @@ const float MathUtil::PI_DIV4 = float(0.25 * PI); const float MathUtil::fDeg2Rad = PI / float(180.0); const float MathUtil::fRad2Deg = float(180.0) / PI; +static const uint8_t kBitsSetTable256[256] = +{ +#define B2(n) n, n+1, n+1, n+2 +#define B4(n) B2(n), B2(n+1), B2(n+1), B2(n+2) +#define B6(n) B4(n), B4(n+1), B4(n+1), B4(n+2) + + B6(0), B6(1), B6(1), B6(2) +}; + +uint32_t MathUtil::popcount(uint8_t v) +{ + return kBitsSetTable256[v]; +} + +uint32_t MathUtil::popcount(uint16_t v) +{ + return kBitsSetTable256[v & 0xff] + kBitsSetTable256[(v >> 8) & 0xff]; +} + +uint32_t MathUtil::popcount(uint32_t v) +{ + return kBitsSetTable256[v & 0xff] + kBitsSetTable256[(v >> 8) & 0xff] + + kBitsSetTable256[(v >> 16) & 0xff] + kBitsSetTable256[v >> 24]; +} + size_t MathUtil::ComponentSize(ComponentType ct) { switch (ct) diff --git a/test/unit/dvt_unit_math_util.cpp b/test/unit/dvt_unit_math_util.cpp index 6b0a49e..4ee7f99 100644 --- a/test/unit/dvt_unit_math_util.cpp +++ b/test/unit/dvt_unit_math_util.cpp @@ -76,4 +76,26 @@ TEST(MathUtil, Basic) EXPECT_EQ_4X4_T_APPROX(m1, gm1, std::numeric_limits::epsilon() * 100); } } + + //couting bit set + { + EXPECT_EQ(MathUtil::popcount((uint8_t)(0x0)), 0); + EXPECT_EQ(MathUtil::popcount((uint8_t)(0xFF)), 8); + EXPECT_EQ(MathUtil::popcount((uint16_t)(0x0)), 0); + EXPECT_EQ(MathUtil::popcount((uint16_t)(0xFFFF)), 16); + EXPECT_EQ(MathUtil::popcount((uint32_t)(0x0)), 0); + EXPECT_EQ(MathUtil::popcount((uint32_t)(0xFFFFFFFF)), 32); + + for(int32_t i=0; i<100; i++) + { + uint8_t v8 = (uint8_t)MathUtil::rangeRandom(0, 0xFF); + EXPECT_EQ(MathUtil::popcount(v8), __popcnt(v8)); + + uint16_t v16 = (uint16_t)MathUtil::rangeRandom(0, 0xFFFF); + EXPECT_EQ(MathUtil::popcount(v16), __popcnt(v16)); + + uint32_t v32 = (uint32_t)MathUtil::rangeRandom(0, 0x7FFFFF); + EXPECT_EQ(MathUtil::popcount(v32), __popcnt(v32)); + } + } }