Author: Gerd Isenberg
Date: 14:43:17 06/14/04
Hi all,
i proudly like to present one application of the De Bruijn generator mentioned
recently, to build a "private" bitscan routine as shown by Gian-Carlo:
http://www.talkchess.com/forums/1/message.html?370092
Simply compile the following small program with a C++ compiler and call the
executable with a parameter, a decimal number in the range of 1 until 134217728
(2**27), e.g. a sequence of digits of your birth date or similar ;-)
The output is a C-routine with a rather unique de Bruijn constant and
appropriate lookup table. Depending on the number it may take a few minutes.
Have fun,
Gerd
#include <stdio.h>
#include <stdlib.h>
typedef unsigned __int64 BitBoard; // long long
class GenBitScan
{
public:
GenBitScan(int match4nth)
{
m_Lock = 0;
m_dBCount = 0;
m_Match4nth = match4nth;
m_Found = false;
findDeBruijn(0, 64-6);
}
private:
BitBoard m_Lock;
int m_dBCount;
int m_Match4nth;
bool m_Found;
void bitScanRoutineFound(BitBoard deBruijn)
{
int index[64], i;
for (i=0; i<64; i++)
index[(deBruijn<<i)>>58] = i;
printf("\nconst BitBoard magic = 0x%08x%08x; // the %d.\n\n",
(int)(deBruijn>>32), (int)(deBruijn), m_dBCount);
printf("const unsigned int magictable[64] =\n{\n");
for (i=0; i<64; i++)
{
if ( (i & 7) == 0 ) printf("\n ");
printf(" %2d,", index[i]);
}
printf("\n};\n\nunsigned int bitScan (BitBoard b) {\n");
printf(" return magictable[((b&-b)*magic) >> 58];\n}\n");
m_Found = true;
}
void findDeBruijn(BitBoard seq, int bidx)
{
int uniqueIdx = (int) (seq>>bidx) & (64-1);
BitBoard uniqueBit = (BitBoard)1 << uniqueIdx;
if ( !m_Found && (m_Lock & uniqueBit) == 0 && uniqueIdx != 64/2 )
{
if ( bidx == 0 )
{
if ( ++m_dBCount == m_Match4nth )
bitScanRoutineFound(seq);
if ( ++m_dBCount == m_Match4nth )
bitScanRoutineFound(seq<<1);
}
else if ( bidx == 1 )
{
m_Lock |= uniqueBit;
findDeBruijn(seq | 1, 0);
m_Lock &= ~uniqueBit;
}
else
{
m_Lock |= uniqueBit;
findDeBruijn(seq, bidx-1);
findDeBruijn(seq | ((BitBoard)1<<(bidx-1)), bidx-1);
m_Lock &= ~uniqueBit;
}
}
}
};
int main(int argc, char* argv[])
{
if (argc < 2)
printf("usage: genBitScan 1 .. %d\n", 1<<27);
else
GenBitScan(atoi(argv[1]));
return 0;
}
This page took 0 seconds to execute
Last modified: Thu, 15 Apr 21 08:11:13 -0700
Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.