From 5aba075ce40cdfd6547d875e367619ec52d376ad Mon Sep 17 00:00:00 2001 From: Clint Banzhaf Date: Thu, 25 Dec 2025 22:41:24 +0100 Subject: [PATCH 1/2] wip --- include/CppCore.Test/Math/Util.h | 14 +++++++++++++- include/CppCore/Math/Util.h | 29 +++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/include/CppCore.Test/Math/Util.h b/include/CppCore.Test/Math/Util.h index 5c117e63..075413a7 100644 --- a/include/CppCore.Test/Math/Util.h +++ b/include/CppCore.Test/Math/Util.h @@ -41,7 +41,19 @@ namespace CppCore { namespace Test { namespace Math CppCore::getbits64(0x0000000000000011ULL, 0x00000000000000FFULL) == 0x0000000000000011ULL && CppCore::getbits64(0x000000000000FF00ULL, 0x00000000000000FFULL) == 0x0000000000000000ULL && CppCore::getbits64(0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL) == 0xFFFFFFFFFFFFFFFFULL; - return a && b; + if (!a || !b) + return false; + uint64_t r[2]; + r[1]=0x0000000000000000ULL; r[0]= 0x0000000000000000ULL; if (CppCore::getbits64(r, 0, 64) != 0x0000000000000000ULL) return false; + r[1]=0x0000000000000001ULL; r[0]= 0x8000000000000000ULL; if (CppCore::getbits64(r, 63, 2) != 0x0000000000000003ULL) return false; + r[1]=0x000000000000FF01ULL; r[0]= 0x80FF000000000000ULL; if (CppCore::getbits64(r, 63, 2) != 0x0000000000000003ULL) return false; + + r[1]=0x8000000000000000ULL; r[0]= 0x0000000000000000ULL; if (CppCore::getbits64(r, 127, 1) != 0x0000000000000001ULL) return false; + + r[1]=0x00000000FFFFFFFFULL; r[0]= 0xFFFFFFFF00000000ULL; if (CppCore::getbits64(r, 32, 64) != 0xFFFFFFFFFFFFFFFFULL) return false; + r[1]=0x0000000000000000ULL; r[0]= 0xFFFFFFFFFFFFFFFFULL; if (CppCore::getbits64(r, 0, 64) != 0xFFFFFFFFFFFFFFFFULL) return false; + r[1]=0xFFFFFFFFFFFFFFFFULL; r[0]= 0x0000000000000000ULL; if (CppCore::getbits64(r, 64, 64) != 0xFFFFFFFFFFFFFFFFULL) return false; + return true; } INLINE static bool setbit32() diff --git a/include/CppCore/Math/Util.h b/include/CppCore/Math/Util.h index c1aaf0a1..00045468 100644 --- a/include/CppCore/Math/Util.h +++ b/include/CppCore/Math/Util.h @@ -132,6 +132,35 @@ namespace CppCore #endif } + template + static INLINE uint64_t getbits64(const UINT& v, const uint32_t i, const uint32_t n) + { + static_assert(sizeof(UINT) % 8 == 0); + assert(i+n <= sizeof(UINT) * 8); + assert(n <= 64); + //if (n > sizeof(uint64_t)*8) return 0; + //if (i+n > sizeof(UINT)*8) return 0; + + const uint64_t* p = (uint64_t*)&v; + const uint32_t idx = i >> 6; + const uint32_t off = i & 0x3F; + + //std::cout << idx << std::endl; + //std::cout << off << std::endl; + uint64_t r = p[idx]; + + if (off) + r = (idx+1 < sizeof(UINT)/8) ? CppCore::shrd64(r, p[idx+1], off) : r >> off; + //else + // r = p[idx]; + //std::cout << r << std::endl; + + if (n < 64) + r &= (1 << n) - 1U; + + return r; + } + /// /// Sets bits that are 1 in mask to 0 in 32-bit integer v and returns it. /// Uses BMI1 if enabled. From 4a56311260eade60805f621aabf4f4c457edfe9d Mon Sep 17 00:00:00 2001 From: Clint Banzhaf Date: Sat, 3 Jan 2026 14:13:41 +0100 Subject: [PATCH 2/2] wip --- include/CppCore.Test/Math/Util.h | 14 ++++++++--- include/CppCore/Math/Util.h | 41 +++++++++++++++++++++----------- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/include/CppCore.Test/Math/Util.h b/include/CppCore.Test/Math/Util.h index 075413a7..ab258fb3 100644 --- a/include/CppCore.Test/Math/Util.h +++ b/include/CppCore.Test/Math/Util.h @@ -24,7 +24,17 @@ namespace CppCore { namespace Test { namespace Math CppCore::getbits32(0x00000011U, 0x000000FFU) == 0x00000011U && CppCore::getbits32(0x0000FF00U, 0x000000FFU) == 0x00000000U && CppCore::getbits32(0xFFFFFFFFU, 0xFFFFFFFFU) == 0xFFFFFFFFU; - return a && b; + if (!a || !b) + return false; + uint32_t r[2]; + r[1] = 0x00000000U; r[0] = 0x00000000U; if (CppCore::getbits32(r, 0, 32) != 0x00000000U) return false; + r[1] = 0x00000001U; r[0] = 0x80000000U; if (CppCore::getbits32(r, 31, 2) != 0x00000003U) return false; + r[1] = 0x0000FF01U; r[0] = 0x80FF0000U; if (CppCore::getbits32(r, 31, 2) != 0x00000003U) return false; + r[1] = 0x80000000U; r[0] = 0x00000000U; if (CppCore::getbits32(r, 63, 1) != 0x00000001U) return false; + r[1] = 0xFFFFFFFFU; r[0] = 0xFFFFFFFFU; if (CppCore::getbits32(r, 16, 32) != 0xFFFFFFFFU) return false; + r[1] = 0x00000000U; r[0] = 0xFFFFFFFFU; if (CppCore::getbits32(r, 0, 32) != 0xFFFFFFFFU) return false; + r[1] = 0xFFFFFFFFU; r[0] = 0x00000000U; if (CppCore::getbits32(r, 32, 32) != 0xFFFFFFFFU) return false; + return true; } INLINE static bool getbits64() @@ -47,9 +57,7 @@ namespace CppCore { namespace Test { namespace Math r[1]=0x0000000000000000ULL; r[0]= 0x0000000000000000ULL; if (CppCore::getbits64(r, 0, 64) != 0x0000000000000000ULL) return false; r[1]=0x0000000000000001ULL; r[0]= 0x8000000000000000ULL; if (CppCore::getbits64(r, 63, 2) != 0x0000000000000003ULL) return false; r[1]=0x000000000000FF01ULL; r[0]= 0x80FF000000000000ULL; if (CppCore::getbits64(r, 63, 2) != 0x0000000000000003ULL) return false; - r[1]=0x8000000000000000ULL; r[0]= 0x0000000000000000ULL; if (CppCore::getbits64(r, 127, 1) != 0x0000000000000001ULL) return false; - r[1]=0x00000000FFFFFFFFULL; r[0]= 0xFFFFFFFF00000000ULL; if (CppCore::getbits64(r, 32, 64) != 0xFFFFFFFFFFFFFFFFULL) return false; r[1]=0x0000000000000000ULL; r[0]= 0xFFFFFFFFFFFFFFFFULL; if (CppCore::getbits64(r, 0, 64) != 0xFFFFFFFFFFFFFFFFULL) return false; r[1]=0xFFFFFFFFFFFFFFFFULL; r[0]= 0x0000000000000000ULL; if (CppCore::getbits64(r, 64, 64) != 0xFFFFFFFFFFFFFFFFULL) return false; diff --git a/include/CppCore/Math/Util.h b/include/CppCore/Math/Util.h index 00045468..3c389552 100644 --- a/include/CppCore/Math/Util.h +++ b/include/CppCore/Math/Util.h @@ -105,6 +105,27 @@ namespace CppCore #endif } + /// + /// Extracts up to 32 bits from an integer that's a multiple of 32 bit. + /// + template + static INLINE uint32_t getbits32(const UINT& v, const uint32_t i, const uint32_t n) + { + static_assert(sizeof(UINT) % 4 == 0); + assert(i+n <= sizeof(UINT) * 8); + assert(n <= 32); + static constexpr size_t N32 = sizeof(UINT) / 4; + const uint32_t* p = (uint32_t*)&v; + const uint32_t idx = i >> 5; + const uint32_t off = i & 0x1F; + uint32_t r = p[idx]; + if (off) + r = (idx+1 < N32) ? CppCore::shrd32(r, p[idx+1], off) : r >> off; + if (n < 32) + r &= (1U << n) - 1U; + return r; + } + /// /// Returns in lowbits the n bits starting at index i from 64-bit integer v. /// Undefined return for i >= 64 (use i AND 0x3F to map cyclic). @@ -132,32 +153,24 @@ namespace CppCore #endif } + /// + /// Extracts up to 64 bits from an integer that's a multiple of 64 bit. + /// template static INLINE uint64_t getbits64(const UINT& v, const uint32_t i, const uint32_t n) { static_assert(sizeof(UINT) % 8 == 0); assert(i+n <= sizeof(UINT) * 8); assert(n <= 64); - //if (n > sizeof(uint64_t)*8) return 0; - //if (i+n > sizeof(UINT)*8) return 0; - + static constexpr size_t N64 = sizeof(UINT) / 8; const uint64_t* p = (uint64_t*)&v; const uint32_t idx = i >> 6; const uint32_t off = i & 0x3F; - - //std::cout << idx << std::endl; - //std::cout << off << std::endl; uint64_t r = p[idx]; - if (off) - r = (idx+1 < sizeof(UINT)/8) ? CppCore::shrd64(r, p[idx+1], off) : r >> off; - //else - // r = p[idx]; - //std::cout << r << std::endl; - + r = (idx+1 < N64) ? CppCore::shrd64(r, p[idx+1], off) : r >> off; if (n < 64) - r &= (1 << n) - 1U; - + r &= (1ULL << n) - 1ULL; return r; }