java.lang.Object
ch.randelshofer.fastdoubleparser.FastDoubleMath

final class FastDoubleMath extends Object
This class provides the mathematical functions needed by JavaDoubleParser.

References:

Daniel Lemire, fast_float number parsing library: 4x faster than strtod. MIT License.
github.com
Daniel Lemire, Number Parsing at a Gigabyte per Second, Software: Practice and Experience 51 (8), 2021. arXiv.2101.11408v3 [cs.DS] 24 Feb 2021
arxiv.org
Clinger WD (1990). How to read floating point numbers accurately. ACM SIGPLAN Notices.
- no link -

  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final int
    Bias used in the exponent of a double.
    (package private) static final int
    Largest power of 10 value of the exponent.
    private static final int
     
    (package private) static final int
    Smallest power of 10 value of the exponent.
    private static final int
     
    private static final double[]
    Precomputed powers of ten from 10^0 to 10^22.
    static final int
    The number of bits in the significand, including the implicit bit.
    (package private) static final long[]
    A complement to mantissa_64 complete to a 128-bit mantissa.
    (package private) static final long[]
    When mapping numbers from decimal to binary, we go from w * 10^q to m * 2^p, but we have 10^q = 5^q * 2^q, so effectively we are trying to match w * 2^q * 5^q to m * 2^p.
    static final int
     
  • Constructor Summary

    Constructors
    Modifier
    Constructor
    Description
    private
    Don't let anyone instantiate this class.
  • Method Summary

    Modifier and Type
    Method
    Description
    (package private) static double
    fastScalb(double number, long scaleFactor)
    This is a faster alternative to Math.scalb(double, int).
    (package private) static double
    tryDecFloatToDoubleTruncated(boolean isNegative, long significand, int exponent, boolean isSignificandTruncated, int exponentOfTruncatedSignificand)
    Tries to compute significand * 10^exponent exactly using a fast algorithm; and if isNegative is true, negate the result; the significand can be truncated.
    (package private) static double
    tryDecToDoubleWithFastAlgorithm(boolean isNegative, long significand, int power)
    Tries to compute significand * 10^power exactly using a fast algorithm; and if isNegative is true, negate the result.
    (package private) static double
    tryHexFloatToDoubleTruncated(boolean isNegative, long significand, long exponent, boolean isSignificandTruncated, long exponentOfTruncatedSignificand)
    Tries to compute significand * 2^exponent exactly using a fast algorithm; and if isNegative is true, negate the result; the significand can be truncated.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • DOUBLE_EXPONENT_BIAS

      public static final int DOUBLE_EXPONENT_BIAS
      Bias used in the exponent of a double.
      See Also:
    • DOUBLE_SIGNIFICAND_WIDTH

      public static final int DOUBLE_SIGNIFICAND_WIDTH
      The number of bits in the significand, including the implicit bit.
      See Also:
    • MAX_REQUIRED_DIGITS

      public static final int MAX_REQUIRED_DIGITS
      See Also:
    • DOUBLE_MIN_EXPONENT_POWER_OF_TEN

      static final int DOUBLE_MIN_EXPONENT_POWER_OF_TEN
      Smallest power of 10 value of the exponent.

      The smallest non-zero double is 2^−1074.

      We take as input numbers of the form w x 10^q where w invalid input: '<' 2^64.

      We have that w * 10^-343 < 2^(63-343) * 5^-343 < 2^-1076.

      However, we have that (2^64-1) * 10^-342 = (2^64 - 1) * 2^-342 * 5^-342 > 2^−1074. Thus, it is possible for a number of the form w * 10^-342 where w is a 64-bit value to be a non-zero double.

      ********

      If we are solely interested in the *normal* numbers then the smallest value is 2^-1022. We can generate a value larger than 2^-1022 with expressions of the form w * 10^-326. Thus, we need to pick SMALLEST_POWER_OF_TEN >= -326.

      See Also:
    • DOUBLE_MAX_EXPONENT_POWER_OF_TEN

      static final int DOUBLE_MAX_EXPONENT_POWER_OF_TEN
      Largest power of 10 value of the exponent.

      Any number of form w * 10^309 where w >= 1 is going to be infinite in a double, so we never need to worry about powers of 10 greater than 308.

      See Also:
    • MANTISSA_64

      static final long[] MANTISSA_64
      When mapping numbers from decimal to binary, we go from w * 10^q to m * 2^p, but we have 10^q = 5^q * 2^q, so effectively we are trying to match w * 2^q * 5^q to m * 2^p.

      Thus, the powers of two are not a concern since they can be represented exactly using the binary notation, only the powers of five affect the binary significand.

      The mantissas of powers of ten from -308 to 308, extended out to sixty-four bits. The array contains the powers of ten approximated as a 64-bit mantissa. It goes from 10^-325 to 10^308 (inclusively). The mantissa is truncated, and never rounded up. Uses about 5 KB.

       long getMantissaHigh(int q) {
        MANTISSA_64[q - SMALLEST_POWER_OF_TEN];
       }
       
    • MANTISSA_128

      static final long[] MANTISSA_128
      A complement to mantissa_64 complete to a 128-bit mantissa.

      Uses about 5KB but is rarely accessed.

       UInt128 getMantissa128(int q) {
           return new UInt128(
              MANTISSA_64[q - SMALLEST_POWER_OF_TEN],
              MANTISSA_128[q - SMALLEST_POWER_OF_TEN];
           );
       }
       
    • DOUBLE_MIN_EXPONENT_POWER_OF_TWO

      private static final int DOUBLE_MIN_EXPONENT_POWER_OF_TWO
      See Also:
    • DOUBLE_MAX_EXPONENT_POWER_OF_TWO

      private static final int DOUBLE_MAX_EXPONENT_POWER_OF_TWO
      See Also:
    • DOUBLE_POWERS_OF_TEN

      private static final double[] DOUBLE_POWERS_OF_TEN
      Precomputed powers of ten from 10^0 to 10^22. These can be represented exactly using the double type.
  • Constructor Details

    • FastDoubleMath

      private FastDoubleMath()
      Don't let anyone instantiate this class.
  • Method Details

    • tryDecFloatToDoubleTruncated

      static double tryDecFloatToDoubleTruncated(boolean isNegative, long significand, int exponent, boolean isSignificandTruncated, int exponentOfTruncatedSignificand)
      Tries to compute significand * 10^exponent exactly using a fast algorithm; and if isNegative is true, negate the result; the significand can be truncated.
      Parameters:
      isNegative - true if the sign is negative
      significand - the significand
      exponent - the exponent number (the power)
      isSignificandTruncated - true if significand has been truncated
      exponentOfTruncatedSignificand - the exponent number of the truncated significand
      Returns:
      the double value, or Double.NaN if the fast path failed.
    • tryDecToDoubleWithFastAlgorithm

      static double tryDecToDoubleWithFastAlgorithm(boolean isNegative, long significand, int power)
      Tries to compute significand * 10^power exactly using a fast algorithm; and if isNegative is true, negate the result.

      This function will only work in some cases, when it does not work it returns NaN. This should work *most of the time* (like 99% of the time). We assume that power is in the [-325, 308] interval: the caller is responsible for this check.

      References:

      Noble Mushtak, Daniel Lemire. (2023) Fast Number Parsing Without Fallback.
      arxiv.org
      Parameters:
      isNegative - whether the number is negative
      significand - uint64 the significand
      power - the exponent number (the power)
      Returns:
      the computed double on success, Double.NaN on failure
    • tryHexFloatToDoubleTruncated

      static double tryHexFloatToDoubleTruncated(boolean isNegative, long significand, long exponent, boolean isSignificandTruncated, long exponentOfTruncatedSignificand)
      Tries to compute significand * 2^exponent exactly using a fast algorithm; and if isNegative is true, negate the result; the significand can be truncated.
      Parameters:
      isNegative - true if the sign is negative
      significand - the significand (unsigned long, uint64)
      exponent - the exponent number (the power)
      isSignificandTruncated - true if significand has been truncated
      exponentOfTruncatedSignificand - the exponent number of the truncated significand
      Returns:
      the double value, or Double.NaN if the fast path failed.
    • fastScalb

      static double fastScalb(double number, long scaleFactor)
      This is a faster alternative to Math.scalb(double, int).

      This method only works if scaleFactor is within the range of Double.MIN_EXPONENT through Double.MAX_EXPONENT (inclusive), so that we do not underflow or overflow.

      Parameters:
      number - a double number
      scaleFactor - the scale factor
      Returns:
      number × 2scaleFactor