public  double scanDouble(char seperator) {
        matchStat = UNKNOWN;

        int offset = bp;
        char chLocal = charAt(offset++);
        final boolean quote = chLocal == '"';
        if (quote) {
            chLocal = charAt(offset++);
        }

        boolean negative = chLocal == '-';
        if (negative) {
            chLocal = charAt(offset++);
        }

        double value;
        if (chLocal >= '0' && chLocal <= '9') {
            long intVal = chLocal - '0';
            for (; ; ) {
                chLocal = charAt(offset++);
                if (chLocal >= '0' && chLocal <= '9') {
                    intVal = intVal * 10 + (chLocal - '0');
                    continue;
                } else {
                    break;
                }
            }

            long power = 1;
            boolean small = (chLocal == '.');
            if (small) {
                chLocal = charAt(offset++);
                if (chLocal >= '0' && chLocal <= '9') {
                    intVal = intVal * 10 + (chLocal - '0');
                    power = 10;
                    for (; ; ) {
                        chLocal = charAt(offset++);
                        if (chLocal >= '0' && chLocal <= '9') {
                            intVal = intVal * 10 + (chLocal - '0');
                            power *= 10;
                            continue;
                        } else {
                            break;
                        }
                    }
                } else {
                    matchStat = NOT_MATCH;
                    return 0;
                }
            }

            boolean exp = chLocal == 'e' || chLocal == 'E';
            if (exp) {
                chLocal = charAt(offset++);
                if (chLocal == '+' || chLocal == '-') {
                    chLocal = charAt(offset++);
                }
                for (; ; ) {
                    if (chLocal >= '0' && chLocal <= '9') {
                        chLocal = charAt(offset++);
                    } else {
                        break;
                    }
                }
            }

            int start, count;
            if (quote) {
                if (chLocal != '"') {
                    matchStat = NOT_MATCH;
                    return 0;
                } else {
                    chLocal = charAt(offset++);
                }
                start = bp + 1;
                count = offset - start - 2;
            } else {
                start = bp;
                count = offset - start - 1;
            }

            if (!exp && count < 18) {
                value = ((double) intVal) / power;
                if (negative) {
                    value = -value;
                }
            } else {
                String text = this.subString(start, count);
                value = Double.parseDouble(text);
            }
        } else if (chLocal == 'n'
                && charAt(offset++) == 'u'
                && charAt(offset++) == 'l'
                && charAt(offset++) == 'l') {
            matchStat = VALUE_NULL;
            value = 0;
            chLocal = charAt(offset++);

            if (quote && chLocal == '"') {
                chLocal = charAt(offset++);
            }

            for (;;) {
                if (chLocal == ',') {
                    bp = offset;
                    this.ch = charAt(bp);
                    matchStat = VALUE_NULL;
                    token = JSONToken.COMMA;
                    return value;
                } else if (chLocal == ']') {
                    bp = offset;
                    this.ch = charAt(bp);
                    matchStat = VALUE_NULL;
                    token = JSONToken.RBRACKET;
                    return value;
                } else if (isWhitespace(chLocal)) {
                    chLocal = charAt(offset++);
                    continue;
                }
                break;
            }
            matchStat = NOT_MATCH;
            return 0;
        } else {
            matchStat = NOT_MATCH;
            return 0;
        }

        if (chLocal == seperator) {
            bp = offset;
            this.ch = this.charAt(bp);
            matchStat = VALUE;
            token = JSONToken.COMMA;
            return value;
        } else {
            matchStat = NOT_MATCH;
            return value;
        }
    }
The value of a literal token, recorded as a string. For integers, leading 0x and 'l' suffixes are suppressed.
src/main/java/com/alibaba/fastjson/parser/JSONScanner.java