mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8294539: Augment discussion of equivalence relations on floating-point values
Reviewed-by: psandoz, smarks
This commit is contained in:
parent
b2e86a6209
commit
1dafbe3f94
2 changed files with 71 additions and 7 deletions
|
@ -58,7 +58,7 @@ import jdk.internal.vm.annotation.IntrinsicCandidate;
|
|||
*
|
||||
* IEEE 754 floating-point values include finite nonzero values,
|
||||
* signed zeros ({@code +0.0} and {@code -0.0}), signed infinities
|
||||
* {@linkplain Double#POSITIVE_INFINITY positive infinity} and
|
||||
* ({@linkplain Double#POSITIVE_INFINITY positive infinity} and
|
||||
* {@linkplain Double#NEGATIVE_INFINITY negative infinity}), and
|
||||
* {@linkplain Double#NaN NaN} (not-a-number).
|
||||
*
|
||||
|
@ -116,12 +116,13 @@ import jdk.internal.vm.annotation.IntrinsicCandidate;
|
|||
* <p>To provide the appropriate semantics for {@code equals} and
|
||||
* {@code compareTo} methods, those methods cannot simply be wrappers
|
||||
* around {@code ==} or ordered comparison operations. Instead, {@link
|
||||
* Double#equals equals} defines NaN arguments to be equal to each
|
||||
* other and defines {@code +0.0} to <em>not</em> be equal to {@code
|
||||
* -0.0}, restoring reflexivity. For comparisons, {@link
|
||||
* Double#compareTo compareTo} defines a total order where {@code
|
||||
* -0.0} is less than {@code +0.0} and where a NaN is equal to itself
|
||||
* and considered greater than positive infinity.
|
||||
* Double#equals equals} uses <a href=#repEquivalence> representation
|
||||
* equivalence</a>, defining NaN arguments to be equal to each other,
|
||||
* restoring reflexivity, and defining {@code +0.0} to <em>not</em> be
|
||||
* equal to {@code -0.0}. For comparisons, {@link Double#compareTo
|
||||
* compareTo} defines a total order where {@code -0.0} is less than
|
||||
* {@code +0.0} and where a NaN is equal to itself and considered
|
||||
* greater than positive infinity.
|
||||
*
|
||||
* <p>The operational semantics of {@code equals} and {@code
|
||||
* compareTo} are expressed in terms of {@linkplain #doubleToLongBits
|
||||
|
@ -143,6 +144,62 @@ import jdk.internal.vm.annotation.IntrinsicCandidate;
|
|||
* elements of a {@link java.util.SortedSet SortedSet} or as keys of a
|
||||
* {@link java.util.SortedMap SortedMap}.
|
||||
*
|
||||
* <p>Comparing numerical equality to various useful equivalence
|
||||
* relations that can be defined over floating-point values:
|
||||
*
|
||||
* <dl>
|
||||
* <dt><a id=fpNumericalEq><i>numerical equality</i></a> ({@code ==}
|
||||
* operator): (<em>Not</em> an equivalence relation)</dt>
|
||||
* <dd>Two floating-point values represent the same extended real
|
||||
* number. The extended real numbers are the real numbers augmented
|
||||
* with positive infinity and negative infinity. Under numerical
|
||||
* equality, {@code +0.0} and {@code -0.0} are equal since they both
|
||||
* map to the same real value, 0. A NaN does not map to any real
|
||||
* number and is not equal to any value, including itself.
|
||||
* </dd>
|
||||
*
|
||||
* <dt><i>bit-wise equivalence</i>:</dt>
|
||||
* <dd>The bits of the two floating-point values are the same. This
|
||||
* equivalence relation for {@code double} values {@code a} and {@code
|
||||
* b} is implemented by the expression
|
||||
* <br>{@code Double.doubleTo}<code><b>Raw</b></code>{@code LongBits(a) == Double.doubleTo}<code><b>Raw</b></code>{@code LongBits(b)}<br>
|
||||
* Under this relation, {@code +0.0} and {@code -0.0} are
|
||||
* distinguished from each other and every bit pattern encoding a NaN
|
||||
* is distinguished from every other bit pattern encoding a NaN.
|
||||
* </dd>
|
||||
*
|
||||
* <dt><i><a id=repEquivalence>representation equivalence</a></i>:</dt>
|
||||
* <dd>The two floating-point values represent the the same IEEE 754
|
||||
* <i>datum</i>. In particular, for {@linkplain #isFinite(double)
|
||||
* finite} values, the sign, {@linkplain Math#getExponent(double)
|
||||
* exponent}, and significand components of the
|
||||
* floating-point values are the same. Under this relation:
|
||||
* <ul>
|
||||
* <li> {@code +0.0} and {@code -0.0} are distinguished from each other.
|
||||
* <li> every bit pattern encoding a NaN is considered equivalent to each other
|
||||
* <li> positive infinity is equivalent to positive infinity; negative
|
||||
* infinity is equivalent to negative infinity.
|
||||
* </ul>
|
||||
* Expressions implementing this equivalence relation include:
|
||||
* <ul>
|
||||
* <li>{@code Double.doubleToLongBits(a) == Double.doubleToLongBits(b)}
|
||||
* <li>{@code Double.valueOf(a).equals(Double.valueOf(b))}
|
||||
* <li>{@code Double.compare(a, b) == 0}
|
||||
* </ul>
|
||||
* Note that representation equivalence is often an appropriate notion
|
||||
* of equivalence to test the behavior of {@linkplain StrictMath math
|
||||
* libraries}.
|
||||
* </dd>
|
||||
* </dl>
|
||||
*
|
||||
* For two binary floating-point values {@code a} and {@code b}, if
|
||||
* neither of {@code a} and {@code b} is zero or NaN, then the three
|
||||
* relations numerical equality, bit-wise equivalence, and
|
||||
* representation equivalence of {@code a} and {@code b} have the same
|
||||
* {@code true}/{@code false} value. In other words, for binary
|
||||
* floating-point values, the three relations only differ if at least
|
||||
* one argument is zero or NaN.
|
||||
*
|
||||
* @jls 4.2.3 Floating-Point Types, Formats, and Values
|
||||
* @jls 4.2.4. Floating-Point Operations
|
||||
* @jls 15.21.1 Numerical Equality Operators == and !=
|
||||
|
|
|
@ -3087,6 +3087,10 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> {
|
|||
|
||||
* @apiNote
|
||||
* Note: this class has a natural ordering that is inconsistent with equals.
|
||||
* The behavior of comparing the result of this method for
|
||||
* equality to 0 is analogous to checking the <a
|
||||
* href="{@docRoot}/java.base/java/lang/Double.html#fpNumericalEq">numerical
|
||||
* equality</a> of {@code double} values.
|
||||
*
|
||||
* @param val {@code BigDecimal} to which this {@code BigDecimal} is
|
||||
* to be compared.
|
||||
|
@ -3179,6 +3183,9 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> {
|
|||
* HALF_UP)} which evaluates to 0.7 and <br>
|
||||
* {@code new BigDecimal("2.00").divide(BigDecimal.valueOf(3),
|
||||
* HALF_UP)} which evaluates to 0.67.
|
||||
* The behavior of this method is analogous to checking the <a
|
||||
* href="{@docRoot}/java.base/java/lang/Double.html#repEquivalence">representation
|
||||
* equivalence</a> of {@code double} values.
|
||||
*
|
||||
* @param x {@code Object} to which this {@code BigDecimal} is
|
||||
* to be compared.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue