mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
Bit counting functions (CountBits, CountBits64) (#232)
* Core: CountBits and CountBits64 functions are added. * autotest: CountBits test added. * Core: inline force on CountBits and CountBits64
This commit is contained in:
parent
c4283f3ceb
commit
421eb73ac9
5 changed files with 112 additions and 0 deletions
33
autotest/CountBits/CountBits.cpp
Normal file
33
autotest/CountBits/CountBits.cpp
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#include <Core/Core.h>
|
||||
|
||||
using namespace Upp;
|
||||
|
||||
CONSOLE_APP_MAIN
|
||||
{
|
||||
StdLogSetup(LOG_FILE|LOG_COUT);
|
||||
|
||||
DUMP(CountBits(0x0001));
|
||||
DUMP(CountBits(0x000f));
|
||||
DUMP(CountBits(0x00ff));
|
||||
DUMP(CountBits(0x0fff));
|
||||
DUMP(CountBits(0xffff));
|
||||
DUMP(CountBits(0x000fffff));
|
||||
DUMP(CountBits(0x00ffffff));
|
||||
DUMP(CountBits(0x0fffffff));
|
||||
DUMP(CountBits(0xffffffff));
|
||||
|
||||
|
||||
LOG("====================");
|
||||
|
||||
DUMP(CountBits64(0x00000001ffffffff));
|
||||
DUMP(CountBits64(0x0000000fffffffff));
|
||||
DUMP(CountBits64(0x000000ffffffffff));
|
||||
DUMP(CountBits64(0x00000fffffffffff));
|
||||
DUMP(CountBits64(0x0000ffffffffffff));
|
||||
DUMP(CountBits64(0x000fffffffffffff));
|
||||
DUMP(CountBits64(0x00ffffffffffffff));
|
||||
DUMP(CountBits64(0x0fffffffffffffff));
|
||||
DUMP(CountBits64(0xffffffffffffffff));
|
||||
|
||||
CheckLogEtalon();
|
||||
}
|
||||
10
autotest/CountBits/CountBits.upp
Normal file
10
autotest/CountBits/CountBits.upp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
uses
|
||||
Core;
|
||||
|
||||
file
|
||||
Etalon.log,
|
||||
CountBits.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "";
|
||||
|
||||
21
autotest/CountBits/Etalon.log
Normal file
21
autotest/CountBits/Etalon.log
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
* /home/maldoror//upp/.cache/upp.out/autotest/CLANG.Debug.Debug_Full.Shared/CountBits 08.02.2025 14:47:07, user: maldoror
|
||||
|
||||
CountBits(0x0001) = 1
|
||||
CountBits(0x000f) = 4
|
||||
CountBits(0x00ff) = 8
|
||||
CountBits(0x0fff) = 12
|
||||
CountBits(0xffff) = 16
|
||||
CountBits(0x000fffff) = 20
|
||||
CountBits(0x00ffffff) = 24
|
||||
CountBits(0x0fffffff) = 28
|
||||
CountBits(0xffffffff) = 32
|
||||
====================
|
||||
CountBits64(0x00000001ffffffff) = 33
|
||||
CountBits64(0x0000000fffffffff) = 36
|
||||
CountBits64(0x000000ffffffffff) = 40
|
||||
CountBits64(0x00000fffffffffff) = 44
|
||||
CountBits64(0x0000ffffffffffff) = 48
|
||||
CountBits64(0x000fffffffffffff) = 52
|
||||
CountBits64(0x00ffffffffffffff) = 56
|
||||
CountBits64(0x0fffffffffffffff) = 60
|
||||
CountBits64(0xffffffffffffffff) = 64
|
||||
|
|
@ -202,6 +202,47 @@ inline bool FitsInInt64(double x)
|
|||
return x >= -9223372036854775808.0 && x < 9223372036854775808.0;
|
||||
}
|
||||
|
||||
force_inline
|
||||
int CountBits(dword mask)
|
||||
{
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
return __builtin_popcount(mask);
|
||||
#elif defined(_MSC_VER)
|
||||
return __popcnt(mask);
|
||||
#else
|
||||
// Fallback (unlikely)
|
||||
mask = mask - ((mask >> 1) & 0x55555555);
|
||||
mask = (mask & 0x33333333) + ((mask >> 2) & 0x33333333);
|
||||
mask = (mask + (mask >> 4)) & 0x0F0F0F0F;
|
||||
mask = mask + (mask >> 8);
|
||||
mask = mask + (mask >> 16);
|
||||
return mask & 0x3F;
|
||||
#endif
|
||||
}
|
||||
|
||||
force_inline
|
||||
int CountBits64(uint64 mask)
|
||||
{
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
return __builtin_popcountll(mask);
|
||||
#elif defined(_MSC_VER)
|
||||
#if defined(_WIN64)
|
||||
return __popcnt64(mask);
|
||||
#else
|
||||
return CountBits(static_cast<dword>(mask)) + CountBits(static_cast<dword>(mask >> 32));
|
||||
#endif
|
||||
#else
|
||||
// Fallback (unlikely)
|
||||
mask = mask - ((mask >> 1) & 0x5555555555555555ULL);
|
||||
mask = (mask & 0x3333333333333333ULL) + ((mask >> 2) & 0x3333333333333333ULL);
|
||||
mask = (mask + (mask >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
|
||||
mask = mask + (mask >> 8);
|
||||
mask = mask + (mask >> 16);
|
||||
mask = mask + (mask >> 32);
|
||||
return mask & 0x7F;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__SIZEOF_INT128__) && (__GNUC__ > 5 || __clang_major__ >= 5)
|
||||
|
||||
#ifdef CPU_X86
|
||||
|
|
|
|||
|
|
@ -132,6 +132,13 @@ for binary value 1010, this value is 4. For 0, the value is 0.&]
|
|||
loosing the precision.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:Upp`:`:CountBits`(dword`): [@(0.0.255) int] [* CountBits]([_^Upp`:`:dword^ dword]
|
||||
[*@3 mask])&]
|
||||
[s5;:Upp`:`:CountBits64`(uint64`): [@(0.0.255) int] [* CountBits64]([_^Upp`:`:uint64^ uint6
|
||||
4] [*@3 mask])&]
|
||||
[s2;%% Returns the total number of set bits in a given bit [%-*@3 mask].&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Upp`:`:Peek16le`(const void`*`): [@(0.0.255) int]_[* Peek16le]([@(0.0.255) const]_[@(0.0.255) v
|
||||
oid]_`*[*@3 ptr])&]
|
||||
[s5;:Upp`:`:Peek32le`(const void`*`): [@(0.0.255) int]_[* Peek32le]([@(0.0.255) const]_[@(0.0.255) v
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue