Currently (Scala 2.12.4 and 2.13.0-M3), there are some problems with `Ordering`

and `Numeric`

, particularly with regards to `Float`

and `Double`

(not `BigDecimal`

).

The current default `Ordering`

s for `Float`

and `Double`

are internally inconsistent (see scala/bug#10511) with `compare`

behaving the same as `j.l.{Float,Double}.compare`

, the comparison methods (`lt`

, `gteq`

, `equiv`

, etc.) being consistent with IEEE spec, and extrema methods (`min`

and `max`

) behaving the same as `math.min`

and `math.max`

(which is *mostly* consistent with IEEE spec). For `Ordering`

s, it is confusing for many methods to be inconsistent with a total ordering.

The default `Numeric`

s for `Float`

and `Double`

inherit from the default `Ordering`

s for them. For `Numeric`

, it is absolutely expected that their behaviour conforms to IEEE spec as much as possible (which is why their behaviour was changed to the way it is in the first place). In addition, `Ordering.min(x, y)`

behaves the same as `x min y`

for `Float`

and `Double`

(violating this is *extremely* unexpected). However, this still leaves the `Ordering`

internally inconsistent, as it is impossible to implement `Ordering.compare`

in a way that complies with IEEE spec.

The root problem is that IEEE floating point values do not have a total ordering; only a partial ordering. This leaves a few solutions:

- Leave
`Ordering`

for`Float`

and`Double`

as is; it is mostly compliant with IEEE spec, but internally inconsistent. - Revert the behaviour of the default
`Ordering`

s for`Float`

and`Double`

to be consistent with their`compare`

implementations (and a total ordering), while no longer being consistent with IEEE spec. At the same time, the old (current)`Ordering`

s can be used for the default implementations of their respective`Numeric`

s; the behaviour of`Numeric[Float]`

and`Numeric[Double]`

will remain as is. - Change
`Numeric`

to inherit from`PartialOrdering`

instead of`Ordering`

.`Ordering[Float]`

and`Ordering[Double]`

are changed to be consistent with a total ordering, and`Numeric[Float]`

and`Numeric[Double]`

are defined with`PartialOrdering`

s consistent with IEEE spec. There may additionally be an`Extrema`

typeclass which`Numeric`

extends, which defines`min`

and`max`

methods (which would be consistent with`math.min`

and`math.max`

). A deprecated implicit conversion from`Numeric`

to`Ordering`

can perhaps be added to reduce breakage. - Something else?

See scala/scala#6323 for a longer discussion of the issues here. A huge thanks to @Ichoran for the discussion and great points raised there.

To me at least, changing `Numeric`

to inherit from `PartialOrdering`

is the most âcorrectâ, and likely to be least confusing in the long term (despite causing breakage in the immediate future).