Find first set
In computer software and hardware, find first set (ffs) or find first one is a bit operation that, given an unsigned machine word,[1] designates the index or position of the least significant bit set to one in the word counting from the least significant bit position. A nearly equivalent operation is count trailing zeros (ctz) or number of trailing zeros (ntz), which counts the number of zero bits following the least significant one bit. The complementary operation that finds the index or position of the most significant set bit is log base 2, so called because it computes the binary logarithm .[2] This is closely related to count leading zeros (clz) or number of leading zeros (nlz), which counts the number of zero bits preceding the most significant one bit. [3] There are two common variants of find first set, the POSIX definition which starts indexing of bits at 1,[4] herein labelled ffs, and the variant which starts indexing of bits at zero, which is equivalent to ctz and so will be called by that name.
Most modern CPU operator sets provide one or more of these as hardware operators; software emulation is usually provided for any that aren't available, either as compiler intrinsics or in system libraries.
Examples
Given the following 32-bit word:
00000000000000001000000000001000
The count trailing zeros operation would return 3, while the count leading zeros operation returns 16. The count leading zeros operation depends on the word size: if this 32-bit word were truncated to a 16-bit word, count leading zeros would return zero. The find first set operation would return 4, indicating the 4th position from the right. The log base 2 is 15.
Similarly, given the following 32-bit word, the bitwise negation of the above word:
11111111111111110111111111110111
The count trailing ones operation would return 3, the count leading ones operation would return 16, and the find first zero operation ffz would return 4.
If the word is zero (no bits set), count leading zeros and count trailing zeros both return the number of bits in the word, while ffs returns zero. Both log base 2 and zero-based implementations of find first set generally return an undefined result for the zero word.
Hardware support
Many architectures include instructions to rapidly perform find first set and/or related operations, listed below. The most common operation is count leading zeros (clz), likely because all other operations can be implemented efficiently in terms of it (see Properties and relations).
Platform | Mnemonic | Name | Operand widths | Description | Result of operating on 0 |
---|---|---|---|---|---|
ARM (ARMv5T architecture and later) except Cortex-M0/M0+/M1/M23 | clz[5] | Count Leading Zeros | 32 | clz | 32 |
ARM (ARMv8-A architecture) | clz | Count Leading Zeros | 32, 64 | clz | Operand width |
AVR32 | clz[6] | Count Leading Zeros | 32 | clz | 32 |
DEC Alpha | ctlz[7] | Count Leading Zeros | 64 | clz | 64 |
cttz[7] | Count Trailing Zeros | 64 | ctz | 64 | |
Intel 80386 and later | bsf[8] | Bit Scan Forward | 16, 32, 64 | ctz | Undefined; sets zero flag |
bsr[8] | Bit Scan Reverse | 16, 32, 64 | Log base 2 | Undefined; sets zero flag | |
x86 supporting ABM | lzcnt[9] | Count Leading Zeros | 16, 32, 64 | clz | Operand width; sets carry flag |
x86 supporting BMI1 | tzcnt[10] | Count Trailing Zeros | 16, 32, 64 | ctz | Operand width; sets carry flag |
Itanium | clz[11] | Count Leading Zeros | 64 | clz | 64 |
MIPS | clz[12][13] | Count Leading Zeros in Word | 32, 64 | clz | Operand width |
clo[12][13] | Count Leading Ones in Word | 32, 64 | clo | Operand width | |
Motorola 68020 and later | bfffo[14] | Find First One in Bit Field | Arbitrary | Log base 2 | Field offset + field width |
PDP-10 | jffo | Jump if Find First One | 36 | ctz | 0; no operation |
POWER/PowerPC/Power ISA | cntlz/cntlzw/cntlzd[15] | Count Leading Zeros | 32, 64 | clz | Operand width |
Power ISA 3.0 and later | cnttzw/cnttzd[16] | Count Trailing Zeros | 32, 64 | ctz | Operand width |
RISC-V ("B" Extension) (draft) | clz[17] | Count Leading Zeros | TBD | clz | Operand width |
ctz[17] | Count Trailing Zeros | TBD | ctz | Operand width | |
SPARC Oracle Architecture 2011 and later | lzcnt (synonym: lzd) [18] | Leading Zero Count | 64 | clz | 64 |
VAX | ffs[19] | Find First Set | 0–32 | ctz | Operand width; sets zero flag |
z/Architecture | vclz[20] | Vector Count Leading Zeroes | 8, 16, 32, 64 | clz | Operand width |
vctz[21] | Vector Count Trailing Zeroes | 8, 16, 32, 64 | ctz | Operand width |
On some Alpha platforms CTLZ and CTTZ are emulated in software.
Tool and library support
A number of compiler and library vendors supply compiler intrinsics or library functions to perform find first set and/or related operations, which are frequently implemented in terms of the hardware instructions above:
Tool/library | Name | Type | Input type(s) | Notes | Result for zero input |
---|---|---|---|---|---|
POSIX.1 compliant libc 4.3BSD libc OS X 10.3 libc[4][22] | ffs | Library function | int | Includes glibc. POSIX does not supply the complementary log base 2 / clz. | 0 |
FreeBSD 5.3 libc OS X 10.4 libc[23] | ffsl fls flsl | Library function | int, long | fls ("find last set") computes (log base 2) + 1. | 0 |
FreeBSD 7.1 libc[24] | ffsll flsll | Library function | long long | 0 | |
GCC 3.4.0[25][26] Clang 5.x [27][28] |
__builtin_ffs[l,ll,imax] __builtin_clz[l,ll,imax] __builtin_ctz[l,ll,imax] | Built-in functions | unsigned int, unsigned long, unsigned long long, uintmax_t | GCC documentation considers result undefined clz and ctz on 0. | 0 (ffs) |
Visual Studio 2005 | _BitScanForward [29]_BitScanReverse [30] | Compiler intrinsics | unsigned long, unsigned __int64 | Separate return value to indicate zero input | 0 |
Visual Studio 2008 | __lzcnt [31] | Compiler intrinsic | unsigned short, unsigned int, unsigned __int64 | Relies on x64-only lzcnt instruction | Input size in bits |
Intel C++ Compiler | _bit_scan_forward _bit_scan_reverse [32] | Compiler intrinsics | int | Undefined | |
NVIDIA CUDA[33] | __clz |
Functions | 32-bit, 64-bit | Compiles to fewer instructions on the GeForce 400 Series | 32 |
__ffs | 0 | ||||
LLVM | llvm.ctlz.* llvm.cttz.* [34] | Intrinsic | 8, 16, 32, 64, 256 | LLVM assembly language | Input size if arg 2 is 0, else undefined |
GHC 7.10 (base 4.8), in Data.Bits | countLeadingZeros countTrailingZeros | Library function | FiniteBits b => b | Haskell programming language | Input size in bits |
Properties and relations
If bits are labeled starting at 1 (which is the convention used in this article), then count trailing zeros and find first set operations are related by ctz(x) = ffs(x) − 1 (except when the input is zero). If bits are labeled starting at 0, then count trailing zeros and find first set are exactly equivalent operations. Given w bits per word, the log_{2} is easily computed from the clz and vice versa by log_{2}(x) = w − 1 − clz(x).
As demonstrated in the example above, the find first zero, count leading ones, and count trailing ones operations can be implemented by negating the input and using find first set, count leading zeros, and count trailing zeros. The reverse is also true.
On platforms with an efficient log_{2} operation such as M68000, ctz can be computed by:
- ctz(x) = log_{2}(x & −x)
where "&" denotes bitwise AND and "−x" denotes the two's complement of x. The expression x & −x clears all but the least-significant 1 bit, so that the most- and least-significant 1 bit are the same.
On platforms with an efficient count leading zeros operation such as ARM and PowerPC, ffs can be computed by:
- ffs(x) = w − clz(x & −x).
Conversely, on machines without log_{2} or clz operators, clz can be computed using ctz, albeit inefficiently:
- clz = w - ctz(2^{${\lceil log_{2}x\rceil }$}) (which depends on ctz returning w for the zero input)
On platforms with an efficient Hamming weight (population count) operation such as SPARC's POPC
[35][36] or Blackfin's ONES
[37], there is:
- ctz(x) = popcount((x & −x) − 1),[38][39]
- ffs(x) = popcount(x ^ ~−x)[40]
- clz = 32 - popcount(2^{${\lceil log_{2}x\rceil }$}-1)
where "^" denotes bitwise exclusive-or and "~" denotes bitwise negation.
The inverse problem (given i, produce an x such that ctz(x) = i) can be computed with a left-shift (1 << i).
Find first set and related operations can be extended to arbitrarily large bit arrays in a straightforward manner by starting at one end and proceeding until a word that is not all-zero (for ffs/ctz/clz) or not all-one (for ffz/clo/cto) is encountered. A tree data structure that recursively uses bitmaps to track which words are nonzero can accelerate this.
Software emulation
Most cpu's dating from the late 1980's onward have bit operators for FFS or equivalent, but a few modern ones like some of the ARM-Mx series, don't. In lieu of hardware operators for ffs, clz and ctz, software can emulate them with shifts, integer arithmetic and bitwise operators. There are several approaches depending on architecture of the CPU and to a lesser extent, the programming language semantics and compiler code generation quality. The approaches may be loosely described as linear search, binary search, search+table lookup, deBruijn multiplication, floating point conversion/exponent extract, and bit operator (branchless) methods. There are tradeoffs between execution time and storage space as well as portability and efficiency.
Software emulations are usually deterministic: they return a defined result for all input values; in particular, the result for an input of all zero bits is usually 0 for ffs, and the bit length of the operand for the other operations.
Note: if one has a hardware clz or equivalent, ctz can be efficiently computed with bit operations, but the converse is NOT true: clz is not efficient to compute in the absence of a hardware operator.
2^{n}
The function 2^{${\lceil log_{2}x\rceil }$} (round up to the nearest power of two) using shifts and bitwise ORs [41] is not efficient to compute as in this 32-bit example and even more inefficient if we have a 64-bit or 128-bit operand:
function pow2(x): if x = 0 return invalid // invalid is implementation defined (not in [0,63]) x ← x - 1 for each y in {1, 2, 4, 8, 16}: x ← x | (x >> y) return x + 1
FFS
Since ffs = ctz + 1 (Posix) or ffs = ctz (other implementations), the applicable algorithms for ctz may be used, with a possible final step of adding 1 to the result, and returning 0 instead of the operand length for input of all zero bits.
CTZ
The canonical algorithm is a loop counting zeros starting at the LSB until a 1-bit is encountered:
function ctz (x) if x = 0 return w t ← 1 r ← 0 while (x & t) = 0 t ← t << 1 r ← r + 1 return r
This algorithm executes O(n) time and operations, and is impractical in practice due to a large number of conditional branches.
A lookup table can eliminate most branches:
table[0..2^{n}-1] = ctz(i) for i in 0..2^{n}-1 function ctz_table (x) if x = 0 return w r ← 0 loop if (x & (2^{n}-1)) ≠ 0 return r + table[x & (2^{n}-1)] x ← x >> n r ← r + n
The parameter n is fixed (typically 8) and represents a time–space tradeoff. The loop may also be fully unrolled. But as a linear lookup, this approach is still O(n) in the number of bits in the operand.
A binary search implementation takes a logarithmic number of operations and branches, as in this 32-bit version:[42][43] This algorithm can be assisted by a table as well, replacing the bottom three "if" statements with a 256 entry lookup table using the first non-zero byte encountered as an index.
function ctz (x) if x = 0 return 32 n ← 0 if (x & 0x0000FFFF) = 0: n ← n + 16, x ← x >> 16 if (x & 0x000000FF) = 0: n ← n + 8, x ← x >> 8 if (x & 0x0000000F) = 0: n ← n + 4, x ← x >> 4 if (x & 0x00000003) = 0: n ← n + 2, x ← x >> 2 if (x & 0x00000001) = 0: n ← n + 1 return n
If the hardware has a clz operator, the most efficient approach to computing ctz is thus:
function ctz_via_clz (x) x ^= -x return w - (clz(x) + 1)
An algorithm for 32-bit ctz uses de Bruijn sequences to construct a minimal perfect hash function that eliminates all branches.[44] [45] This algorithm assumes that the result of the multiplication is truncated to 32 bit.
for i from 0 to 31: table[ ( 0x077CB531 * ( 1 << i ) ) >> 27 ] ← i // table [0..31] initialized function ctz_debruijn (x) return table[((x & -x) * 0x077CB531) >> 27]
The expression (x & -x) again isolates the least-significant 1 bit. There are then only 32 possible words, which the unsigned multiplication and shift hash to the correct position in the table. (This algorithm does not handle the zero input.)
CLZ
The canonical algorithm examines one bit at a time starting from the MSB until a non-zero bit is found, as shown in this example. It executes in O(n) time where n is the bit-length of the operand, and is not a practical algorithm for general use.
function clz (x) if x = 0 return w t ← 1 << w - 1 r ← 0 while (x & t) = 0 t ← t >> 1 r ← r + 1 return r
An improvement on the previous looping approach examines eight bits at a time then uses a 256 (2^{8}) entry lookup table for the first non-zero byte. This approach, however, is still O(n) in execution time.
function clz (x) if x = 0 return w t ← 0xff << w - 8 r ← 0 while (x & t) = 0 t ← t >> 8 r ← r + 8 return r + table[x>>w-8]
Binary search can reduce execution time to O(log_{2}n):
function clz (x) if x = 0 return 32 n ← 0 if (x & 0xFFFF0000) = 0: n ← n + 16, x ← x << 16 if (x & 0xFF000000) = 0: n ← n + 8, x ← x << 8 if (x & 0xF0000000) = 0: n ← n + 4, x ← x << 4 if (x & 0xC0000000) = 0: n ← n + 2, x ← x << 2 if (x & 0x80000000) = 0: n ← n + 1 return n
The fastest portable approaches to simulate clz are a combination of binary search and table lookup: an 8-bit table lookup (2^{8}=256 1-byte entries) can replace the bottom 3 branches in binary search. 64-bit operands require an additional branch. A larger width lookup can be used but the maximum practical table size is limited by the size of L1 data cache on modern processors, which is 32Kb for many. Saving a branch is more than offset by the latency of an L1 cache miss.
An algorithm similar to de Bruijn multiplication for CTZ works for CLZ, but rather than isolate the most-significant bit, it rounds up to the nearest integer of the form 2^{n}−1 using shifts and bitwise ORs:[46]
table[0..31] = {0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31} function lg_debruijn (x) for each y in {1, 2, 4, 8, 16}: x ← x | (x >> y) return table[(x * 0x07C4ACDD) >> 27]
For processors with deep pipelines, like Prescott and later Intel processors, it may be faster to replace branches by bit-wise AND and OR operators (even though many more instructions are required) to avoid pipeline flushes for mispredicted branches (and these types of branches are inherently unpredictable):
function clz_q (x) r = (x > 0xFFFF) << 4; x >>= r; q = (x > 0xFF ) << 3; x >>= q; r |= q; q = (x > 0xF ) << 2; x >>= q; r |= q; q = (x > 0x3 ) << 1; x >>= q; r |= q; r |= (x >> 1); return r;
On platforms that provide hardware conversion of integers to floating point, the exponent field can be extracted and subtracted from a constant to compute the count of leading zeros. Corrections are needed to account for rounding errors.[42][47] Floating point conversion can have substantial latency. This method is highly non-portable and not usually recommended.
int x;
int r;
union { unsigned int u[2]; double d; } t;
t.u[LE] = 0x43300000; // LE is 1 for little-endian
t.u[!LE] = x;
t.d -= 4503599627370496.0;
r = (t.u[LE] >> 20) - 0x3FF; // log2
r++; // CLZ
Applications
The count leading zeros (clz) operation can be used to efficiently implement normalization, which encodes an integer as m × 2^{e}, where m has its most significant bit in a known position (such as the highest position). This can in turn be used to implement Newton-Raphson division, perform integer to floating point conversion in software, and other applications.[42][48]
Count leading zeros (clz) can be used to compute the 32-bit predicate "x = y" (zero if true, one if false) via the identity clz(x − y) >> 5, where ">>" is unsigned right shift.[49] It can be used to perform more sophisticated bit operations like finding the first string of n 1 bits.[50] The expression 1 << (16 − clz(x − 1)/2) is an effective initial guess for computing the square root of a 32-bit integer using Newton's method.[51] CLZ can efficiently implement null suppression, a fast data compression technique that encodes an integer as the number of leading zero bytes together with the nonzero bytes.[52] It can also efficiently generate exponentially distributed integers by taking the clz of uniformly random integers.[42]
The log base 2 can be used to anticipate whether a multiplication will overflow, since .[53]
Count leading zeros and count trailing zeros can be used together to implement Gosper's loop-detection algorithm,[54] which can find the period of a function of finite range using limited resources.[43]
The binary GCD algorithm spends many cycles removing trailing zeros; this can be replaced by a count trailing zeros (ctz) followed by a shift. A similar loop appears in computations of the hailstone sequence.
A bit array can be used to implement a priority queue. In this context, find first set (ffs) is useful in implementing the "pop" or "pull highest priority element" operation efficiently. The Linux kernel real-time scheduler internally uses sched_find_first_bit()
for this purpose.[55]
The count trailing zeros operation gives a simple optimal solution to the Tower of Hanoi problem: the disks are numbered from zero, and at move k, disk number ctz(k) is moved the minimum possible distance to the right (circling back around to the left as needed). It can also generate a Gray code by taking an arbitrary word and flipping bit ctz(k) at step k.[43]
See also
- Bit Manipulation Instruction Sets for Intel and AMD x86-based processors
References
- Using bit operations on other than an unsigned machine word may yield undefined results
- Anderson, Find the log base 2 of an integer with the MSB N set in O(N) operations (the obvious way)
- These four operations also have (much less common) negated versions:
- find first zero (ffz), which identifies the index of the least significant zero bit;
- count trailing ones, which counts the number of one bits following the least significant zero bit.
- count leading ones, which counts the number of one bits preceding the most significant zero bit;
- find the index of the most significant zero bit, which is an inverted version of the binary logarithm.
- "FFS(3)". Linux Programmer's Manual. The Linux Kernel Archives. Retrieved 2 January 2012.
- "ARM Instruction Reference > ARM general data processing instructions > CLZ". ARM Developer Suite Assembler Guide. ARM. Retrieved 3 January 2012.
- "AVR32 Architecture Document" (PDF). Atmel. Retrieved 2016-10-22.
- Alpha Architecture Reference Manual (PDF). Compaq. 2002. pp. 4–32, 4–34.
- Intel 64 and IA-32 Architectures Software Developer Manual. Volume 2A: Intel. pp. 3–92–3–97. Order number 325383.
- AMD64 Architecture Programmer's Manual Volume 3: General Purpose and System Instructions3 (PDF). AMD. 2011. pp. 204–5.
- "AMD64 Architecture Programmer's Manual, Volume 3: General-Purpose and System Instructions" (PDF). amd.com. AMD. October 2013. Retrieved 2014-01-02.
- Intel Itanium Architecture Software Developer's Manual. Volume 3: Intel Itanium Instruction Set. Intel. 2010. pp. 3:38.
- MIPS Architecture For Programmers. Volume II-A: The MIPS32 Instruction Set (Revision 3.02 ed.). MIPS Technologies. 2011. pp. 101–102.
- MIPS Architecture For Programmers. Volume II-A: The MIPS64 Instruction Set (Revision 3.02 ed.). MIPS Technologies. 2011. pp. 105, 107, 122, 123.
- M68000 Family Programmer's Reference Manual (PDF). Motorola. 1992. pp. 4–43–4–45.
- Frey, Brad. PowerPC Architecture Book (Version 2.02 ed.). 3.3.11 Fixed-Point Logical Instructions: IBM. p. 70.
- Power ISA Version 3.0B. 3.3.13 Fixed-Point Logical Instructions, 3.3.13.1 64-bit Fixed-Point Logical Instructions: IBM. pp. 95, 98.
- Wolf, Clifford (March 22, 2019). "RISC-V "B" Bit Manipulation Extension for RISC-V, Draft v0.37" (PDF). Github. Clifford Wolf.
- Oracle SPARC Architecture 2011. Oracle.
- VAX Architecture Reference Manual (PDF). DEC. 1987. pp. 70–71.
- IBM z/Architecture Principles of Operation (PDF) (Eleventh ed.). Chapter 22. Vector Integer Instructions: IBM. March 2015. p. 22-10.
- IBM z/Architecture Principles of Operation (PDF) (Eleventh ed.). Chapter 22. Vector Integer Instructions: IBM. March 2015. p. 22-10.
- "FFS(3)". Mac OS X Developer Library. Apple, Inc. 1994-04-19. Retrieved 4 January 2012.
- "FFS(3)". Mac OS X Developer Library. Apple. 2004-01-13. Retrieved 4 January 2012.
- "FFS(3)". FreeBSD Library Functions Manual. The FreeBSD Project. Retrieved 4 January 2012.
- "Other built-in functions provided by GCC". Using the GNU Compiler Collection (GCC). Free Software Foundation, Inc. Retrieved 14 November 2015.
- "GCC 3.4.0 ChangeLog". GCC 3.4.0. Free Software Foundation, Inc. Retrieved 14 November 2015.
- "Clang Language Extensions, chapter Builtin Functions". Clang supports a number of builtin library functions with the same syntax as GCC. The Clang Team. Retrieved 9 April 2017.
- "Source code of Clang". LLVM Team, University of Illinois at Urbana-Champaign. Retrieved 9 April 2017.
- "_BitScanForward, _BitScanForward64". Visual Studio 2008: Visual C++: Compiler Intrinsics. Microsoft. Retrieved 21 May 2018.
- "_BitScanReverse, _BitScanReverse64". Visual Studio 2008: Visual C++: Compiler Intrinsics. Microsoft. Retrieved 21 May 2018.
- "__lzcnt16, __lzcnt, __lzcnt64". Visual Studio 2008: Visual C++: Compiler Intrinsics. Microsoft. Retrieved 3 January 2012.
- Intel C++ Compiler for Linux Intrinsics Reference. Intel. 2006. p. 21.
- NVIDIA CUDA Programming Guide (PDF) (Version 3.0 ed.). NVIDIA. 2010. p. 92.
- "'llvm.ctlz.*' Intrinsic, 'llvm.cttz.*' Intrinsic". LLVM Language Reference Manual. The LLVM Compiler Infrastructure. Retrieved 23 February 2016.
- SPARC International, Inc. (1992). "A.41: Population Count. Programming Note" (PDF). The SPARC architecture manual: version 8 (Version 8 ed.). Englewood Cliffs, New Jersey, USA: Prentice Hall. p. 231. ISBN 978-0-13-825001-0.
- Warren, Jr., Henry S. (2013) [2002]. Hacker's Delight (2 ed.). Addison Wesley - Pearson Education, Inc. ISBN 978-0-321-84268-8. 0-321-84268-5.
- Blackfin Instruction Set Reference (Preliminary ed.). Analog Devices. 2001. pp. 8–24. Part Number 82-000410-14.
- Dietz, Henry Gordon. "The Aggregate Magic Algorithms". University of Kentucky.
- Isenberg, Gerd. forward-Index of LS1B by Popcount "BitScanProtected" Check
|url=
value (help). Chess Programming Wiki. Retrieved 3 January 2012. - SPARC International, Inc. (1992). The SPARC architecture manual : version 8 (Version 8. ed.). Englewood Cliffs, N.J.: Prentice Hall. p. 231. ISBN 978-0-13-825001-0. A.41: Population Count. Programming Note.
- Anderson, Round up to the next highest power of 2.
- Warren, Section 5-3: Counting Leading 0's.
- Warren, Section 5-4: Counting Trailing 0's.
- Leiserson, Charles E.; Prokop, Harald; Randall, Keith H. (1998), Using de Bruijn Sequences to Index a 1 in a Computer Word (PDF)
- Busch, Philip (2009), Computing trailing Zeros HOWTO (PDF)
- Anderson, Find the log base 2 of an N-bit integer in O(lg(N)) operations with multiply and lookup
- Anderson, Find the integer log base 2 of an integer with a 64-bit IEEE float.
- Sloss, Andrew N.; Symes, Dominic; Wright, Chris (2004). ARM system developer's guide designing and optimizing system software (1st ed.). San Francisco, CA: Morgan Kaufmann. pp. 212–213. ISBN 978-1-55860-874-0.
- Warren, Section 2-11: Comparison Predicates
- Warren, Section 6-2. Find First String of 1-Bits of a Given Length.
- Warren, 11-1: Integer Square Root.
- Schlegel, Benjamin; Rainer Gemulla; Wolfgang Lehner (June 2010). Fast integer compression using SIMD instructions. Proceedings of the Sixth International Workshop on Data Management on New Hardware (DaMoN 2010). pp. 34–40. CiteSeerX 10.1.1.230.6379. doi:10.1145/1869389.1869394. ISBN 9781450301893.
- Warren, Section 2-12. Overflow Detection.
- Gosper, Bill (1972). "Loop detector". HAKMEM (239): Item 132.
- Aas, Josh (2005). Understanding the Linux 2.6.8.1 CPU Scheduler (PDF). Silicon Graphics, Inc. p. 19.
Further reading
- Warren Jr., Henry S. (2013). Hacker's Delight (2 ed.). Addison Wesley - Pearson Education, Inc. ISBN 978-0-321-84268-8.
- Anderson, Sean Eron. "Bit Twiddling Hacks". Sean Eron Anderson student homepage. Stanford University. Retrieved 3 January 2012. (NB. Lists several efficient public domain C implementations for count trailing zeros and log base 2.)
External links
- Intel Intrinsics Guide
- Chess Programming Wiki: BitScan: A detailed explanation of a number of implementation methods for ffs (called LS1B) and log base 2 (called MS1B).