### vogel's blog

By vogel, 8 years ago, translation,

Now I am writing an article about bit manipulation, bit magic and other trciks for wiki — conspects (This is a great resource of algorithms in Russian). If you know some useful bit tricks, which used in algoritms or just funny things connected with bits write them in comments below. Also you are welcomed with really strange, weird and sophisticated solutions for well-known problems. For example: swapping values with XOR.

• Descripotion of the problem
• Solution of the problem in code with short explanation for tricky moments

Example of a perfect comment:
Determining if an integer is a power of 2

unsigned int v; // we want to see if v is a power of 2
bool f;         // the result goes here

f = (v & (v - 1)) == 0;


Short explanation: Let v — power of two (this is one and k zeros in binary presentation) and v — 1 is k ones in binary presenation. Then notice that bitwise AND v and v — 1 must be 0.

Warm — up problem: Find smallest 1 — bit (not zero) in O(1)

• +50

| Write comment?
 » 8 years ago, # |   +37 Zero is not a power of two. Your code says otherwise :)
•  » » 8 years ago, # ^ |   0 Yeah. f = v && !(v & (v - 1)) 
•  » » 8 years ago, # ^ |   +98 232 = 0
 » 8 years ago, # | ← Rev. 2 →   0 or: f = __builtin_popcount(v) == 1;
•  » » 8 years ago, # ^ | ← Rev. 3 →   0 This method is much slower.
 » 8 years ago, # |   +23 Smallest bit set to 1 of an integer int bit = number & -number; Explanation: -number representation using 2-complement keeps the smallest 1-bit and inverts the other most significative bits.Unsetting the smallest 1-bit of an integerint number = 123; number -= number & -number;Counting the number of bits set to 1 int amount = 0; for (; number > 0; number -= number & -number) ++amount; Toggle bit i from 1->0 or 0->1 number ^= 1 << i; Xor with bit set to 1, makes it change its value, whereas the other bits are 0 and don't change anything.Iterate all subsets of a bitmask in increasing order for ( int sub = 0 ; sub = sub - bitmask & bitmask ; ) { // do something } Iterate all subsets of a bitmask in decreasing order for(int sub = (mask-1) & bitmask ; sub > 0 ; sub = (sub-1) & bitmask ) { // do something } 
•  » » 8 years ago, # ^ |   0 Can u plz give a small example for "Iterate all subsets of a bitmask in increasing order". It is not clear to me... :/
 » 8 years ago, # | ← Rev. 12 →   -37 Swap two integers a ^= b ^= a ^= b; Check whether two integers are equal or not: if (a ^ b) // they aren't equal! Check if a equals -1 or not if (~a) // a != -1 Get the largest number I can! int (or long long) INF = -1ull/2; For the least number int (or long long) LEAST = ~(-1ull/2); 
 » 8 years ago, # |   0 Operation x & (x — 1) sets rightmost 1 to 0. As powers of 2 have only one 1 — it can be used to check them.
 » 8 years ago, # |   +3 My favorite is binary searching by bit manipulation — no off-by-1 errors! /** * Binary search by bit toggling from MSB to LSB * O(64) bit-wise operations for Longs (O(32) for Ints) * * @return Some(x) such that x is the largest number for which f is true * If no such x is found, None */ def bitBinSearch(f: Long => Boolean): Option[Long] = { var p = 0L var n = Long.MinValue var t = n >>> 1 while (t > 0) { if (f(p|t)) p |= t if (f(n|t)) n |= t t >>= 1 } Seq(p, n) find f } 
•  » » 8 years ago, # ^ |   0 Could you explain please what Seq(p, n) find f means?
•  » » » 8 years ago, # ^ | ← Rev. 3 →   +4 p and n are numbers in [0, Long.MaxValue] and [Long.MinValue, 0] respectively for which f maybe satisfactory. Seq(p, n) creates a sequence of these 2 numbers and Seq(p, n) find f returns the first one for which f is true else None. I am using Scala as my language; here's a Java/C++-ish version (not tested): long p = 0L, n = Long.MinValue; for (long t = n >>> 1; t > 0; t >>= 1) { if (f(p|t)) p |= t; if (f(n|t)) n |= t; } if (f(p)) return p; if (f(n)) return n; return null; 
 » 6 years ago, # |   +1 Can someone provide links to the problems, where you need a fast way to count number of 1's in mask or index of last setted bit?
•  » » 6 years ago, # ^ |   +5