Grant Osborne wrote:Are you still having a problem with your rook multiplier for square number 27 or is it fixed now?
Well, I replaced it with the multiplier that I posted. That works. But if yours is really buggy it's strange that noone before me noticed that.
I believe that this program demonstrates the bug:
- Code: Select all
#include <iostream>
typedef unsigned long long U64;
const U64 d2 = 1ULL<<(1*8+3);
const U64 d7 = 1ULL<<(6*8+3);
const U64 magic = 0x0F4A2006C2001602ULL;
//const U64 magic = 0x0021000800001001ULL;
const int shift = 22;
U64 index (U64 occ)
{
unsigned int lo = (int)(occ) * (int)(magic);
unsigned int hi = (int)(occ >> 32) * (int)(magic >> 32);
return (lo ^ hi) >> shift;
}
int main ()
{
if (index(d2) == index(d2|d7))
std::cout << "multiplier is broken" << std::endl;
}
Since I discovered that the shift can be incorporated in the multiplier,
Interesting idea. Saves one memory access. But aren't the shifts in cache anyway? Then I would assume that a lookup in a separate table is faster then extracting the shift from the multiplier. Have you done tests?
I found that the better magics are the more dense ones for a smaller table.
Sure. I meant that I prefer multipliers with fewer bits set (as in 0x0021000800001001 compared to 0x0F4A2006C2001602) when the shifts are the same. With "sparse" I refered to "fewer bits set in multiplier" not "more remaining bits after shift".
But the reason for replacing the multiplier was that I believe that the latter multiplier is broken. So I computed a correct one with pencil and paper, and I am unable to find multipliers with many bits set this way.