Remove LSB: b &= b-1
Is there an equivalent trick to remove the MSB ?
Remove MSB
Moderator: Ras
-
lucasart
- Posts: 3243
- Joined: Mon May 31, 2010 1:29 pm
- Full name: lucasart
Remove MSB
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
-
cdani
- Posts: 2204
- Joined: Sat Jan 18, 2014 10:24 am
- Location: Andorra
Re: Remove MSB
I only know thinks more complicated like thins one:
unsigned resetLeadingBit(x) {
return x & ~(0x80000000U >> _BitScanReverse(x))
}
unsigned resetLeadingBit(x) {
return x & ~(0x80000000U >> _BitScanReverse(x))
}
Daniel José -
http://www.andscacs.com
-
lucasart
- Posts: 3243
- Joined: Mon May 31, 2010 1:29 pm
- Full name: lucasart
Re: Remove MSB
That's not a trick. You're calling _BitScanReverse() = msb().cdani wrote:I only know thinks more complicated like thins one:
unsigned resetLeadingBit(x) {
return x & ~(0x80000000U >> _BitScanReverse(x))
}
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: 2674
- Joined: Fri Nov 26, 2010 2:00 pm
- Location: Czech Republic
- Full name: Martin Sedlak
Re: Remove MSB
No, his code is right (if x is 32-bit), I would probably prefer doing x & ((~0ull>>1)>>bsr),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.
_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).
-
hgm
- Posts: 28461
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: Remove MSB
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).
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: 751
- Joined: Tue May 22, 2007 11:13 am
Re: Remove MSB
Finding msb is Log(N), not N log(N)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).
-
hgm
- Posts: 28461
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: Remove MSB
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: 751
- Joined: Tue May 22, 2007 11:13 am
Re: Remove MSB
In fact, the log base 2 is equal to the msbhgm 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.
-
Sven
- Posts: 4052
- Joined: Thu May 15, 2008 9:57 pm
- Location: Berlin, Germany
- Full name: Sven Schüle
Re: Remove MSB
See also various implementations of "bitScanReverse" in https://chessprogramming.wikispaces.com/BitScanRein Halbersma wrote:In fact, the log base 2 is equal to the msbhgm 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.
-
Henk
- Posts: 7251
- Joined: Mon May 27, 2013 10:31 am
Re: Remove MSB
Yes I used:Rein Halbersma wrote:In fact, the log base 2 is equal to the msbhgm 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.
Code: Select all
public class BitBoardBackwardIterator: IBitBoardIterator
{
UInt64 bits;
public void Reset(UInt64 bits)
{
this.bits = bits;
}
public UInt64 Next()
{
while (bits != 0)
{
int index = (int)Math.Log(bits, 2);
UInt64 bit = ((UInt64)1 << index);
bits &= ~bit;
return bit;
}
return 0;
}
}