chess:programming:lsb_least_significant_bit
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
chess:programming:lsb_least_significant_bit [2021/10/30 11:09] – peter | chess:programming:lsb_least_significant_bit [2021/10/30 13:11] (current) – peter | ||
---|---|---|---|
Line 19: | Line 19: | ||
---- | ---- | ||
- | ===== Using a Loop ===== | + | ===== Using Bit-wise operations |
<code cpp> | <code cpp> | ||
- | int getLSB(ulong v) | + | ulong lsb = x & ~(x-1); |
+ | </ | ||
+ | |||
+ | ---- | ||
+ | |||
+ | ===== Using Bit Manipulation ===== | ||
+ | |||
+ | <code cpp> | ||
+ | UINT64 countTrailingZeros(UINT64 input) | ||
{ | { | ||
- | | + | |
- | | + | return 64; |
- | { | + | |
- | lsb++; | + | UINT64 n = 0; |
- | } | + | |
- | return | + | |
+ | if ((input & 0xFFFF) | ||
+ | if ((input & 0xFF) == 0) { n = n + 8; input = input >> 8; } | ||
+ | | ||
+ | if ((input & 3) == 0) { n = n + 2; input = input >> 2; } | ||
+ | | ||
+ | |||
+ | return | ||
} | } | ||
</ | </ | ||
- | |||
- | <WRAP info> | ||
- | **NOTE: | ||
- | </ | ||
---- | ---- | ||
- | ===== Using Logs ===== | + | ===== Using Builtin |
+ | |||
+ | GCC has **< | ||
<code cpp> | <code cpp> | ||
- | int lsb = (int)(Math.Log(v, | + | lsb = __builtin_clz(pos); |
</ | </ | ||
---- | ---- | ||
+ | |||
+ | |||
===== Using de Bruijn ===== | ===== Using de Bruijn ===== | ||
Line 72: | Line 87: | ||
} | } | ||
</ | </ | ||
+ | |||
+ | <WRAP info> | ||
+ | **NOTE: | ||
+ | |||
+ | * The De Bruijn lookup table needs to be pre-calculated. | ||
+ | * See: https:// | ||
+ | |||
+ | </ | ||
---- | ---- | ||
- | ===== Using Bit Manipulation | + | |
+ | ===== Using Logs ===== | ||
<code cpp> | <code cpp> | ||
- | UINT64 countTrailingZeros(UINT64 input) | + | int lsb = (int)(Math.Log(v, |
- | { | + | </ |
- | if (input == 0) | + | |
- | | + | |
- | UINT64 n = 0; | + | ---- |
- | if ((input & 0xFFFFFFFF) | + | ===== Using a Loop ===== |
- | if ((input & 0xFFFF) | + | |
- | if ((input & 0xFF) == 0) { n = n + 8; input = input >> 8; } | + | |
- | if ((input & 0xF) == 0) { n = n + 4; input = input >> 4; } | + | |
- | if ((input & 3) == 0) { n = n + 2; input = input >> 2; } | + | |
- | if ((input & 1) == 0) { ++n; } | + | |
- | | + | <code cpp> |
+ | int getLSB(ulong v) | ||
+ | { | ||
+ | int lsb = 0; | ||
+ | while ((v >>= 1) != 0) | ||
+ | { | ||
+ | lsb++; | ||
+ | } | ||
+ | | ||
} | } | ||
</ | </ | ||
+ | |||
+ | <WRAP info> | ||
+ | **NOTE: | ||
+ | </ | ||
---- | ---- | ||
Line 130: | Line 159: | ||
</ | </ | ||
+ | ---- | ||
+ | |||
+ | ===== Using the integer log base 2 of an integer with an 64-bit IEEE float ===== | ||
+ | |||
+ | TODO | ||
+ | |||
+ | <code cpp> | ||
+ | int v; // 32-bit integer to find the log base 2 of | ||
+ | int r; // result of log_2(v) goes here | ||
+ | union { unsigned int u[2]; double d; } t; // temp | ||
+ | |||
+ | t.u[__FLOAT_WORD_ORDER==LITTLE_ENDIAN] = 0x43300000; | ||
+ | t.u[__FLOAT_WORD_ORDER!=LITTLE_ENDIAN] = v; | ||
+ | t.d -= 4503599627370496.0; | ||
+ | r = (t.u[__FLOAT_WORD_ORDER==LITTLE_ENDIAN] >> 20) - 0x3FF; | ||
+ | </ | ||
+ | |||
+ | <WRAP info> | ||
+ | **NOTE: | ||
+ | |||
+ | * From this newly minted double, 2^52 (expressed as a double) is subtracted, which sets the resulting exponent to the log base 2 of the input value, v. | ||
+ | * All that is left is shifting the exponent bits into position (20 bits right) and subtracting the bias, 0x3FF (which is 1023 decimal). | ||
+ | * This technique only takes 5 operations, but many CPUs are slow at manipulating doubles, and the endianess of the architecture must be accommodated. | ||
+ | |||
+ | </ | ||
---- | ---- | ||
Line 135: | Line 189: | ||
===== References ===== | ===== References ===== | ||
- | https://docs.microsoft.com/en-us/cpp/ | + | http://graphics.stanford.edu/~seander/bithacks.html# |
+ | https:// | ||
+ | https:// | ||
+ | |||
+ | https:// |
chess/programming/lsb_least_significant_bit.1635592198.txt.gz · Last modified: 2021/10/30 11:09 by peter