fix float vs rational comparisons

This (should) fix `FloatingPoint` vs `Rational` comparisons (mentioned in #2960 and #8411), and should be easily extendable to other binary `Real` types such as [FixedPointNumbers.jl](https://github.com/JeffBezanson/FixedPointNumbers.jl).

It does change the dispatch of comparison operators considerably, so there is a chance that this could break something, or cause a performance regression.
The reason for this are the calls to `sign`, which require `<(::NewType,::Integer)`. I might replace these with explicit `x > zero(x)` checks, or define `ispos`/`isneg` methods (the advantage of the latter is that for `BigFloat` and `BigInt` it is possible to do the check without creating a `zero(x)`). Then the `Integer` comparisons would not be required for new types.

The problem with `promote` is that in a lot of cases, there isn't going to be a single type which encompasses two distinct `Real` types (e.g. `BigFloat` can't exactly represent `Rational`s). The `decompose`-based approach seems like the most general construction, and would cover almost all cases (including `<(::NewType,::Integer)`): the only exceptions I can think of are irrationals (like `MathConst` or @jiahao's suggested `Surd` type) and decimal floating point (which would require something like [this](http://dx.doi.org/10.1109/ARITH.2013.23)).