Well, these difficulties may be connected to internal conversion of depth values. Remember that if you have set near and far depth with glDepthRange(n, f) or if your are using default values n = 0 and f = 1, the depth is converted according to the following formula:
zw = ((f-n)/2) * z + (f+n)/2;
Therfore, in the most simple case you just get your depth value divided by 2 before actually being written to the depth buffer (remember that after projection the depth value is between -1 and 1). I’ve had a problem with this once; so, you could just transform the value back (that is, multiply by 2 and subtract 1 in the simplest case) to get the value you think is correct.
The y coordinate should actually be
newY = height - y - 1
Secondly, the depth coordinates are not part of a linear scale. The closer the depth is to the near clipping plane, the better the accuracy. The farther it is, the more likely you are to run into issues. Make sure your near and far clipping planes are only as far apart as you need them to be, otherwise you are introducing greater error.