Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,19 @@ com.fasterxml.jackson.core.*;version=${project.version}
</plugins>
</build>

<dependencies>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
</dependencies>

</project>

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
* References:
* <dl>
* <dt>This class has been derived from "FastDoubleParser".</dt>
* <dd>Copyright (c) Werner Randelshofer. Apache 2.0 License.
* <a href="https://github.com/wrandelshofer/FastDoubleParser">github.com</a>.</dd>
* </dl>
*/

package com.fasterxml.jackson.core.io.doubleparser;

/**
* Abstract base class for parsers that parse a {@code FloatValue} from a
* character sequence ({@code str}).
* <p>
* This is a C++ to Java port of Daniel Lemire's fast_double_parser.
* <p>
* References:
* <dl>
* <dt>Daniel Lemire, fast_double_parser, 4x faster than strtod.
* Apache License 2.0 or Boost Software License.</dt>
* <dd><a href="https://github.com/lemire/fast_double_parser">github.com</a></dd>
*
* <dt>Daniel Lemire, fast_float number parsing library: 4x faster than strtod.
* Apache License 2.0.</dt>
* <dd><a href="https://github.com/fastfloat/fast_float">github.com</a></dd>
*
* <dt>Daniel Lemire, Number Parsing at a Gigabyte per Second,
* Software: Practice and Experience 51 (8), 2021.
* arXiv.2101.11408v3 [cs.DS] 24 Feb 2021</dt>
* <dd><a href="https://arxiv.org/pdf/2101.11408.pdf">arxiv.org</a></dd>
* </dl>
*/
abstract class AbstractFloatValueParser {
final static long MINIMAL_NINETEEN_DIGIT_INTEGER = 1000_00000_00000_00000L;
/**
* The decimal exponent of a double has a range of -324 to +308.
* The hexadecimal exponent of a double has a range of -1022 to +1023.
*/
final static int MAX_EXPONENT_NUMBER = 1024;
/**
* Special value in {@link #CHAR_TO_HEX_MAP} for
* the decimal point character.
*/
static final byte DECIMAL_POINT_CLASS = -4;
/**
* Special value in {@link #CHAR_TO_HEX_MAP} for
* characters that are neither a hex digit nor
* a decimal point character..
*/
static final byte OTHER_CLASS = -1;
/**
* Includes all non-negative values of a {@code byte}, so that we only have
* to check for byte values {@literal <} 0 before accessing this array.
*/
static final byte[] CHAR_TO_HEX_MAP = new byte[128];

static {
for (char ch = 0; ch < AbstractFloatValueParser.CHAR_TO_HEX_MAP.length; ch++) {
AbstractFloatValueParser.CHAR_TO_HEX_MAP[ch] = AbstractFloatValueParser.OTHER_CLASS;
}
for (char ch = '0'; ch <= '9'; ch++) {
AbstractFloatValueParser.CHAR_TO_HEX_MAP[ch] = (byte) (ch - '0');
}
for (char ch = 'A'; ch <= 'F'; ch++) {
AbstractFloatValueParser.CHAR_TO_HEX_MAP[ch] = (byte) (ch - 'A' + 10);
}
for (char ch = 'a'; ch <= 'f'; ch++) {
AbstractFloatValueParser.CHAR_TO_HEX_MAP[ch] = (byte) (ch - 'a' + 10);
}
for (char ch = '.'; ch <= '.'; ch++) {
AbstractFloatValueParser.CHAR_TO_HEX_MAP[ch] = AbstractFloatValueParser.DECIMAL_POINT_CLASS;
}
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/**
* References:
* <dl>
* <dt>This class has been derived from "FastDoubleParser".</dt>
* <dd>Copyright (c) Werner Randelshofer. Apache 2.0 License.
* <a href="https://github.com/wrandelshofer/FastDoubleParser">github.com</a>.</dd>
* </dl>
*/

package com.fasterxml.jackson.core.io.doubleparser;

/**
* Parses a {@code double} from a {@link CharSequence}.
*/
public final class DoubleFromCharSequence extends AbstractFloatValueFromCharSequence {


/**
* Creates a new instance.
*/
public DoubleFromCharSequence() {

}

@Override
long nan() {
return Double.doubleToRawLongBits(Double.NaN);
}

@Override
long negativeInfinity() {
return Double.doubleToRawLongBits(Double.NEGATIVE_INFINITY);
}

/**
* Parses a {@code FloatValue} from a {@link CharSequence} and converts it
* into a {@code double} value.
* <p>
* See {@link com.fasterxml.jackson.core.io.doubleparser} for the syntax of {@code FloatValue}.
*
* @param str the string to be parsed
* @param offset the start offset of the {@code FloatValue} in {@code str}
* @param length the length of {@code FloatValue} in {@code str}
* @return the parsed double value
* @throws NumberFormatException if the string can not be parsed
*/
public double parseDouble(CharSequence str, int offset, int length) throws NumberFormatException {
return Double.longBitsToDouble(parseFloatValue(str, offset, length));
}

@Override
long positiveInfinity() {
return Double.doubleToRawLongBits(Double.POSITIVE_INFINITY);
}

@Override
long valueOfFloatLiteral(CharSequence str, int startIndex, int endIndex, boolean isNegative,
long significand, int exponent, boolean isSignificandTruncated,
int exponentOfTruncatedSignificand) {
double d = FastDoubleMath.tryDecFloatToDoubleTruncated(isNegative, significand, exponent, isSignificandTruncated,
exponentOfTruncatedSignificand);
return Double.doubleToRawLongBits(Double.isNaN(d) ? Double.parseDouble(str.subSequence(startIndex, endIndex).toString()) : d);
}

@Override
long valueOfHexLiteral(
CharSequence str, int startIndex, int endIndex, boolean isNegative, long significand, int exponent,
boolean isSignificandTruncated, int exponentOfTruncatedSignificand) {
double d = FastDoubleMath.tryHexFloatToDoubleTruncated(isNegative, significand, exponent, isSignificandTruncated,
exponentOfTruncatedSignificand);
return Double.doubleToRawLongBits(Double.isNaN(d) ? Double.parseDouble(str.subSequence(startIndex, endIndex).toString()) : d);
}

}
Loading