How hard is are bitwise operators to interpret?
I program embedded systems. I've practiced this stuff a lot. Your linked question about hash maps with the code
static int hash(int h) {
// This function ensures that hashCodes that differ only by
// constant multiples at each bit position have a bounded
// number of collisions (approximately 8 at default load factor).
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
made perfect sense to me in about as long as would take to dictate the code aloud. The events described in bitCount
are immediately clear, but it takes a minute to work out why it actually counts bits. Comments would be great, though, and would make understanding what the code does only slightly harder than the hash problem.
It's important to make the distinction between reading and understanding the code. I can interpret the bitCount
code, and read off what it does, but proving why it works or even that it works would take a minute. There's a difference between being able to read code smoothly and being able to grok why the code is the way it is. Some algorithms are simply hard. The what of the hash
code made sense, but the comment explained why the what was being done. Don't be discouraged if a function using bitwise operators is hard to understand, they're often used to do tricky mathematical stuff which would be hard no matter the format.
An analogy
I'm used to this stuff. One subject that I'm not used to is regex. I deal with them occasionally on build scripts, but never in daily development work.
I know how to use the following elements of a regex:
[]
character classes
- The
*
, .
, and +
wildcards
- The start of string
^
and end of string $
- The \d, \w, and \s character classes
- The /g flag
This is enough to craft simple queries, and many of the queries I see don't stray far from this.
Anything not on this list, I reach for a cheat sheet. Anything, that is, except {}
and ()
- The cheat sheet won't be enough. I know just enough about these guys to know that I'm going to need a whiteboard, a reference manual, and maybe a coworker. You can pack some crazy algorithms into a few short lines of regex.
To design a regex which requires or suggests anything that's not in my list of known elements, I'm going to list out all the classes of inputs that I expect to recognize and put them in a test suite. I'm going to craft the regex slowly and incrementally, with lots of intermittent steps, and commit these steps to source control and/or leave them in a comment so I can understand what was supposed to happen later when it breaks. If it's in production code, I'm going to make sure that it gets reviewed by someone with more experience.
Is this where you're at with bitwise operators?
So you want to be well rounded?
In my estimation, if you're able to interpret what code like this does by pulling out a piece of paper or going to the whiteboard and running through the operations manually, you qualify as well-rounded. To qualify as a good well-rounded programmer in the area of bitwise operations you should be able to do four things:
Be able to read and write common operations fluidly
For an applications programmer, common operations with bitwise operators include the basic operators of |
and &
to set and clear flags. This should be easy. You should be able to read and write stuff like
open('file', O_WRONLY | O_APPEND | O_CREAT );
// Use an OR operator ^ here and ^ here to set multiple flags
without slowing down (assuming you know what the flags mean).
Be able to read more complex operations with some work
Counting bits really fast in O(log(n)) time without branches, ensuring that the number of collisions in hashCodes can differ by a bounded amount, and parsing email addresses, phone numbers, or HTML with a regex are hard problems. It's reasonable for anyone who's not an expert in these areas to reach for the whiteboard, it's unreasonable to be unable to begin working to understand.
Be able to write some complex algorithms with a lot of work
If you're not an expert, you shouldn't expect to be able to do complex and difficult stuff. However, a good programmer should be able to get it done by working at it continuously. Do this enough, and you'll soon be an expert :)