Skip to content

Avoid Float out of range warning for clearly underflowing numbers#1044

Merged
byroot merged 1 commit into
ruby:masterfrom
znz:copilot/investigate-jsonminefieldparser-warnings
Jun 27, 2026
Merged

Avoid Float out of range warning for clearly underflowing numbers#1044
byroot merged 1 commit into
ruby:masterfrom
znz:copilot/investigate-jsonminefieldparser-warnings

Conversation

@znz

@znz znz commented Jun 26, 2026

Copy link
Copy Markdown
Member

Two new minefield parser tests (test_i_number_double_huge_neg_exp, test_i_number_real_underflow) introduced in 6507a836c5 cause spurious CI warnings because numbers like 123.456e-789 and 123e-10000000 fall through to json_decode_large_floatrb_cstr_to_dblstrtod, which sets errno=ERANGE on underflow and triggers Ruby's rb_warning("Float %s out of range", ...).

Fix

Add an early-return guard in json_decode_float() before the rb_cstr_to_dbl fallback:

if (RB_UNLIKELY(mantissa_digits > 18 || mantissa_digits + exponent < -307)) {
    if (RB_UNLIKELY(mantissa_digits + exponent < -324)) {
        return rb_float_new(negative ? -0.0 : 0.0);
    }
    return json_decode_large_float(start, end - start);
}

When mantissa_digits + exponent < -324, the value is bounded above by 10^(-324) = 1e-324 < DBL_TRUE_MIN/2 ≈ 2.47e-324, so IEEE 754 round-to-nearest guarantees a result of 0.0 — no need to call rb_cstr_to_dbl. The subnormal range (-324 ≤ mantissa_digits + exponent < -307) still goes through rb_cstr_to_dbl for accurate results.

Same approach as 5b4d95b8d0 which added the exponent < INT32_MIN → 0.0 fast-path with the same motivation.

When parsing JSON floats with extremely negative exponents (like
123.456e-789 or 123e-10000000), the parser would fall back to
rb_cstr_to_dbl which internally calls strtod. When strtod returns
ERANGE due to underflow to 0.0, Ruby emits a "Float out of range"
warning, causing noise in the test output.

Fix: when mantissa_digits + exponent < -324, the effective value is
less than 10^(-324) < DBL_TRUE_MIN/2, so it must round to 0.0 in
IEEE 754 round-to-nearest. Return 0.0 directly without going through
rb_cstr_to_dbl, avoiding the spurious warning.

This fixes warnings introduced by JSONMinefieldParserTest tests
(test_i_number_double_huge_neg_exp and test_i_number_real_underflow)
added in commit 6507a836c5.
@byroot byroot merged commit 724edda into ruby:master Jun 27, 2026
42 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

3 participants