Class FastDoubleMath
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
FieldsModifier and TypeFieldDescriptionstatic final intBias used in the exponent of a double.(package private) static final intLargest power of 10 value of the exponent.private static final int(package private) static final intSmallest power of 10 value of the exponent.private static final intprivate static final double[]Precomputed powers of ten from 10^0 to 10^22.static final intThe 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 -
Method Summary
Modifier and TypeMethodDescription(package private) static doublefastScalb(double number, long scaleFactor) This is a faster alternative toMath.scalb(double, int).(package private) static doubletryDecFloatToDoubleTruncated(boolean isNegative, long significand, int exponent, boolean isSignificandTruncated, int exponentOfTruncatedSignificand) Tries to computesignificand * 10^exponentexactly using a fast algorithm; and ifisNegativeis true, negate the result; the significand can be truncated.(package private) static doubletryDecToDoubleWithFastAlgorithm(boolean isNegative, long significand, int power) Tries to computesignificand * 10^powerexactly using a fast algorithm; and ifisNegativeis true, negate the result.(package private) static doubletryHexFloatToDoubleTruncated(boolean isNegative, long significand, long exponent, boolean isSignificandTruncated, long exponentOfTruncatedSignificand) Tries to computesignificand * 2^exponentexactly using a fast algorithm; and ifisNegativeis true, negate the result; the significand can be truncated.
-
Field Details
-
DOUBLE_EXPONENT_BIAS
public static final int DOUBLE_EXPONENT_BIASBias used in the exponent of a double.- See Also:
-
DOUBLE_SIGNIFICAND_WIDTH
public static final int DOUBLE_SIGNIFICAND_WIDTHThe 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_TENSmallest 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_TENLargest 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_64When 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_128A 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_TENPrecomputed 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 computesignificand * 10^exponentexactly using a fast algorithm; and ifisNegativeis true, negate the result; the significand can be truncated.- Parameters:
isNegative- true if the sign is negativesignificand- the significandexponent- the exponent number (the power)isSignificandTruncated- true if significand has been truncatedexponentOfTruncatedSignificand- the exponent number of the truncated significand- Returns:
- the double value,
or
Double.NaNif the fast path failed.
-
tryDecToDoubleWithFastAlgorithm
static double tryDecToDoubleWithFastAlgorithm(boolean isNegative, long significand, int power) Tries to computesignificand * 10^powerexactly using a fast algorithm; and ifisNegativeis 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 negativesignificand- uint64 the significandpower- the exponent number (the power)- Returns:
- the computed double on success,
Double.NaNon failure
-
tryHexFloatToDoubleTruncated
static double tryHexFloatToDoubleTruncated(boolean isNegative, long significand, long exponent, boolean isSignificandTruncated, long exponentOfTruncatedSignificand) Tries to computesignificand * 2^exponentexactly using a fast algorithm; and ifisNegativeis true, negate the result; the significand can be truncated.- Parameters:
isNegative- true if the sign is negativesignificand- the significand (unsigned long, uint64)exponent- the exponent number (the power)isSignificandTruncated- true if significand has been truncatedexponentOfTruncatedSignificand- the exponent number of the truncated significand- Returns:
- the double value,
or
Double.NaNif the fast path failed.
-
fastScalb
static double fastScalb(double number, long scaleFactor) This is a faster alternative toMath.scalb(double, int).This method only works if scaleFactor is within the range of
Double.MIN_EXPONENTthroughDouble.MAX_EXPONENT(inclusive), so that we do not underflow or overflow.- Parameters:
number- a double numberscaleFactor- the scale factor- Returns:
- number × 2scaleFactor
-