Precision.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */

  17. package org.apache.commons.numbers.core;

  18. import java.math.BigDecimal;
  19. import java.math.RoundingMode;

  20. /**
  21.  * Utilities for comparing numbers.
  22.  */
  23. public final class Precision {
  24.     /**
  25.      * <p>
  26.      * Largest double-precision floating-point number such that
  27.      * {@code 1 + EPSILON} is numerically equal to 1. This value is an upper
  28.      * bound on the relative error due to rounding real numbers to double
  29.      * precision floating-point numbers.
  30.      * </p>
  31.      * <p>
  32.      * In IEEE 754 arithmetic, this is 2<sup>-53</sup>.
  33.      * </p>
  34.      *
  35.      * @see <a href="http://en.wikipedia.org/wiki/Machine_epsilon">Machine epsilon</a>
  36.      */
  37.     public static final double EPSILON;

  38.     /**
  39.      * Safe minimum, such that {@code 1 / SAFE_MIN} does not overflow.
  40.      * In IEEE 754 arithmetic, this is also the smallest normalized
  41.      * number 2<sup>-1022</sup>.
  42.      *
  43.      * @see Double#MIN_NORMAL
  44.      */
  45.     public static final double SAFE_MIN = Double.MIN_NORMAL;

  46.     /** Exponent offset in IEEE754 representation. */
  47.     private static final long EXPONENT_OFFSET = 1023L;

  48.     /** Positive zero. */
  49.     private static final double POSITIVE_ZERO = 0d;

  50.     static {
  51.         /*
  52.          *  This was previously expressed as = 0x1.0p-53
  53.          *  However, OpenJDK (Sparc Solaris) cannot handle such small
  54.          *  constants: MATH-721
  55.          */
  56.         EPSILON = Double.longBitsToDouble((EXPONENT_OFFSET - 53L) << 52);
  57.     }

  58.     /**
  59.      * Private constructor.
  60.      */
  61.     private Precision() {}

  62.     /**
  63.      * Compares two numbers given some amount of allowed error.
  64.      * The returned value is:
  65.      * <ul>
  66.      *  <li>zero if considered equal using {@link #equals(double,double,double) equals(x, y, eps)}
  67.      *  <li>negative if not equal and {@code x < y}
  68.      *  <li>positive if not equal and {@code x > y}
  69.      * </ul>
  70.      *
  71.      * <p>NaN values are handled as if using {@link Double#compare(double, double)} where the
  72.      * returned value is:
  73.      * <ul>
  74.      *  <li>zero if {@code NaN, NaN}
  75.      *  <li>negative if {@code !NaN, NaN}
  76.      *  <li>positive if {@code NaN, !NaN}
  77.      * </ul>
  78.      *
  79.      * @param x First value.
  80.      * @param y Second value.
  81.      * @param eps Allowed error when checking for equality.
  82.      * @return 0 if the value are considered equal, -1 if the first is smaller than
  83.      * the second, 1 if the first is larger than the second.
  84.      * @see #equals(double, double, double)
  85.      */
  86.     public static int compareTo(double x, double y, double eps) {
  87.         if (equals(x, y, eps)) {
  88.             return 0;
  89.         } else if (x < y) {
  90.             return -1;
  91.         } else if (x > y) {
  92.             return 1;
  93.         }
  94.         // NaN input.
  95.         return Double.compare(x, y);
  96.     }

  97.     /**
  98.      * Compares two numbers given some amount of allowed error.
  99.      * The returned value is:
  100.      * <ul>
  101.      *  <li>zero if considered equal using {@link #equals(double,double,int) equals(x, y, maxUlps)}
  102.      *  <li>negative if not equal and {@code x < y}
  103.      *  <li>positive if not equal and {@code x > y}
  104.      * </ul>
  105.      *
  106.      * <p>NaN values are handled as if using {@link Double#compare(double, double)} where the
  107.      * returned value is:
  108.      * <ul>
  109.      *  <li>zero if {@code NaN, NaN}
  110.      *  <li>negative if {@code !NaN, NaN}
  111.      *  <li>positive if {@code NaN, !NaN}
  112.      * </ul>
  113.      *
  114.      * @param x First value.
  115.      * @param y Second value.
  116.      * @param maxUlps {@code (maxUlps - 1)} is the number of floating point
  117.      * values between {@code x} and {@code y}.
  118.      * @return 0 if the value are considered equal, -1 if the first is smaller than
  119.      * the second, 1 if the first is larger than the second.
  120.      * @see #equals(double, double, int)
  121.      */
  122.     public static int compareTo(final double x, final double y, final int maxUlps) {
  123.         if (equals(x, y, maxUlps)) {
  124.             return 0;
  125.         } else if (x < y) {
  126.             return -1;
  127.         } else if (x > y) {
  128.             return 1;
  129.         }
  130.         // NaN input.
  131.         return Double.compare(x, y);
  132.     }

  133.     /**
  134.      * Returns true iff they are equal as defined by
  135.      * {@link #equals(float,float,int) equals(x, y, 1)}.
  136.      *
  137.      * @param x first value
  138.      * @param y second value
  139.      * @return {@code true} if the values are equal.
  140.      */
  141.     public static boolean equals(float x, float y) {
  142.         return equals(x, y, 1);
  143.     }

  144.     /**
  145.      * Returns true if both arguments are NaN or they are
  146.      * equal as defined by {@link #equals(float,float) equals(x, y, 1)}.
  147.      *
  148.      * @param x first value
  149.      * @param y second value
  150.      * @return {@code true} if the values are equal or both are NaN.
  151.      */
  152.     public static boolean equalsIncludingNaN(float x, float y) {
  153.         final boolean xIsNan = Float.isNaN(x);
  154.         final boolean yIsNan = Float.isNaN(y);
  155.         // Combine the booleans with bitwise OR
  156.         return (xIsNan | yIsNan) ?
  157.             xIsNan == yIsNan :
  158.             equals(x, y, 1);
  159.     }

  160.     /**
  161.      * Returns {@code true} if there is no float value strictly between the
  162.      * arguments or the difference between them is within the range of allowed
  163.      * error (inclusive). Returns {@code false} if either of the arguments
  164.      * is NaN.
  165.      *
  166.      * @param x first value
  167.      * @param y second value
  168.      * @param eps the amount of absolute error to allow.
  169.      * @return {@code true} if the values are equal or within range of each other.
  170.      */
  171.     public static boolean equals(float x, float y, float eps) {
  172.         return equals(x, y, 1) || Math.abs(y - x) <= eps;
  173.     }

  174.     /**
  175.      * Returns true if the arguments are both NaN, there are no float value strictly
  176.      * between the arguments or the difference between them is within the range of allowed
  177.      * error (inclusive).
  178.      *
  179.      * @param x first value
  180.      * @param y second value
  181.      * @param eps the amount of absolute error to allow.
  182.      * @return {@code true} if the values are equal or within range of each other,
  183.      * or both are NaN.
  184.      */
  185.     public static boolean equalsIncludingNaN(float x, float y, float eps) {
  186.         return equalsIncludingNaN(x, y, 1) || Math.abs(y - x) <= eps;
  187.     }

  188.     /**
  189.      * Returns true if the arguments are equal or within the range of allowed
  190.      * error (inclusive). Returns {@code false} if either of the arguments is NaN.
  191.      * <p>
  192.      * Two double numbers are considered equal if there are {@code (maxUlps - 1)}
  193.      * (or fewer) floating point numbers between them, i.e. two adjacent
  194.      * floating point numbers are considered equal.
  195.      * </p>
  196.      * <p>
  197.      * Adapted from <a
  198.      * href="http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/">
  199.      * Bruce Dawson</a>.
  200.      * </p>
  201.      *
  202.      * @param x first value
  203.      * @param y second value
  204.      * @param maxUlps {@code (maxUlps - 1)} is the number of floating point
  205.      * values between {@code x} and {@code y}.
  206.      * @return {@code true} if there are fewer than {@code maxUlps} floating
  207.      * point values between {@code x} and {@code y}.
  208.      */
  209.     public static boolean equals(final float x, final float y, final int maxUlps) {
  210.         final int xInt = Float.floatToRawIntBits(x);
  211.         final int yInt = Float.floatToRawIntBits(y);

  212.         final boolean isEqual;
  213.         if ((xInt ^ yInt) < 0) {
  214.             // Numbers have opposite signs, take care of overflow.
  215.             // Remove the sign bit to obtain the absolute ULP above zero.
  216.             final int deltaPlus = xInt & Integer.MAX_VALUE;
  217.             final int deltaMinus = yInt & Integer.MAX_VALUE;

  218.             // Avoid possible overflow from adding the deltas by using a long.
  219.             isEqual = (long) deltaPlus + deltaMinus <= maxUlps;
  220.         } else {
  221.             // Numbers have same sign, there is no risk of overflow.
  222.             isEqual = Math.abs(xInt - yInt) <= maxUlps;
  223.         }

  224.         return isEqual && !Float.isNaN(x) && !Float.isNaN(y);
  225.     }

  226.     /**
  227.      * Returns true if both arguments are NaN or if they are equal as defined
  228.      * by {@link #equals(float,float,int) equals(x, y, maxUlps)}.
  229.      *
  230.      * @param x first value
  231.      * @param y second value
  232.      * @param maxUlps {@code (maxUlps - 1)} is the number of floating point
  233.      * values between {@code x} and {@code y}.
  234.      * @return {@code true} if both arguments are NaN or if there are less than
  235.      * {@code maxUlps} floating point values between {@code x} and {@code y}.
  236.      */
  237.     public static boolean equalsIncludingNaN(float x, float y, int maxUlps) {
  238.         final boolean xIsNan = Float.isNaN(x);
  239.         final boolean yIsNan = Float.isNaN(y);
  240.         // Combine the booleans with bitwise OR
  241.         return (xIsNan | yIsNan) ?
  242.             xIsNan == yIsNan :
  243.             equals(x, y, maxUlps);
  244.     }

  245.     /**
  246.      * Returns true iff they are equal as defined by
  247.      * {@link #equals(double,double,int) equals(x, y, 1)}.
  248.      *
  249.      * @param x first value
  250.      * @param y second value
  251.      * @return {@code true} if the values are equal.
  252.      */
  253.     public static boolean equals(double x, double y) {
  254.         return equals(x, y, 1);
  255.     }

  256.     /**
  257.      * Returns true if the arguments are both NaN or they are
  258.      * equal as defined by {@link #equals(double,double) equals(x, y, 1)}.
  259.      *
  260.      * @param x first value
  261.      * @param y second value
  262.      * @return {@code true} if the values are equal or both are NaN.
  263.      */
  264.     public static boolean equalsIncludingNaN(double x, double y) {
  265.         final boolean xIsNan = Double.isNaN(x);
  266.         final boolean yIsNan = Double.isNaN(y);
  267.         // Combine the booleans with bitwise OR
  268.         return (xIsNan | yIsNan) ?
  269.             xIsNan == yIsNan :
  270.             equals(x, y, 1);
  271.     }

  272.     /**
  273.      * Returns {@code true} if there is no double value strictly between the
  274.      * arguments or the difference between them is within the range of allowed
  275.      * error (inclusive). Returns {@code false} if either of the arguments
  276.      * is NaN.
  277.      *
  278.      * @param x First value.
  279.      * @param y Second value.
  280.      * @param eps Amount of allowed absolute error.
  281.      * @return {@code true} if the values are equal or within range of each other.
  282.      */
  283.     public static boolean equals(double x, double y, double eps) {
  284.         return equals(x, y, 1) || Math.abs(y - x) <= eps;
  285.     }

  286.     /**
  287.      * Returns {@code true} if there is no double value strictly between the
  288.      * arguments or the relative difference between them is less than or equal
  289.      * to the given tolerance. Returns {@code false} if either of the arguments
  290.      * is NaN.
  291.      *
  292.      * @param x First value.
  293.      * @param y Second value.
  294.      * @param eps Amount of allowed relative error.
  295.      * @return {@code true} if the values are two adjacent floating point
  296.      * numbers or they are within range of each other.
  297.      */
  298.     public static boolean equalsWithRelativeTolerance(double x, double y, double eps) {
  299.         if (equals(x, y, 1)) {
  300.             return true;
  301.         }

  302.         final double absoluteMax = Math.max(Math.abs(x), Math.abs(y));
  303.         final double relativeDifference = Math.abs((x - y) / absoluteMax);

  304.         return relativeDifference <= eps;
  305.     }

  306.     /**
  307.      * Returns true if the arguments are both NaN, there are no double value strictly
  308.      * between the arguments or the difference between them is within the range of allowed
  309.      * error (inclusive).
  310.      *
  311.      * @param x first value
  312.      * @param y second value
  313.      * @param eps the amount of absolute error to allow.
  314.      * @return {@code true} if the values are equal or within range of each other,
  315.      * or both are NaN.
  316.      */
  317.     public static boolean equalsIncludingNaN(double x, double y, double eps) {
  318.         return equalsIncludingNaN(x, y) || Math.abs(y - x) <= eps;
  319.     }

  320.     /**
  321.      * Returns true if the arguments are equal or within the range of allowed
  322.      * error (inclusive). Returns {@code false} if either of the arguments is NaN.
  323.      * <p>
  324.      * Two float numbers are considered equal if there are {@code (maxUlps - 1)}
  325.      * (or fewer) floating point numbers between them, i.e. two adjacent
  326.      * floating point numbers are considered equal.
  327.      * </p>
  328.      * <p>
  329.      * Adapted from <a
  330.      * href="http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/">
  331.      * Bruce Dawson</a>.
  332.      * </p>
  333.      *
  334.      * @param x first value
  335.      * @param y second value
  336.      * @param maxUlps {@code (maxUlps - 1)} is the number of floating point
  337.      * values between {@code x} and {@code y}.
  338.      * @return {@code true} if there are fewer than {@code maxUlps} floating
  339.      * point values between {@code x} and {@code y}.
  340.      */
  341.     public static boolean equals(final double x, final double y, final int maxUlps) {
  342.         final long xInt = Double.doubleToRawLongBits(x);
  343.         final long yInt = Double.doubleToRawLongBits(y);

  344.         if ((xInt ^ yInt) < 0) {
  345.             // Numbers have opposite signs, take care of overflow.
  346.             // Remove the sign bit to obtain the absolute ULP above zero.
  347.             final long deltaPlus = xInt & Long.MAX_VALUE;
  348.             final long deltaMinus = yInt & Long.MAX_VALUE;

  349.             // Note:
  350.             // If either value is NaN, the exponent bits are set to (2047L << 52) and the
  351.             // distance above 0.0 is always above an integer ULP error. So omit the test
  352.             // for NaN and return directly.

  353.             // Avoid possible overflow from adding the deltas by splitting the comparison
  354.             return deltaPlus <= maxUlps && deltaMinus <= (maxUlps - deltaPlus);
  355.         }

  356.         // Numbers have same sign, there is no risk of overflow.
  357.         return Math.abs(xInt - yInt) <= maxUlps && !Double.isNaN(x) && !Double.isNaN(y);
  358.     }

  359.     /**
  360.      * Returns true if both arguments are NaN or if they are equal as defined
  361.      * by {@link #equals(double,double,int) equals(x, y, maxUlps)}.
  362.      *
  363.      * @param x first value
  364.      * @param y second value
  365.      * @param maxUlps {@code (maxUlps - 1)} is the number of floating point
  366.      * values between {@code x} and {@code y}.
  367.      * @return {@code true} if both arguments are NaN or if there are less than
  368.      * {@code maxUlps} floating point values between {@code x} and {@code y}.
  369.      */
  370.     public static boolean equalsIncludingNaN(double x, double y, int maxUlps) {
  371.         final boolean xIsNan = Double.isNaN(x);
  372.         final boolean yIsNan = Double.isNaN(y);
  373.         // Combine the booleans with bitwise OR
  374.         return (xIsNan | yIsNan) ?
  375.             xIsNan == yIsNan :
  376.             equals(x, y, maxUlps);
  377.     }

  378.     /**
  379.      * Rounds the given value to the specified number of decimal places.
  380.      * The value is rounded using {@link RoundingMode#HALF_UP}.
  381.      *
  382.      * <p>Note: This method is intended to act on the String representation
  383.      * of the {@code double} argument. See {@link #round(double, int, RoundingMode)}
  384.      * for details.
  385.      *
  386.      * @param x Value to round.
  387.      * @param scale Number of digits to the right of the decimal point.
  388.      * @return the rounded value.
  389.      * @see #round(double, int, RoundingMode)
  390.      */
  391.     public static double round(double x, int scale) {
  392.         return round(x, scale, RoundingMode.HALF_UP);
  393.     }

  394.     /**
  395.      * Rounds the given value to the specified number of decimal places.
  396.      * The value is rounded using the given {@link RoundingMode rounding mode}.
  397.      *
  398.      * <p>If {@code x} is infinite or {@code NaN}, then the value of {@code x} is
  399.      * returned unchanged, regardless of the other parameters.
  400.      *
  401.      * <p><b>Note</b>
  402.      *
  403.      * <p>Rounding of a 64-bit base-2 format {@code double} using a decimal representation
  404.      * may result in rounding during conversion to and/or from a base-10 representation.
  405.      *
  406.      * <p>This method is intended to act on the String representation of the {@code double}
  407.      * argument, i.e. the closest representable decimal value. The argument is converted to
  408.      * a String (with possible rounding), rounding is performed on the decimal representation,
  409.      * and the resulting String is returned as the closest representable {@code double}.
  410.      *
  411.      * <p>Conversion from base-2 to base-10 format uses the {@link BigDecimal#valueOf(double)}
  412.      * method. The alternative would be to use
  413.      * {@link BigDecimal#BigDecimal(double) new BigDecimal(x)} to construct an exact decimal
  414.      * representation of the value.
  415.      *
  416.      * <p>Conversion from base-10 to base-2 format uses the equivalent of
  417.      * {@link Double#parseDouble(String)} to create the closest representable {@code double}
  418.      * to the decimal value.
  419.      *
  420.      * <p>The following code demonstrates how to eliminate rounding during conversion to a
  421.      * decimal format. The return conversion to a {@code double} may be inexact:
  422.      * <pre>
  423.      * double rounded = new BigDecimal(x).setScale(scale, roundingMode).doubleValue();
  424.      * </pre>
  425.      *
  426.      * <p>Acting on the String representation of the {@code double} allows this method to
  427.      * return expected output when rounding {@code double} representations of decimal text.
  428.      * <pre>
  429.      * Precision.round(39.245, 2) == 39.25
  430.      * Precision.round(30.095, 2) == 30.1
  431.      * Precision.round(30.645, 2) == 30.65
  432.      * </pre>
  433.      *
  434.      * @param x Value to round.
  435.      * @param scale Number of digits to the right of the decimal point.
  436.      * @param roundingMode Rounding mode as defined in {@link BigDecimal}.
  437.      * @return the rounded value.
  438.      * @see BigDecimal#doubleValue()
  439.      * @throws ArithmeticException if {@code roundingMode} is
  440.      * {@link RoundingMode#UNNECESSARY} and the specified scaling operation
  441.      * would require rounding.
  442.      */
  443.     public static double round(double x,
  444.                                int scale,
  445.                                RoundingMode roundingMode) {
  446.         try {
  447.             final double rounded = (new BigDecimal(Double.toString(x))
  448.                    .setScale(scale, roundingMode))
  449.                    .doubleValue();
  450.             // MATH-1089: negative values rounded to zero should result in negative zero
  451.             return rounded == POSITIVE_ZERO ? POSITIVE_ZERO * x : rounded;
  452.         } catch (NumberFormatException ex) {
  453.             if (Double.isInfinite(x)) {
  454.                 return x;
  455.             }
  456.             return Double.NaN;
  457.         }
  458.     }

  459.     /**
  460.      * Computes a number close to {@code delta} with the property that
  461.      * {@code (x + delta - x)} is exactly machine-representable.
  462.      * This is useful when computing numerical derivatives, in order to
  463.      * reduce roundoff errors.
  464.      *
  465.      * @param x Value.
  466.      * @param delta Offset value.
  467.      * @return the machine-representable floating number closest to the
  468.      * difference between {@code x + delta} and {@code x}.
  469.      */
  470.     public static double representableDelta(double x,
  471.                                             double delta) {
  472.         return x + delta - x;
  473.     }

  474.     /**
  475.      * Creates a {@link DoubleEquivalence} instance that uses the given epsilon
  476.      * value for determining equality.
  477.      *
  478.      * @param eps Value to use for determining equality.
  479.      * @return a new instance.
  480.      */
  481.     public static DoubleEquivalence doubleEquivalenceOfEpsilon(final double eps) {
  482.         if (!Double.isFinite(eps) ||
  483.             eps < 0d) {
  484.             throw new IllegalArgumentException("Invalid epsilon value: " + eps);
  485.         }

  486.         return new DoubleEquivalence() {
  487.             /** Epsilon value. */
  488.             private final double epsilon = eps;

  489.             /** {@inheritDoc} */
  490.             @Override
  491.             public int compare(double a,
  492.                                double b) {
  493.                 return Precision.compareTo(a, b, epsilon);
  494.             }
  495.         };
  496.     }

  497.     /**
  498.      * Interface containing comparison operations for doubles that allow values
  499.      * to be <em>considered</em> equal even if they are not exactly equal.
  500.      * It is intended for comparing outputs of a computation where floating
  501.      * point errors may have occurred.
  502.      */
  503.     public interface DoubleEquivalence {
  504.         /**
  505.          * Indicates whether given values are considered equal to each other.
  506.          *
  507.          * @param a Value.
  508.          * @param b Value.
  509.          * @return true if the given values are considered equal.
  510.          */
  511.         default boolean eq(double a, double b) {
  512.             return compare(a, b) == 0;
  513.         }

  514.         /**
  515.          * Indicates whether the given value is considered equal to zero.
  516.          * It is a shortcut for {@code eq(a, 0.0)}.
  517.          *
  518.          * @param a Value.
  519.          * @return true if the argument is considered equal to zero.
  520.          */
  521.         default boolean eqZero(double a) {
  522.             return eq(a, 0d);
  523.         }

  524.         /**
  525.          * Indicates whether the first argument is strictly smaller than the second.
  526.          *
  527.          * @param a Value.
  528.          * @param b Value.
  529.          * @return true if {@code a < b}
  530.          */
  531.         default boolean lt(double a, double b) {
  532.             return compare(a, b) < 0;
  533.         }

  534.         /**
  535.          * Indicates whether the first argument is smaller or considered equal to the second.
  536.          *
  537.          * @param a Value.
  538.          * @param b Value.
  539.          * @return true if {@code a <= b}
  540.          */
  541.         default boolean lte(double a, double b) {
  542.             return compare(a, b) <= 0;
  543.         }

  544.         /**
  545.          * Indicates whether the first argument is strictly greater than the second.
  546.          *
  547.          * @param a Value.
  548.          * @param b Value.
  549.          * @return true if {@code a > b}
  550.          */
  551.         default boolean gt(double a, double b) {
  552.             return compare(a, b) > 0;
  553.         }

  554.         /**
  555.          * Indicates whether the first argument is greater than or considered equal to the second.
  556.          *
  557.          * @param a Value.
  558.          * @param b Value.
  559.          * @return true if {@code a >= b}
  560.          */
  561.         default boolean gte(double a, double b) {
  562.             return compare(a, b) >= 0;
  563.         }

  564.         /**
  565.          * Returns the {@link Math#signum(double) sign} of the argument.
  566.          * The returned value is
  567.          * <ul>
  568.          *  <li>{@code -0.0} if {@code a} is considered equal to zero and negatively signed,</li>
  569.          *  <li>{@code +0.0} if {@code a} is considered equal to zero and positively signed,</li>
  570.          *  <li>{@code -1.0} if {@code a} is considered less than zero,</li>
  571.          *  <li>{@code +1.0} if {@code a} is considered greater than zero.</li>
  572.          * </ul>
  573.          *
  574.          * <p>The equality with zero uses the {@link #eqZero(double) eqZero} method.
  575.          *
  576.          * @param a Value.
  577.          * @return the sign (or {@code a} if {@code a == 0} or
  578.          * {@code a} is NaN).
  579.          * @see #eqZero(double)
  580.          */
  581.         default double signum(double a) {
  582.             if (a == 0d || Double.isNaN(a)) {
  583.                 return a;
  584.             }
  585.             return eqZero(a) ?
  586.                 Math.copySign(0d, a) :
  587.                 Math.copySign(1d, a);
  588.         }

  589.         /**
  590.          * Compares two values.
  591.          * The returned value is
  592.          * <ul>
  593.          *  <li>{@code 0} if the arguments are considered equal,</li>
  594.          *  <li>{@code -1} if {@code a < b},</li>
  595.          *  <li>{@code +1} if {@code a > b} or if either value is NaN.</li>
  596.          * </ul>
  597.          *
  598.          * @param a Value.
  599.          * @param b Value.
  600.          * @return {@code 0} if the values are considered equal, {@code -1}
  601.          * if the first is smaller than the second, {@code 1} is the first
  602.          * is larger than the second or either value is NaN.
  603.          */
  604.         int compare(double a, double b);
  605.     }
  606. }