@@ -16,6 +16,7 @@ package math
16
16
import java .util .Comparator
17
17
18
18
import scala .language .implicitConversions
19
+ import scala .annotation .migration
19
20
20
21
/** Ordering is a trait whose instances each represent a strategy for sorting
21
22
* instances of a type.
@@ -369,7 +370,36 @@ object Ordering extends LowPriorityOrderingImplicits {
369
370
370
371
/** `Ordering`s for `Float`s.
371
372
*
372
- * @define floatOrdering Because the behaviour of `Float`s specified by IEEE is
373
+ * The behavior of the comparison operations provided by default (implicit)
374
+ * ordering on `Float` has changed in 2.10.0 and 2.13.0.
375
+ * Prior to Scala 2.10.0, the `Ordering` instance used the semantics
376
+ * consistent with `java.lang.Float.compare`.
377
+ *
378
+ * Scala 2.10.0 changed the implementation of `lt`, `equiv`, `min` etc to be
379
+ * IEEE 754 compliant, while keeping `compare` method NOT compliant,
380
+ * creating an internally inconsistent instance. IEEE 754 specified that
381
+ * `0.0F == -0.0F`. In addition, all comparisons with `Float.NaN` must return
382
+ * `false` thus `0.0F < Float.NaN`, `0.0F > Float.NaN`, and
383
+ * `Float.NaN == Float.NaN` all yield `false`, analogous to `None`.
384
+ *
385
+ * Recognizing the limitation of the IEEE 754 semantics in terms of ordering,
386
+ * Scala 2.13.0 created two instances `Ordering.Float.IeeeOrdering` and
387
+ * `Ordering.Float.TotalOrdering`, which brings back the `java.lang.Float.compare`
388
+ * semantics for all operations. The default extends `TotalOrdering`.
389
+ *
390
+ * {{{
391
+ * List(0.0F, 1.0F, 0.0F / 0.0F, -1.0F / 0.0F).sorted // List(-Infinity, 0.0, 1.0, NaN)
392
+ * List(0.0F, 1.0F, 0.0F / 0.0F, -1.0F / 0.0F).min // -Infinity
393
+ * implicitly[Ordering[Float]].lt(0.0F, 0.0F / 0.0F) // true
394
+ * {
395
+ * import Ordering.Float.IeeeOrdering
396
+ * List(0.0F, 1.0F, 0.0F / 0.0F, -1.0F / 0.0F).sorted // List(-Infinity, 0.0, 1.0, NaN)
397
+ * List(0.0F, 1.0F, 0.0F / 0.0F, -1.0F / 0.0F).min // NaN
398
+ * implicitly[Ordering[Float]].lt(0.0F, 0.0F / 0.0F) // false
399
+ * }
400
+ * }}}
401
+ *
402
+ * @define floatOrdering Because the behavior of `Float`s specified by IEEE is
373
403
* not consistent with a total ordering when dealing with
374
404
* `NaN`, there are two orderings defined for `Float`:
375
405
* `TotalOrdering`, which is consistent with a total
@@ -380,7 +410,7 @@ object Ordering extends LowPriorityOrderingImplicits {
380
410
object Float {
381
411
/** An ordering for `Float`s which is a fully consistent total ordering,
382
412
* and treats `NaN` as larger than all other `Float` values; it behaves
383
- * the same as [[java.lang.Float# compare ]].
413
+ * the same as [[java.lang.Float. compare ]].
384
414
*
385
415
* $floatOrdering
386
416
*
@@ -401,7 +431,7 @@ object Ordering extends LowPriorityOrderingImplicits {
401
431
* `NaN`.
402
432
* - `min` and `max` are consistent with `math.min` and `math.max`, and
403
433
* return `NaN` when called with `NaN` as either argument.
404
- * - `compare` behaves the same as [[java.lang.Float# compare ]].
434
+ * - `compare` behaves the same as [[java.lang.Float. compare ]].
405
435
*
406
436
* $floatOrdering
407
437
*
@@ -422,14 +452,46 @@ object Ordering extends LowPriorityOrderingImplicits {
422
452
}
423
453
implicit object IeeeOrdering extends IeeeOrdering
424
454
}
425
- @ deprecated(" There are multiple ways to order Floats (Ordering.Float.TotalOrdering, " +
426
- " Ordering.Float.IeeeOrdering). Specify one by using a local import, assigning an implicit val, or passing it " +
427
- " explicitly. See their documentation for details." , since = " 2.13.0" )
455
+ @ migration(
456
+ " The new ordering does not affect the sorting, placing NaN at the end.\n " +
457
+ " However, methods such as `lt`, `min`, and `equiv` now match `compare`\n " +
458
+ " instead of giving IEEE 754 behavior for -0.0F and NaN.\n " +
459
+ " Import Ordering.Float.IeeeOrdering to retain the previous behavior.\n " +
460
+ " See also https://www.scala-lang.org/api/current/scala/math/Ordering$$Float$.html" , " 2.13.0" )
428
461
implicit object DeprecatedFloatOrdering extends Float .TotalOrdering
429
462
430
463
/** `Ordering`s for `Double`s.
431
464
*
432
- * @define doubleOrdering Because the behaviour of `Double`s specified by IEEE is
465
+ * The behavior of the comparison operations provided by default (implicit)
466
+ * ordering on `Double` has changed in 2.10.0 and 2.13.0.
467
+ * Prior to Scala 2.10.0, the `Ordering` instance used the semantics
468
+ * consistent with `java.lang.Double.compare`.
469
+ *
470
+ * Scala 2.10.0 changed the implementation of `lt`, `equiv`, `min` etc to be
471
+ * IEEE 754 compliant, while keeping `compare` method NOT compliant,
472
+ * creating an internally inconsistent instance. IEEE 754 specified that
473
+ * `0.0 == -0.0`. In addition, all comparisons with `Double.NaN` must return
474
+ * `false` thus `0.0 < Double.NaN`, `0.0 > Double.NaN`, and
475
+ * `Double.NaN == Double.NaN` all yield `false`, analogous to `None`.
476
+ *
477
+ * Recognizing the limitation of the IEEE 754 semantics in terms of ordering,
478
+ * Scala 2.13.0 created two instances `Ordering.Double.IeeeOrdering` and
479
+ * `Ordering.Double.TotalOrdering`, which brings back the `java.lang.Double.compare`
480
+ * semantics for all operations. The default extends `TotalOrdering`.
481
+ *
482
+ * {{{
483
+ * List(0.0, 1.0, 0.0 / 0.0, -1.0 / 0.0).sorted // List(-Infinity, 0.0, 1.0, NaN)
484
+ * List(0.0, 1.0, 0.0 / 0.0, -1.0 / 0.0).min // -Infinity
485
+ * implicitly[Ordering[Double]].lt(0.0, 0.0 / 0.0) // true
486
+ * {
487
+ * import Ordering.Double.IeeeOrdering
488
+ * List(0.0, 1.0, 0.0 / 0.0, -1.0 / 0.0).sorted // List(-Infinity, 0.0, 1.0, NaN)
489
+ * List(0.0, 1.0, 0.0 / 0.0, -1.0 / 0.0).min // NaN
490
+ * implicitly[Ordering[Double]].lt(0.0, 0.0 / 0.0) // false
491
+ * }
492
+ * }}}
493
+ *
494
+ * @define doubleOrdering Because the behavior of `Double`s specified by IEEE is
433
495
* not consistent with a total ordering when dealing with
434
496
* `NaN`, there are two orderings defined for `Double`:
435
497
* `TotalOrdering`, which is consistent with a total
@@ -440,7 +502,7 @@ object Ordering extends LowPriorityOrderingImplicits {
440
502
object Double {
441
503
/** An ordering for `Double`s which is a fully consistent total ordering,
442
504
* and treats `NaN` as larger than all other `Double` values; it behaves
443
- * the same as [[java.lang.Double# compare ]].
505
+ * the same as [[java.lang.Double. compare ]].
444
506
*
445
507
* $doubleOrdering
446
508
*
@@ -461,7 +523,7 @@ object Ordering extends LowPriorityOrderingImplicits {
461
523
* `NaN`.
462
524
* - `min` and `max` are consistent with `math.min` and `math.max`, and
463
525
* return `NaN` when called with `NaN` as either argument.
464
- * - `compare` behaves the same as [[java.lang.Double# compare ]].
526
+ * - `compare` behaves the same as [[java.lang.Double. compare ]].
465
527
*
466
528
* $doubleOrdering
467
529
*
@@ -482,9 +544,12 @@ object Ordering extends LowPriorityOrderingImplicits {
482
544
}
483
545
implicit object IeeeOrdering extends IeeeOrdering
484
546
}
485
- @ deprecated(" There are multiple ways to order Doubles (Ordering.Double.TotalOrdering, " +
486
- " Ordering.Double.IeeeOrdering). Specify one by using a local import, assigning an implicit val, or passing it " +
487
- " explicitly. See their documentation for details." , since = " 2.13.0" )
547
+ @ migration(
548
+ " The new ordering does not affect the sorting, placing NaN at the end.\n " +
549
+ " However, methods such as `lt`, `min`, and `equiv` now match `compare`\n " +
550
+ " instead of giving IEEE 754 behavior for -0.0 and NaN.\n " +
551
+ " Import Ordering.Double.IeeeOrdering to retain the previous behavior.\n " +
552
+ " See also https://www.scala-lang.org/api/current/scala/math/Ordering$$Double$.html." , " 2.13.0" )
488
553
implicit object DeprecatedDoubleOrdering extends Double .TotalOrdering
489
554
490
555
trait BigIntOrdering extends Ordering [BigInt ] {
0 commit comments