Let's take a contrived example. Supposed that you have a method that calculates the sine of a variable. But unlike the sine function in the standard library provided by your framework, it can't handle the case when the pass-in variable is a multiple of Pi. But it does not matter since everyone knows that the sine of multiple Pi is always 0. To workaround the limitation, you implement the following wrapper function, and of course, some comments so that your colleagues will not get bamboozled:
public double SineWrapper(double x)
if(x%Math.Pi==0) //this is needed because MySpecialSine(x) can't handle x=0
In this case the comment is needed simply because there is a bug in the function MySpecialSine. Comment is there to explain the why of the source code. But if a programmer can't deduce the why from the context that surrounds that particular piece of code, then maybe there is a bug, or at the very least you may need to rewrite your code so that it is self explanatory. Not just in terms of its working, but of its purpose as well.
One exception to the above rule is that when you are dealing with a third party component that you can't modify the source. The component is buggy and so you need to implement an awkward workaround. The of course you need to comment on it. But this reflects the imperfectness of this world and is undesirable. It's much like the trade-offs you make; you don't want to make them if things are within your control.
Comment on Why? Only when you have to workaround the limitations you have no power over to change.