If the calculations are done in the same precision, I think they'll end up the same. However, if that's not the case, both float->double and double->float conversions will create discrepancies. And that's not an impossible scenario (at least without fp:strict), since the compiler can mix FPU and SSE code (for instance, if it needs to call a function that's not implemented in SSE, or use it as an argument/return result for a cdecl function).
That said, you can also create a quotient (x/y) class and use it as the key. You can define all arithmetic for it, for instance
q0+q1 = (q0.x*q1.y+q1.x*q0.y)/(q0.y*q1.y)
q0<q1 = q0.x*q1.y*(q0.y*q1.y) < q1.x*q0.y*(q0.y*q1.y)
(in the latter case * (q0.y * q1.y) is added to account for the fact that we've multiplied the original expression, q0.x/q0.y < q1.x/q1.y by q0.y*q1.y, and if it's negative, < will change to >). You can also get rid of some divisions that way.