inline double StrtodFullPrecision()

in src/main/cpp/sdk/common/rapidjson/internal/strtod.h [226:285]


inline double StrtodFullPrecision(double d, int p, const char* decimals, size_t length, size_t decimalPosition, int exp) {
    RAPIDJSON_ASSERT(d >= 0.0);
    RAPIDJSON_ASSERT(length >= 1);

    double result = 0.0;
    if (StrtodFast(d, p, &result))
        return result;

    RAPIDJSON_ASSERT(length <= INT_MAX);
    int dLen = static_cast<int>(length);

    RAPIDJSON_ASSERT(length >= decimalPosition);
    RAPIDJSON_ASSERT(length - decimalPosition <= INT_MAX);
    int dExpAdjust = static_cast<int>(length - decimalPosition);

    RAPIDJSON_ASSERT(exp >= INT_MIN + dExpAdjust);
    int dExp = exp - dExpAdjust;

    // Make sure length+dExp does not overflow
    RAPIDJSON_ASSERT(dExp <= INT_MAX - dLen);

    // Trim leading zeros
    while (dLen > 0 && *decimals == '0') {
        dLen--;
        decimals++;
    }

    // Trim trailing zeros
    while (dLen > 0 && decimals[dLen - 1] == '0') {
        dLen--;
        dExp++;
    }

    if (dLen == 0) { // Buffer only contains zeros.
        return 0.0;
    }

    // Trim right-most digits
    const int kMaxDecimalDigit = 767 + 1;
    if (dLen > kMaxDecimalDigit) {
        dExp += dLen - kMaxDecimalDigit;
        dLen = kMaxDecimalDigit;
    }

    // If too small, underflow to zero.
    // Any x <= 10^-324 is interpreted as zero.
    if (dLen + dExp <= -324)
        return 0.0;

    // If too large, overflow to infinity.
    // Any x >= 10^309 is interpreted as +infinity.
    if (dLen + dExp > 309)
        return std::numeric_limits<double>::infinity();

    if (StrtodDiyFp(decimals, dLen, dExp, &result))
        return result;

    // Use approximation from StrtodDiyFp and make adjustment with BigInteger comparison
    return StrtodBigInteger(result, decimals, dLen, dExp);
}