public final double readDoubleValue()

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;
    }