public static float floatValue(boolean isNegative, int decExponent, byte[] digits, int nDigits) {
        final int SINGLE_MAX_NDIGITS = 200;
        final int SINGLE_MAX_DECIMAL_DIGITS = 7;
        final int MAX_DECIMAL_DIGITS = 15;
        final int FLOAT_EXP_BIAS = 127;
        final int SINGLE_EXP_SHIFT = 24 /*FLOAT_SIGNIFICAND_WIDTH*/ - 1;
        final int SINGLE_MAX_SMALL_TEN = SINGLE_SMALL_10_POW.length - 1;

        int kDigits = Math.min(nDigits, SINGLE_MAX_DECIMAL_DIGITS + 1);
        int iValue = (int) digits[0] - (int) '0';
        for (int i = 1; i < kDigits; i++) {
            iValue = iValue * 10 + (int) digits[i] - (int) '0';
        }
        float fValue = (float) iValue;
        int exp = decExponent - kDigits;

        if (nDigits <= SINGLE_MAX_DECIMAL_DIGITS) {
            if (exp == 0 || fValue == 0.0f) {
                return (isNegative) ? -fValue : fValue; // small floating integer
            } else if (exp >= 0) {
                if (exp <= SINGLE_MAX_SMALL_TEN) {
                    fValue *= SINGLE_SMALL_10_POW[exp];
                    return (isNegative) ? -fValue : fValue;
                }
                int slop = SINGLE_MAX_DECIMAL_DIGITS - kDigits;
                if (exp <= SINGLE_MAX_SMALL_TEN + slop) {
                    fValue *= SINGLE_SMALL_10_POW[slop];
                    fValue *= SINGLE_SMALL_10_POW[exp - slop];
                    return (isNegative) ? -fValue : fValue;
                }
            } else {
                if (exp >= -SINGLE_MAX_SMALL_TEN) {
                    fValue /= SINGLE_SMALL_10_POW[-exp];
                    return (isNegative) ? -fValue : fValue;
                }
            }
        } else if ((decExponent >= nDigits) && (nDigits + decExponent <= MAX_DECIMAL_DIGITS)) {
            long lValue = iValue;
            for (int i = kDigits; i < nDigits; i++) {
                lValue = lValue * 10L + (long) ((int) digits[i] - (int) '0');
            }
            double dValue = (double) lValue;
            exp = decExponent - nDigits;
            dValue *= SMALL_10_POW[exp];
            fValue = (float) dValue;
            return (isNegative) ? -fValue : fValue;
        }
        double dValue = fValue;
        if (exp > 0) {
            final int SINGLE_MAX_DECIMAL_EXPONENT = 38;
            if (decExponent > SINGLE_MAX_DECIMAL_EXPONENT + 1) {
                return (isNegative) ? Float.NEGATIVE_INFINITY : Float.POSITIVE_INFINITY;
            }
            if ((exp & 15) != 0) {
                dValue *= SMALL_10_POW[exp & 15];
            }
            if ((exp >>= 4) != 0) {
                int j;
                for (j = 0; exp > 0; j++, exp >>= 1) {
                    if ((exp & 1) != 0) {
                        dValue *= BIG_10_POW[j];
                    }
                }
            }
        } else if (exp < 0) {
            exp = -exp;
            final int SINGLE_MIN_DECIMAL_EXPONENT = -45;
            if (decExponent < SINGLE_MIN_DECIMAL_EXPONENT - 1) {
                return (isNegative) ? -0.0f : 0.0f;
            }
            if ((exp & 15) != 0) {
                dValue /= SMALL_10_POW[exp & 15];
            }
            if ((exp >>= 4) != 0) {
                int j;
                for (j = 0; exp > 0; j++, exp >>= 1) {
                    if ((exp & 1) != 0) {
                        dValue *= TINY_10_POW[j];
                    }
                }
            }
        }
        fValue = Math.max(Float.MIN_VALUE, Math.min(Float.MAX_VALUE, (float) dValue));

        if (nDigits > SINGLE_MAX_NDIGITS) {
            nDigits = SINGLE_MAX_NDIGITS + 1;
            digits[SINGLE_MAX_NDIGITS] = '1';
        }
        FDBigInteger bigD0 = new FDBigInteger(iValue, digits, kDigits, nDigits);
        exp = decExponent - nDigits;

        int ieeeBits = Float.floatToRawIntBits(fValue); // IEEE-754 bits of float candidate
        final int B5 = Math.max(0, -exp); // powers of 5 in bigB, value is not modified inside correctionLoop
        final int D5 = Math.max(0, exp); // powers of 5 in bigD, value is not modified inside correctionLoop
        bigD0 = bigD0.multByPow52(D5, 0);
        bigD0.makeImmutable();   // prevent bigD0 modification inside correctionLoop
        FDBigInteger bigD = null;
        int prevD2 = 0;

        while (true) {
            // here ieeeBits can't be NaN, Infinity or zero
            int binexp = ieeeBits >>> SINGLE_EXP_SHIFT;
            final int FLOAT_SIGNIF_BIT_MASK = 0x007FFFFF;
            int bigBbits = ieeeBits & FLOAT_SIGNIF_BIT_MASK;
            if (binexp > 0) {
                final int SINGLE_FRACT_HOB = 1 << 23;
                bigBbits |= SINGLE_FRACT_HOB;
            } else { // Normalize denormalized numbers.
                assert bigBbits != 0 : bigBbits; // floatToBigInt(0.0)
                int leadingZeros = Integer.numberOfLeadingZeros(bigBbits);
                int shift = leadingZeros - (31 - SINGLE_EXP_SHIFT);
                bigBbits <<= shift;
                binexp = 1 - shift;
            }
            binexp -= FLOAT_EXP_BIAS;
            int lowOrderZeros = Integer.numberOfTrailingZeros(bigBbits);
            bigBbits >>>= lowOrderZeros;
            final int bigIntExp = binexp - SINGLE_EXP_SHIFT + lowOrderZeros;
            final int bigIntNBits = SINGLE_EXP_SHIFT + 1 - lowOrderZeros;

            int B2 = B5; // powers of 2 in bigB
            int D2 = D5; // powers of 2 in bigD
            int Ulp2;   // powers of 2 in halfUlp.
            if (bigIntExp >= 0) {
                B2 += bigIntExp;
            } else {
                D2 -= bigIntExp;
            }
            Ulp2 = B2;

            int hulpbias;
            if (binexp <= -FLOAT_EXP_BIAS) {
                hulpbias = binexp + lowOrderZeros + FLOAT_EXP_BIAS;
            } else {
                hulpbias = 1 + lowOrderZeros;
            }
            B2 += hulpbias;
            D2 += hulpbias;

            int common2 = Math.min(B2, Math.min(D2, Ulp2));
            B2 -= common2;
            D2 -= common2;
            Ulp2 -= common2;
            // do multiplications by powers of 5 and 2
            FDBigInteger bigB = FDBigInteger.valueOfMulPow52(bigBbits, B5, B2);
            if (bigD == null || prevD2 != D2) {
                bigD = bigD0.leftShift(D2);
                prevD2 = D2;
            }

            FDBigInteger diff;
            int cmpResult;
            boolean overvalue;
            if ((cmpResult = bigB.cmp(bigD)) > 0) {
                overvalue = true; // our candidate is too big.
                diff = bigB.leftInplaceSub(bigD); // bigB is not user further - reuse
                if ((bigIntNBits == 1) && (bigIntExp > -FLOAT_EXP_BIAS + 1)) {
                    Ulp2 -= 1;
                    if (Ulp2 < 0) {
                        Ulp2 = 0;
                        diff = diff.leftShift(1);
                    }
                }
            } else if (cmpResult < 0) {
                overvalue = false; // our candidate is too small.
                diff = bigD.rightInplaceSub(bigB); // bigB is not user further - reuse
            } else {
                break;
            }
            cmpResult = diff.cmpPow52(B5, Ulp2);
            if ((cmpResult) < 0) {
                break;
            } else if (cmpResult == 0) {
                if ((ieeeBits & 1) != 0) { // half ties to even
                    ieeeBits += overvalue ? -1 : 1; // nextDown or nextUp
                }
                break;
            } else {
                ieeeBits += overvalue ? -1 : 1; // nextDown or nextUp
                final int FLOAT_EXP_BIT_MASK = 0x7F800000;
                if (ieeeBits == 0 || ieeeBits == FLOAT_EXP_BIT_MASK) { // 0.0 or Float.POSITIVE_INFINITY
                    break; // oops. Fell off end of range.
                }
            }
        }
        if (isNegative) {
            final int FLOAT_SIGN_BIT_MASK = 0x80000000;
            ieeeBits |= FLOAT_SIGN_BIT_MASK;
        }
        return Float.intBitsToFloat(ieeeBits);
    }
All the positive powers of 10 that can be
represented exactly in double/float.
core/src/main/java/com/alibaba/fastjson2/util/TypeUtils.java