Here is my 64/6-bit De Bruijn bitScanForward-generator.Aleks Peshkov wrote:Please, show here the smallest one.There are way too many 64-bit magics to print out; however, there should be 2^27 magics for 64-bits
Considering only the 2^26 odd sequences with 6 leading binary zeros.
You can call it with 1...67108864 (0x4000000).
0x0218a392cd3d5dbf is the smallest one,
0x03f79d71b4cb0a89 the biggest (odd) one.
Code: Select all
C:\source\deBruijn\Release>debruijn 1
const u64 magic = 0x0218a392cd3d5dbf; // the 1.
const unsigned int magictable[64] =
{
0, 1, 2, 7, 3, 13, 8, 19,
4, 25, 14, 28, 9, 34, 20, 40,
5, 17, 26, 38, 15, 46, 29, 48,
10, 31, 35, 54, 21, 50, 41, 57,
63, 6, 12, 18, 24, 27, 33, 39,
16, 37, 45, 47, 30, 53, 49, 56,
62, 11, 23, 32, 36, 44, 52, 55,
61, 22, 43, 51, 60, 42, 59, 58,
};
unsigned int bitScanForward (u64 b) {
return magictable[((b&-b)*magic) >> 58];
}
Code: Select all
C:\source\deBruijn\Release>debruijn 67108864
const u64 magic = 0x03f79d71b4cb0a89; // the 67108864.
const unsigned int magictable[64] =
{
0, 1, 48, 2, 57, 49, 28, 3,
61, 58, 50, 42, 38, 29, 17, 4,
62, 55, 59, 36, 53, 51, 43, 22,
45, 39, 33, 30, 24, 18, 12, 5,
63, 47, 56, 27, 60, 41, 37, 16,
54, 35, 52, 21, 44, 32, 23, 11,
46, 26, 40, 15, 34, 20, 31, 10,
25, 14, 19, 9, 13, 8, 7, 6,
};
unsigned int bitScanForward (u64 b) {
return magictable[((b&-b)*magic) >> 58];
}
Code: Select all
#include <stdio.h>
#include <stdlib.h>
typedef unsigned __int64 u64; // long long
class GenBitScan
{
public:
GenBitScan(int match4nth)
{
m_Lock = 0;
m_dBCount = 0;
m_Match4nth = match4nth;
initPow2();
try {findDeBruijn(0, 64-6, 0);} catch(int){}
}
private:
u64 pow2[64];
u64 m_Lock;
int m_dBCount;
int m_Match4nth;
void initPow2() {
for (int i=0; i < 64; i++)
pow2[i] = (u64)1 << i;
}
virtual void bitScanRoutineFound(u64 deBruijn)
{
int index[64], i;
for (i=0; i<64; i++) // init magic array
index[ (deBruijn<<i) >> (64-6) ] = i;
printf("\nconst u64 magic = 0x%08x%08x; // the %d.\n\n",
(int)(deBruijn>>32), (int)(deBruijn), m_dBCount);
printf("const unsigned int magictable[64] =\n{");
for (i=0; i<64; i++)
{
if ( (i & 7) == 0 ) printf("\n ");
printf(" %2d,", index[i]);
}
printf("\n};\n\nunsigned int bitScanForward (u64 b) {\n");
printf(" return magictable[((b&-b)*magic) >> 58];\n}\n");
throw 0; // unwind the stack until catched
}
void findDeBruijn(u64 seq, int depth, int unique)
{
if ( (m_Lock & pow2[unique]) == 0 && unique != 32)
{
if ( depth == 0 )
{
if ( ++m_dBCount == m_Match4nth )
bitScanRoutineFound(seq);
}
else
{
m_Lock ^= pow2[unique];
if ( depth > 2 && unique == 31 )
{
findDeBruijn(seq | pow2[depth-1], depth-2, 62);
}
else
{
if ( depth > 1 )
findDeBruijn(seq, depth-1, (unique*2)&63);
findDeBruijn(seq | pow2[depth-1], depth-1, (unique*2+1)&63);
}
m_Lock ^= pow2[unique];
}
}
}
};
int main(int argc, char* argv[])
{
if (argc < 2)
printf("usage: genBitScan 1 .. %d\n", 1<<26);
else
GenBitScan(atoi(argv[1]));
return 0;
}
2^26 ways to traverse it...
Code: Select all
.->-a1-------------------------->--\../--<-----------------------------\
....^...............................b1.................................|
....|..............c1--------------/..\-------------d1.................|
....|......e1-----/..\-----f1...............g1-----/..\-----h1.........|
....|..a2-/..\-b2......c2-/..\-d2.......e2-/..\-f2......g2-/..\-h2.....|
....|a3..b3..c3..d3..e3.|f3|.g3..h3...a4..b4..c4..d4..e4..f4..g4..h4...|
....a5b5c5d5e5f5g5h5a6b6c6d6e6f6g6h6.a7b7c7d7e7f7g7h7a8b8c8d8e8f8..h8..|
....../\/\/\/\/\/\/\/\/\.\/\/\/\/\/\./\/\/\/\/\/\/\/\/\/\/\/\/\/\..|...|
...................................................................|...|
....................................../--<-------------------------/...^
....................................g8.................................|
...................f8--------------/..\-------------e8.................|
...........d8-----/..\-----c8...............b8-----/..\-----a8.........|
.......h7-/..\-g7......f7-/..\-e7.......d7-/..\-c7......b7-/..\-a7.....|
.....h6..g6..f6..e6..d6.|c6|.b6..a6...h5..g5..f5..e5..d5..c5..b5..a5...|
....h4g4f4e4d4c4b4a4h3g3f3e3d3c3b3a3.h2g2f2e2d2c2b2a2h1g1f1e1d1c1..a1..|
.....\/\/\/\/\/\/\/\/\/\.\/\/\/\/\/\./\/\/\/\/\/\/\/\/\/\/\/\/\/\...\--/