code: /*
   * Copyright 2012-2018 Chronicle Map Contributors
   * Copyright 2001-2015 The Apache Software Foundation
   * Copyright 2010-2012 CS Systèmes d'Information
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package net.openhft.chronicle.hash.impl.util.math;
  
  class Precision {
  
      /**
       * Offset to order signed double numbers lexicographically.
       */
      private static final long SGN_MASK = 0x8000000000000000L;
      /**
       * Positive zero bits.
       */
      private static final long POSITIVE_ZERO_DOUBLE_BITS = Double.doubleToRawLongBits(+0.0);
      /**
       * Negative zero bits.
       */
      private static final long NEGATIVE_ZERO_DOUBLE_BITS = Double.doubleToRawLongBits(-0.0);
  
      /**
       * Returns {@code true} if there is no double value strictly between the
       * arguments or the difference between them is within the range of allowed
       * error (inclusive).
       *
       * @param x   First value.
       * @param y   Second value.
       * @param eps Amount of allowed absolute error.
       * @return {@code true} if the values are two adjacent floating point
       * numbers or they are within range of each other.
       */
      public static boolean isEquals(double x, double y, double eps) {
          return isEquals(x, y, 1) || Math.abs(y - x) <= eps;
      }
  
      /**
       * Returns <code>true</code> if both arguments are equal or within the range of allowed
       * error (inclusive).
       * <p>
       * Two float numbers are considered equal if there are {@code (maxUlps - 1)}
       * (or fewer) floating point numbers between them, i.e. two adjacent
       * floating point numbers are considered equal.
       * </p>
       * <p>
       * Adapted from <a
       * href="http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/">
       * Bruce Dawson</a>
       * </p>
       *
       * @param x       first value
       * @param y       second value
       * @param maxUlps {@code (maxUlps - 1)} is the number of floating point
       *                values between {@code x} and {@code y}.
       * @return {@code true} if there are fewer than {@code maxUlps} floating
       * point values between {@code x} and {@code y}.
       */
      public static boolean isEquals(final double x, final double y, final int maxUlps) {
  
          final long xInt = Double.doubleToRawLongBits(x);
          final long yInt = Double.doubleToRawLongBits(y);
  
          final boolean isEqual;
          if (((xInt ^ yInt) & SGN_MASK) == 0L) {
              // number have same sign, there is no risk of overflow
              isEqual = Math.abs(xInt - yInt) <= maxUlps;
          } else {
              // number have opposite signs, take care of overflow
              final long deltaPlus;
              final long deltaMinus;
              if (xInt < yInt) {
                  deltaPlus = yInt - POSITIVE_ZERO_DOUBLE_BITS;
                  deltaMinus = xInt - NEGATIVE_ZERO_DOUBLE_BITS;
              } else {
                  deltaPlus = xInt - POSITIVE_ZERO_DOUBLE_BITS;
                  deltaMinus = yInt - NEGATIVE_ZERO_DOUBLE_BITS;
              }
  
              if (deltaPlus > maxUlps) {
                  isEqual = false;
              } else {
                  isEqual = deltaMinus <= (maxUlps - deltaPlus);
              }
          }
  
          return isEqual && !Double.isNaN(x) && !Double.isNaN(y);
  
      }
  }
  