Remove MSB

Discussion of chess software programming and technical issues.

Moderators: hgm, Dann Corbit, Harvey Williamson

User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

Remove MSB

Post by lucasart »

Remove LSB: b &= b-1

Is there an equivalent trick to remove the MSB ?
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
User avatar
cdani
Posts: 2204
Joined: Sat Jan 18, 2014 10:24 am
Location: Andorra

Re: Remove MSB

Post by cdani »

I only know thinks more complicated like thins one:

unsigned resetLeadingBit(x) {
return x & ~(0x80000000U >> _BitScanReverse(x))
}
User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

Re: Remove MSB

Post by lucasart »

cdani wrote:I only know thinks more complicated like thins one:

unsigned resetLeadingBit(x) {
return x & ~(0x80000000U >> _BitScanReverse(x))
}
That's not a trick. You're calling _BitScanReverse() = msb().

And I think your code is wrong. It shoud be 1ULL << msb(x), not 0x80000000ULL >> msb(x).

Perhaps there is no trick, and x &= ~(1ULL << msb(x)) is the way to go.
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
mar
Posts: 2552
Joined: Fri Nov 26, 2010 2:00 pm
Location: Czech Republic
Full name: Martin Sedlak

Re: Remove MSB

Post by mar »

lucasart wrote:That's not a trick. You're calling _BitScanReverse() = msb().

And I think your code is wrong. It shoud be 1ULL << msb(x), not 0x80000000ULL >> msb(x).

Perhaps there is no trick, and x &= ~(1ULL << msb(x)) is the way to go.
No, his code is right (if x is 32-bit), I would probably prefer doing x & ((~0ull>>1)>>bsr),
_BitScanReverse is equivalent to builtin_clz (and so is the x86 bsr instruction)

The question is interesting though.
Since ARM has no CTZ instruction, well... Unfortunately most common versions are only 32 bit...
I tried using builtin_ctz recently and found it superior to builtin_ffs (at least with gcc) on ARM (I used a specialized two part 32-bit version),
the compiler somehow managed to transform it into CLZ but I couldn't find rbit (bit reversal instruction).
I haven't examined the assembly further, but it looked pretty good to me (nicer than ffs).
User avatar
hgm
Posts: 27701
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Remove MSB

Post by hgm »

No such trick; carry propagates from lower to higher significance.

Without specialized instructions to do this, the fastest way would be to invert the bit order (which is an N log(N) process) and extract the LSB. Or perhaps a binary search on the bit, which also takes N log(N).
Rein Halbersma
Posts: 741
Joined: Tue May 22, 2007 11:13 am

Re: Remove MSB

Post by Rein Halbersma »

hgm wrote:No such trick; carry propagates from lower to higher significance.

Without specialized instructions to do this, the fastest way would be to invert the bit order (which is an N log(N) process) and extract the LSB. Or perhaps a binary search on the bit, which also takes N log(N).
Finding msb is Log(N), not N log(N)
User avatar
hgm
Posts: 27701
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Remove MSB

Post by hgm »

Oops, you are right. I ignored that N bits are done in parallel. And without that it would of course just be O(N), as you would simply scan.
Rein Halbersma
Posts: 741
Joined: Tue May 22, 2007 11:13 am

Re: Remove MSB

Post by Rein Halbersma »

hgm wrote:Oops, you are right. I ignored that N bits are done in parallel. And without that it would of course just be O(N), as you would simply scan.
In fact, the log base 2 is equal to the msb :)
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Remove MSB

Post by Sven »

Rein Halbersma wrote:
hgm wrote:Oops, you are right. I ignored that N bits are done in parallel. And without that it would of course just be O(N), as you would simply scan.
In fact, the log base 2 is equal to the msb :)
See also various implementations of "bitScanReverse" in https://chessprogramming.wikispaces.com/BitScan
Henk
Posts: 7210
Joined: Mon May 27, 2013 10:31 am

Re: Remove MSB

Post by Henk »

Rein Halbersma wrote:
hgm wrote:Oops, you are right. I ignored that N bits are done in parallel. And without that it would of course just be O(N), as you would simply scan.
In fact, the log base 2 is equal to the msb :)
Yes I used:

Code: Select all

    public class BitBoardBackwardIterator&#58; IBitBoardIterator
    &#123;
        UInt64 bits;


        public void Reset&#40;UInt64 bits&#41;
        &#123;
            this.bits = bits;
        &#125;

        public UInt64 Next&#40;)
        &#123;
            while &#40;bits != 0&#41;
            &#123;
                int index = &#40;int&#41;Math.Log&#40;bits, 2&#41;;
                UInt64 bit = (&#40;UInt64&#41;1 << index&#41;;

                bits &= ~bit;
                return bit;
            &#125;
            return 0;
       &#125;
    &#125;