What USEFUL bitwise operator code tricks should a developer know about?

Language AgnosticBit ManipulationBit

Language Agnostic Problem Overview


I must say I have never had cause to use bitwise operators, but I am sure there are some operations that I have performed that would have been more efficiently done with them. How have "shifting" and "OR-ing" helped you solve a problem more efficiently?

Language Agnostic Solutions


Solution 1 - Language Agnostic

Using bitwise operations on strings (characters)

Convert letter to lowercase:

  • OR by space => (x | ' ')
  • Result is always lowercase even if letter is already lowercase
  • eg. ('a' | ' ') => 'a' ; ('A' | ' ') => 'a'

Convert letter to uppercase:

  • AND by underline => (x & '_')
  • Result is always uppercase even if letter is already uppercase
  • eg. ('a' & '_') => 'A' ; ('A' & '_') => 'A'

Invert letter's case:

  • XOR by space => (x ^ ' ')
  • eg. ('a' ^ ' ') => 'A' ; ('A' ^ ' ') => 'a'

Letter's position in alphabet:

  • AND by chr(31)/binary('11111')/(hex('1F') => (x & "\x1F")
  • Result is in 1..26 range, letter case is not important
  • eg. ('a' & "\x1F") => 1 ; ('B' & "\x1F") => 2

Get letter's position in alphabet (for Uppercase letters only):

  • AND by ? => (x & '?') or XOR by @ => (x ^ '@')
  • eg. ('C' & '?') => 3 ; ('Z' ^ '@') => 26

Get letter's position in alphabet (for lowercase letters only):

  • XOR by backtick/chr(96)/binary('1100000')/hex('60') => (x ^ '`')
  • eg. ('d' ^ '`') => 4 ; ('x' ^ '`') => 25

Note: using anything other than the english letters will produce garbage results

Solution 2 - Language Agnostic


  • Bitwise operations on integers(int)

Get the maximum integer

int maxInt = ~(1 << 31);
int maxInt = (1 << 31) - 1;
int maxInt = (1 << -1) - 1;

Get the minimum integer

int minInt = 1 << 31;
int minInt = 1 << -1;

Get the maximum long

long maxLong = ((long)1 << 127) - 1;

Multiplied by 2

n << 1; // n*2

Divided by 2

n >> 1; // n/2

Multiplied by the m-th power of 2

n << m; // (3<<5) ==>3 * 2^5 ==> 96

Divided by the m-th power of 2

n >> m; // (20>>2) ==>(20/( 2^2) ==> 5

Check odd number

(n & 1) == 1;

Exchange two values

a ^= b;
b ^= a;
a ^= b;

Get absolute value

(n ^ (n >> 31)) - (n >> 31);

Get the max of two values

b & ((a-b) >> 31) | a & (~(a-b) >> 31);

Get the min of two values

a & ((a-b) >> 31) | b & (~(a-b) >> 31);

Check whether both have the same sign

(x ^ y) >= 0;

Calculate 2^n

2 << (n-1);

Whether is factorial of 2

n > 0 ? (n & (n - 1)) == 0 : false;

Modulo 2^n against m

m & (n - 1);

Get the average

(x + y) >> 1;
((x ^ y) >> 1) + (x & y);

Get the m-th bit of n (from low to high)

(n >> (m-1)) & 1;

Set the m-th bit of n to 0 (from low to high)

n & ~(1 << (m-1));

n + 1

-~n

n - 1

~-n

Get the contrast number

~n + 1;
(n ^ -1) + 1; 

if (x==a) x=b; if (x==b) x=a;

x = a ^ b ^ x;

Solution 3 - Language Agnostic

See the famous Bit Twiddling Hacks
Most of the multiply/divide ones are unnecessary - the compiler will do that automatically and you will just confuse people.

But there are a bunch of, 'check/set/toggle bit N' type hacks that are very useful if you work with hardware or communications protocols.

Solution 4 - Language Agnostic

There's only three that I've ever used with any frequency:

  1. Set a bit: a |= 1 << bit;

  2. Clear a bit: a &= ~(1 << bit);

  3. Test that a bit is set: a & (1 << bit);

Solution 5 - Language Agnostic

Matters Computational: Ideas, Algorithms, Source Code, by Jorg Arndt (PDF). This book contains tons of stuff, I found it via a link at http://www.hackersdelight.org/

> Average without overflow > > A routine for the computation of the average (x + y)/2 of two > arguments x and y is > > static inline ulong average(ulong x, ulong y) > // Return floor( (x+y)/2 ) > // Use: x+y == ((x&y)<<1) + (x^y) > // that is: sum == carries + sum_without_carries > { > return (x & y) + ((x ^ y) >> 1); > }

Solution 6 - Language Agnostic

  1. Divide/Multiply by a power of 2

foo >>= x; (divide by power of 2)

foo <<= x; (multiply by power of 2)

  1. Swap

    x ^= y; y = x ^ y; x ^= y;

Solution 7 - Language Agnostic

You can compress data, e.g. a collection of integers:

  • See which integer values appear more frequently in the collection

  • Use short bit-sequences to represent the values which appear more frequently (and longer bit-sequences to represent the values which appear less frequently)

  • Concatenate the bits-sequences: so for example, the first 3 bits in the resulting bit stream might represent one integer, then the next 9 bits another integer, etc.

Solution 8 - Language Agnostic

I used bitwise operators to efficiently implement distance calculations for bitstrings. In my application bitstrings were used to represent positions in a discretised space (an octree, if you're interested, encoded with Morton ordering). The distance calculations were needed to know whether points on the grid fell within a particular radius.

Solution 9 - Language Agnostic

Counting set bits, finding lowest/highest set bit, finding nth-from-top/bottom set bit and others can be useful, and it's worth looking at the bit-twiddling hacks site.

That said, this kind of thing isn't day-to-day important. Useful to have a library, but even then the most common uses are indirect (e.g. using a bitset container). Also, ideally, these would be standard library functions - a lot of them are better handled using specialise CPU instructions on some platforms.

Solution 10 - Language Agnostic

While multiplying/dividing by shifting seems nifty, the only thing I needed once in a while was compressing booleans into bits. For that you need bitwise AND/OR, and probably bit shifting/inversion.

Solution 11 - Language Agnostic

I wanted a function to round numbers to the next highest power of two, so I visited the Bit Twiddling website that's been brought up several times and came up with this:

i--;
i |= i >> 1;
i |= i >> 2;
i |= i >> 4;
i |= i >> 8;
i |= i >> 16;
i++;

I use it on a size_t type. It probably won't play well on signed types. If you're worried about portability to platforms with different sized types, sprinkle your code with #if SIZE_MAX >= (number) directives in appropriate places.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionnon sequitorView Question on Stackoverflow
Solution 1 - Language AgnosticCSᵠView Answer on Stackoverflow
Solution 2 - Language AgnosticMohasin AliView Answer on Stackoverflow
Solution 3 - Language AgnosticMartin BeckettView Answer on Stackoverflow
Solution 4 - Language AgnosticScottView Answer on Stackoverflow
Solution 5 - Language Agnosticu0b34a0f6aeView Answer on Stackoverflow
Solution 6 - Language AgnosticTaylor LeeseView Answer on Stackoverflow
Solution 7 - Language AgnosticChrisWView Answer on Stackoverflow
Solution 8 - Language Agnosticire_and_cursesView Answer on Stackoverflow
Solution 9 - Language Agnosticuser180247View Answer on Stackoverflow
Solution 10 - Language AgnosticsbiView Answer on Stackoverflow
Solution 11 - Language AgnosticChris LutzView Answer on Stackoverflow