From 8e22ba5b8d0d29277b498d61fc7124dc1d39128a Mon Sep 17 00:00:00 2001 From: Peter M Date: Sat, 4 Apr 2026 08:26:29 +0200 Subject: [PATCH] Fix test_json failure on single-precision (float32) Three JSON test suite cases (y_number, y_number_real_exponent, y_number_real_fraction_exponent) contain float values that exceed the IEEE 754 float32 range (~3.4e38), e.g. 1.23e67, 1.23e47, 1.23456e80. On AVM_USE_SINGLE_PRECISION builds, binary_to_float/1 calls strtof() which returns inf for these values, failing the isfinite() check and raising badarg. Skip these three test cases on single-precision builds by checking erlang:system_info(avm_floatsize) at runtime, following the existing pattern used in floatext.erl and other float-sensitive tests. And: Fix test_json encode test for single-precision float32 On float32 builds, 3.14 is stored as 3.1400001 (nearest IEEE 754 single-precision representation), so float_to_binary produces <<"3.1400001">> rather than <<"3.14">>. Use is_single_precision() to expect the correct output for each precision. Signed-off-by: Peter M --- tests/libs/estdlib/test_json.erl | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/tests/libs/estdlib/test_json.erl b/tests/libs/estdlib/test_json.erl index c661310288..c9334c11f6 100644 --- a/tests/libs/estdlib/test_json.erl +++ b/tests/libs/estdlib/test_json.erl @@ -58,7 +58,7 @@ test() -> ok. test_y() -> - lists:foreach(fun run_y_test/1, y_tests()), + lists:foreach(fun run_y_test/1, filter_precision(y_tests())), ok. test_n() -> @@ -74,7 +74,7 @@ test_t() -> ok. test_y_roundtrip() -> - lists:foreach(fun run_y_roundtrip/1, y_tests()), + lists:foreach(fun run_y_roundtrip/1, filter_precision(y_tests())), ok. test_i_roundtrip() -> @@ -125,6 +125,25 @@ resolve({external_term, Enc}) -> resolve(Term) -> Term. +%% Filter out test cases containing float values that exceed single-precision range. +filter_precision(Tests) -> + case is_single_precision() of + true -> [T || T = {Name, _, _} <- Tests, not requires_double(Name)]; + false -> Tests + end. + +is_single_precision() -> + case erlang:system_info(machine) of + "BEAM" -> false; + "ATOM" -> erlang:system_info(avm_floatsize) =:= 4 + end. + +%% Test cases with float values exceeding float32 range (~3.4e38). +requires_double("y_number.json") -> true; +requires_double("y_number_real_exponent.json") -> true; +requires_double("y_number_real_fraction_exponent.json") -> true; +requires_double(_) -> false. + to_bin(IoData) -> iolist_to_binary(IoData). test_decode_basic() -> @@ -380,7 +399,12 @@ test_encode_basic() -> <<"9007199254740993">> = to_bin(json:encode(9007199254740993)), <<"1.0">> = to_bin(json:encode(1.0)), - <<"3.14">> = to_bin(json:encode(3.14)), + case is_single_precision() of + true -> + <<"3.1400001">> = to_bin(json:encode(3.14)); + false -> + <<"3.14">> = to_bin(json:encode(3.14)) + end, <<"-2.5">> = to_bin(json:encode(-2.5)), <<"-0.0">> = to_bin(json:encode(-0.0)),