Skip to content

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

Open
znz wants to merge 1 commit into
ruby:masterfrom
znz:copilot/investigate-jsonminefieldparser-warnings
Open

Avoid Float out of range warning for clearly underflowing numbers#1044
znz wants to merge 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants