I disagree with Darin a little...I think there are valid times when you should comment on what the code is doing. Sometimes what may be self documenting to you is not as self documenting to others. I run into this commonly with bit manipulations and bitwise functions, and lately even more so with FPGA. Often times if someone just left a comment "this checks if bit 4 changed" I would understand quickly vs. trying to read the ands and ors and scale by power of 2's that my mind doesn't yet process as easily. Maybe this is my own shortcoming, but I still think it's worth noting. The problem is at what point do you determine whether something is self documenting in general and the majority of programmers would agree that it is, or whether it's self documenting just for yourself (code reviews, anyone?). I find myself looking at my own code and thinking "that makes sense" but forgetting that it took me 3 hours to get it to work. Anyways, this is just one example and I think touches on the same thing Cat is saying above.
One thing I am always sure to document is the random "increment" or "decrement" function. C'mon, we've all seen this, the code works, yet we wonder wth is that there for!