@@ -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,37 @@ 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 the default (implicit)
374
+ * ordering on `Float` changed in 2.10.0 and 2.13.0.
375
+ * Prior to Scala 2.10.0, the `Ordering` instance used 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 the `compare` method NOT compliant,
380
+ * creating an internally inconsistent instance. IEEE 754 specifies that
381
+ * `0.0F == -0.0F`. In addition, it requires all comparisons with `Float.NaN` return
382
+ * `false` thus `0.0F < Float.NaN`, `0.0F > Float.NaN`, and
383
+ * `Float.NaN == Float.NaN` all yield `false`, analogous `None` in `flatMap`.
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`, which retains
387
+ * the IEEE 754 semantics from Scala 2.12.x, and `Ordering.Float.TotalOrdering`,
388
+ * which brings back the `java.lang.Float.compare` semantics for all operations.
389
+ * The default extends `TotalOrdering`.
390
+ *
391
+ * {{{
392
+ * List(0.0F, 1.0F, 0.0F / 0.0F, -1.0F / 0.0F).sorted // List(-Infinity, 0.0, 1.0, NaN)
393
+ * List(0.0F, 1.0F, 0.0F / 0.0F, -1.0F / 0.0F).min // -Infinity
394
+ * implicitly[Ordering[Float]].lt(0.0F, 0.0F / 0.0F) // true
395
+ * {
396
+ * import Ordering.Float.IeeeOrdering
397
+ * List(0.0F, 1.0F, 0.0F / 0.0F, -1.0F / 0.0F).sorted // List(-Infinity, 0.0, 1.0, NaN)
398
+ * List(0.0F, 1.0F, 0.0F / 0.0F, -1.0F / 0.0F).min // NaN
399
+ * implicitly[Ordering[Float]].lt(0.0F, 0.0F / 0.0F) // false
400
+ * }
401
+ * }}}
402
+ *
403
+ * @define floatOrdering Because the behavior of `Float`s specified by IEEE is
373
404
* not consistent with a total ordering when dealing with
374
405
* `NaN`, there are two orderings defined for `Float`:
375
406
* `TotalOrdering`, which is consistent with a total
@@ -380,7 +411,7 @@ object Ordering extends LowPriorityOrderingImplicits {
380
411
object Float {
381
412
/** An ordering for `Float`s which is a fully consistent total ordering,
382
413
* and treats `NaN` as larger than all other `Float` values; it behaves
383
- * the same as [[java.lang.Float# compare ]].
414
+ * the same as [[java.lang.Float. compare ]].
384
415
*
385
416
* $floatOrdering
386
417
*
@@ -401,7 +432,7 @@ object Ordering extends LowPriorityOrderingImplicits {
401
432
* `NaN`.
402
433
* - `min` and `max` are consistent with `math.min` and `math.max`, and
403
434
* return `NaN` when called with `NaN` as either argument.
404
- * - `compare` behaves the same as [[java.lang.Float# compare ]].
435
+ * - `compare` behaves the same as [[java.lang.Float. compare ]].
405
436
*
406
437
* $floatOrdering
407
438
*
@@ -422,14 +453,48 @@ object Ordering extends LowPriorityOrderingImplicits {
422
453
}
423
454
implicit object IeeeOrdering extends IeeeOrdering
424
455
}
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" )
456
+ @ migration(
457
+ " The default implicit ordering for floats now maintains consistency\n " +
458
+ " between its `compare` method and its `lt`, `min`, `equiv`, etc., methods,\n " +
459
+ " which means nonconforming to IEEE 754's behavior for -0.0F and NaN.\n " +
460
+ " The sort order of floats remains the same, however, with NaN at the end.\n " +
461
+ " Import Ordering.Float.IeeeOrdering to recover the previous behavior.\n " +
462
+ " See also https://www.scala-lang.org/api/current/scala/math/Ordering$$Float$.html." , " 2.13.0" )
428
463
implicit object DeprecatedFloatOrdering extends Float .TotalOrdering
429
464
430
465
/** `Ordering`s for `Double`s.
431
466
*
432
- * @define doubleOrdering Because the behaviour of `Double`s specified by IEEE is
467
+ * The behavior of the comparison operations provided by the default (implicit)
468
+ * ordering on `Double` changed in 2.10.0 and 2.13.0.
469
+ * Prior to Scala 2.10.0, the `Ordering` instance used semantics
470
+ * consistent with `java.lang.Double.compare`.
471
+ *
472
+ * Scala 2.10.0 changed the implementation of `lt`, `equiv`, `min`, etc., to be
473
+ * IEEE 754 compliant, while keeping the `compare` method NOT compliant,
474
+ * creating an internally inconsistent instance. IEEE 754 specifies that
475
+ * `0.0 == -0.0`. In addition, it requires all comparisons with `Double.NaN` return
476
+ * `false` thus `0.0 < Double.NaN`, `0.0 > Double.NaN`, and
477
+ * `Double.NaN == Double.NaN` all yield `false`, analogous `None` in `flatMap`.
478
+ *
479
+ * Recognizing the limitation of the IEEE 754 semantics in terms of ordering,
480
+ * Scala 2.13.0 created two instances: `Ordering.Double.IeeeOrdering`, which retains
481
+ * the IEEE 754 semantics from Scala 2.12.x, and `Ordering.Double.TotalOrdering`,
482
+ * which brings back the `java.lang.Double.compare` semantics for all operations.
483
+ * The default extends `TotalOrdering`.
484
+ *
485
+ * {{{
486
+ * List(0.0, 1.0, 0.0 / 0.0, -1.0 / 0.0).sorted // List(-Infinity, 0.0, 1.0, NaN)
487
+ * List(0.0, 1.0, 0.0 / 0.0, -1.0 / 0.0).min // -Infinity
488
+ * implicitly[Ordering[Double]].lt(0.0, 0.0 / 0.0) // true
489
+ * {
490
+ * import Ordering.Double.IeeeOrdering
491
+ * List(0.0, 1.0, 0.0 / 0.0, -1.0 / 0.0).sorted // List(-Infinity, 0.0, 1.0, NaN)
492
+ * List(0.0, 1.0, 0.0 / 0.0, -1.0 / 0.0).min // NaN
493
+ * implicitly[Ordering[Double]].lt(0.0, 0.0 / 0.0) // false
494
+ * }
495
+ * }}}
496
+ *
497
+ * @define doubleOrdering Because the behavior of `Double`s specified by IEEE is
433
498
* not consistent with a total ordering when dealing with
434
499
* `NaN`, there are two orderings defined for `Double`:
435
500
* `TotalOrdering`, which is consistent with a total
@@ -440,7 +505,7 @@ object Ordering extends LowPriorityOrderingImplicits {
440
505
object Double {
441
506
/** An ordering for `Double`s which is a fully consistent total ordering,
442
507
* and treats `NaN` as larger than all other `Double` values; it behaves
443
- * the same as [[java.lang.Double# compare ]].
508
+ * the same as [[java.lang.Double. compare ]].
444
509
*
445
510
* $doubleOrdering
446
511
*
@@ -461,7 +526,7 @@ object Ordering extends LowPriorityOrderingImplicits {
461
526
* `NaN`.
462
527
* - `min` and `max` are consistent with `math.min` and `math.max`, and
463
528
* return `NaN` when called with `NaN` as either argument.
464
- * - `compare` behaves the same as [[java.lang.Double# compare ]].
529
+ * - `compare` behaves the same as [[java.lang.Double. compare ]].
465
530
*
466
531
* $doubleOrdering
467
532
*
@@ -482,9 +547,13 @@ object Ordering extends LowPriorityOrderingImplicits {
482
547
}
483
548
implicit object IeeeOrdering extends IeeeOrdering
484
549
}
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" )
550
+ @ migration(
551
+ " The default implicit ordering for doubles now maintains consistency\n " +
552
+ " between its `compare` method and its `lt`, `min`, `equiv`, etc., methods,\n " +
553
+ " which means nonconforming to IEEE 754's behavior for -0.0 and NaN.\n " +
554
+ " The sort order of doubles remains the same, however, with NaN at the end.\n " +
555
+ " Import Ordering.Double.IeeeOrdering to recover the previous behavior.\n " +
556
+ " See also https://www.scala-lang.org/api/current/scala/math/Ordering$$Double$.html." , " 2.13.0" )
488
557
implicit object DeprecatedDoubleOrdering extends Double .TotalOrdering
489
558
490
559
trait BigIntOrdering extends Ordering [BigInt ] {
0 commit comments