in core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF8.java [3566:3735]
public final double readDoubleValue() {
double doubleValue = 0;
final byte[] bytes = this.bytes;
int quote = '\0';
int ch = this.ch;
int offset = this.offset, end = this.end;
if (ch == '"' || ch == '\'') {
quote = ch;
ch = offset == end ? EOI : bytes[offset++];
}
long result;
boolean wasNull = false;
if (quote != 0 && ch == quote) {
ch = offset == end ? EOI : bytes[offset++];
wasNull = true;
result = 0;
} else {
int fc = ch;
result = ch >= '0' && ch <= '9'
? '0' - ch
: ch == '-' || ch == '+'
? 0
: 1; // or any value > 0
int d;
while (result <= 0
&& offset + 1 < end
&& (d = IOUtils.digit2(bytes, offset)) != -1) {
if (Long.MIN_VALUE / 100 <= result) {
result = result * 100 - d; // overflow from d => result > 0
offset += 2;
} else {
result = 1; // overflow
}
}
if (result <= 0 && offset < end && IOUtils.isDigit(ch = bytes[offset])) {
if (Long.MIN_VALUE / 10 <= result) {
result = result * 10 + '0' - ch; // overflow from '0' - d => result > 0
offset++;
} else {
result = 1; // overflow
}
}
int scale = 0;
if (result <= 0
&& offset < end
&& bytes[offset] == '.'
) {
offset++;
while (result <= 0
&& offset + 1 < end
&& (d = IOUtils.digit2(bytes, offset)) != -1) {
if (Long.MIN_VALUE / 100 <= result) {
result = result * 100 - d; // overflow from d => result > 0
offset += 2;
scale += 2;
} else {
result = 1; // overflow
}
}
if (result <= 0 && offset < end && IOUtils.isDigit(ch = bytes[offset])) {
if (Long.MIN_VALUE / 10 <= result) {
result = result * 10 + '0' - ch; // overflow from '0' - d => result > 0
offset++;
scale++;
} else {
result = 1; // overflow
}
}
}
if (result <= 0) {
ch = offset == end ? EOI : bytes[offset++];
}
int expValue;
if (result <= 0) {
if (ch == 'e' || ch == 'E') {
boolean negativeExp;
ch = offset == end ? EOI : bytes[offset++];
if ((negativeExp = (ch == '-')) || ch == '+') {
ch = offset == end ? EOI : bytes[offset++];
} else if (ch == ',') {
throw numberError();
}
if (IOUtils.isDigit(ch)) {
expValue = ch - '0';
while (offset < end
&& IOUtils.isDigit((ch = bytes[offset]))
) {
d = ch - '0';
expValue = expValue * 10 + d;
if (expValue > MAX_EXP) {
throw new JSONException("too large exp value : " + expValue);
}
offset++;
}
if (negativeExp) {
expValue = -expValue;
}
scale -= expValue;
ch = offset == end ? EOI : bytes[offset++];
} else {
result = 1; // invalid
}
} else if (ch == 'L' || ch == 'F' || ch == 'D' || ch == 'B' || ch == 'S') {
ch = offset == end ? EOI : bytes[offset++];
}
}
if (result <= 0 && quote != 0) {
if (ch == quote) {
ch = offset == end ? EOI : bytes[offset++];
} else {
result = 1; // invalid
}
}
if (result <= 0) {
boolean value = true;
if (scale == 0) {
doubleValue = (double) result;
} else if ((long) (double) result == result) {
if (0 < scale && scale < DOUBLE_10_POW.length) {
doubleValue = (double) result / DOUBLE_10_POW[scale];
} else if (0 > scale && scale > -DOUBLE_10_POW.length) {
doubleValue = (double) result * DOUBLE_10_POW[-scale];
} else {
value = false;
}
} else {
value = false;
}
if (!value) {
if (scale > 0 && scale < 64) {
doubleValue = TypeUtils.doubleValue(fc == '-' ? -1 : 1, Math.abs(result), scale);
} else {
result = 1; // invalid
}
} else {
if (fc != '-' && doubleValue != 0) {
doubleValue = -doubleValue;
}
}
}
}
if (result > 0) {
readNumber0();
return getDoubleValue();
}
while (ch <= ' ' && ((1L << ch) & SPACE) != 0) {
ch = offset == end ? EOI : bytes[offset++];
}
if (comma = (ch == ',')) {
ch = offset == end ? EOI : bytes[offset++];
while (ch <= ' ' && ((1L << ch) & SPACE) != 0) {
ch = offset == end ? EOI : bytes[offset++];
}
}
this.wasNull = wasNull;
this.ch = (char) ch;
this.offset = offset;
return doubleValue;
}