From c18e94e8d3044812ebfed8966dd4eabc5194c130 Mon Sep 17 00:00:00 2001 From: pnezis Date: Mon, 9 Mar 2026 16:46:10 +0200 Subject: [PATCH] Fix `Float.parse/1` inconsistent error handling for non-scientific notation overflow `Float.parse/1` was returning `:error` for overflow in scientific notation (e.g., "1.0e400") but raising `ArgumentError` for equivalent overflow in non-scientific notation (e.g., a 310-digit number). This violated the documented behavior that states `Float.parse/1` should return `:error` when the float exceeds the maximum size. --- lib/elixir/lib/float.ex | 17 +++-------------- lib/elixir/test/elixir/float_test.exs | 5 +++++ 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/lib/elixir/lib/float.ex b/lib/elixir/lib/float.ex index 801fa649c8a..ac721dda52b 100644 --- a/lib/elixir/lib/float.ex +++ b/lib/elixir/lib/float.ex @@ -186,10 +186,9 @@ defmodule Float do when exp_marker in ~c"eE" and sign in ~c"-+" and digit in ?0..?9, do: parse_unsigned(rest, true, true, [digit, sign, ?e | add_dot(acc, dot?)]) - # When floats are expressed in scientific notation, :erlang.binary_to_float/1 can raise an - # ArgumentError if the e exponent is too big. For example, "1.0e400". Because of this, we - # rescue the ArgumentError here and return an error. - defp parse_unsigned(rest, dot?, true = _e?, acc) do + # :erlang.binary_to_float/1 can raise an ArgumentError if the e exponent is too big. For example, + # "1.0e400". Because of this, we rescue the ArgumentError here and return an error. + defp parse_unsigned(rest, dot?, _, acc) do acc |> add_dot(dot?) |> :lists.reverse() @@ -200,16 +199,6 @@ defmodule Float do float -> {float, rest} end - defp parse_unsigned(rest, dot?, false = _e?, acc) do - float = - acc - |> add_dot(dot?) - |> :lists.reverse() - |> :erlang.list_to_float() - - {float, rest} - end - defp add_dot(acc, true), do: acc defp add_dot(acc, false), do: [?0, ?. | acc] diff --git a/lib/elixir/test/elixir/float_test.exs b/lib/elixir/test/elixir/float_test.exs index fbc9230a490..945aca6ec67 100644 --- a/lib/elixir/test/elixir/float_test.exs +++ b/lib/elixir/test/elixir/float_test.exs @@ -57,6 +57,11 @@ defmodule FloatTest do assert Float.parse("1.7976931348623159e308") === :error assert Float.parse("1.7976931348623159e+308") === :error assert Float.parse("9e8363") === :error + + # Non-scientific notation overflow + assert Float.parse(String.duplicate("9", 310) <> ".0") === :error + assert Float.parse("-" <> String.duplicate("9", 310) <> ".0") === :error + assert Float.parse(String.duplicate("9", 310) <> ".0foo") === :error end test "floor/1" do