Core: CountTrailingZeroBits, CountTrailingZeroBits64

This commit is contained in:
Mirek Fidler 2025-03-31 11:31:21 +02:00
parent f6a6a4da1f
commit e2cf21ba7a
5 changed files with 198 additions and 1 deletions

View file

@ -0,0 +1,24 @@
#include <Core/Core.h>
using namespace Upp;
CONSOLE_APP_MAIN
{
StdLogSetup(LOG_FILE|LOG_COUT);
for(int i = 0; i < 32; i++)
DLOG(i << " " << CountTrailingZeroBits(1 << i));
DDUMP(CountTrailingZeroBits(0x78));
DDUMP(CountTrailingZeroBits(0xf000));
DDUMP(CountTrailingZeroBits(0xf0000000));
for(int i = 0; i < 64; i++)
DLOG(i << " " << CountTrailingZeroBits64((uint64)1 << i));
DDUMP(CountTrailingZeroBits64(0x78));
DDUMP(CountTrailingZeroBits64(0xf000));
DDUMP(CountTrailingZeroBits64(0xf0000000));
DDUMP(CountTrailingZeroBits64(0xf0000000f0000000));
DDUMP(CountTrailingZeroBits64(0xf000000000000000));
CheckLogEtalon();
}

View file

@ -0,0 +1,10 @@
uses
Core;
file
Etalon.log,
CountTrailingZeroBits.cpp;
mainconfig
"" = "";

View file

@ -0,0 +1,106 @@
* C:\upp\out\autotest\CLANGx64.Debug.Debug_Full\CountTrailingZeroBits.exe 31.03.2025 11:30:38, user: mirek
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10
11 11
12 12
13 13
14 14
15 15
16 16
17 17
18 18
19 19
20 20
21 21
22 22
23 23
24 24
25 25
26 26
27 27
28 28
29 29
30 30
31 31
CountTrailingZeroBits(0x78) = 3
CountTrailingZeroBits(0xf000) = 12
CountTrailingZeroBits(0xf0000000) = 28
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 10
11 11
12 12
13 13
14 14
15 15
16 16
17 17
18 18
19 19
20 20
21 21
22 22
23 23
24 24
25 25
26 26
27 27
28 28
29 29
30 30
31 31
32 32
33 33
34 34
35 35
36 36
37 37
38 38
39 39
40 40
41 41
42 42
43 43
44 44
45 45
46 46
47 47
48 48
49 49
50 50
51 51
52 52
53 53
54 54
55 55
56 56
57 57
58 58
59 59
60 60
61 61
62 62
63 63
CountTrailingZeroBits64(0x78) = 3
CountTrailingZeroBits64(0xf000) = 12
CountTrailingZeroBits64(0xf0000000) = 28
CountTrailingZeroBits64(0xf0000000f0000000) = 28
CountTrailingZeroBits64(0xf000000000000000) = 60

View file

@ -243,6 +243,55 @@ int CountBits64(uint64 mask)
#endif
}
force_inline
int CountTrailingZeroBits(dword x)
{
#if COMPILER_GCC && !defined(flagLEGACY_CPU)
return __builtin_ctz(x);
#elif COMPILER_MSC && !defined(flagLEGACY_CPU)
unsigned long index;
_BitScanForward(&index, x);
return index;
#else
// unlikely fallback
int ret = 0;
if((x & 0xffff) == 0) {
x >>= 16;
ret += 16;
}
if((x & 0xff) == 0) {
x >>= 8;
ret += 8;
}
if((x & 0xf) == 0) {
x >>= 4;
ret += 4;
}
if((x & 0x3) == 0) {
x >>= 2;
ret += 2;
}
if((x & 0x1) == 0)
ret += 1;
return ret;
#endif
}
force_inline
int CountTrailingZeroBits64(uint64 x)
{
#if COMPILER_GCC && !defined(flagLEGACY_CPU)
return __builtin_ctzll(x);
#elif COMPILER_MSC && !defined(flagLEGACY_CPU)
unsigned long index;
_BitScanForward64(&index, x);
return index;
#else
// unlikely fallback
return (x & 0xffffffff) ? CountTrailingZeroBits((dword)x) : CountTrailingZeroBits((dword)(x >> 32)) + 32;
#endif
}
#if defined(__SIZEOF_INT128__) && (__GNUC__ > 5 || __clang_major__ >= 5)
#ifdef CPU_X86

View file

@ -114,7 +114,7 @@ onst]_[@(0.0.255) void]_`*[*@3 ptr], [_^size`_t^ size`_t]_[*@3 size])&]
word]_[*@3 h])&]
[s2;%% This functions `"hashes all bits together`". One purpose is
to bring the entropy of higher bits down so that the hash can
be limited by masking, other purpose is to provide hash for integral
be limited by masking, other purpose is to provide hash for integer
numbers.&]
[s2;%% &]
[s4; &]
@ -139,6 +139,14 @@ loosing the precision.&]
[s2;%% Returns the total number of set bits in a given bit [%-*@3 mask].&]
[s3; &]
[s4; &]
[s5;:Upp`:`:CountTrailingZeroBits`(dword`): [@(0.0.255) int] [* CountTrailingZeroBits](dw
ord [*@3 x])&]
[s5;:Upp`:`:CountTrailingZeroBits64`(uint64`): [@(0.0.255) int] [* CountTrailingZeroBits6
4](uint64 [*@3 x])&]
[s2; [%% Returns the index of first non`-zero bit in (from least significant
bit). If] [*@3 x] is zero, the result is undefined.&]
[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