diff --git a/lib/elixir/lib/float.ex b/lib/elixir/lib/float.ex index 07313e45d31..c42907f40db 100644 --- a/lib/elixir/lib/float.ex +++ b/lib/elixir/lib/float.ex @@ -164,40 +164,50 @@ defmodule Float do end defp parse_unsigned(<>) when digit in ?0..?9, - do: parse_unsigned(rest, false, false, <>) + do: parse_unsigned(rest, false, false, [digit]) defp parse_unsigned(binary) when is_binary(binary), do: :error defp parse_unsigned(<>, dot?, e?, acc) when digit in ?0..?9, - do: parse_unsigned(rest, dot?, e?, <>) + do: parse_unsigned(rest, dot?, e?, [digit | acc]) defp parse_unsigned(<>, false, false, acc) when digit in ?0..?9, - do: parse_unsigned(rest, true, false, <>) + do: parse_unsigned(rest, true, false, [digit, ?. | acc]) defp parse_unsigned(<>, dot?, false, acc) when exp_marker in ~c"eE" and digit in ?0..?9, - do: parse_unsigned(rest, true, true, <>) + do: parse_unsigned(rest, true, true, [digit, ?e | add_dot(acc, dot?)]) defp parse_unsigned(<>, dot?, false, acc) when exp_marker in ~c"eE" and sign in ~c"-+" and digit in ?0..?9, - do: parse_unsigned(rest, true, true, <>) + 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(add_dot(acc, dot?)) + acc + |> add_dot(dot?) + |> :lists.reverse() + |> :erlang.list_to_float() rescue ArgumentError -> :error else float -> {float, rest} end - defp parse_unsigned(rest, dot?, false = _e?, acc), - do: {:erlang.binary_to_float(add_dot(acc, dot?)), rest} + 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: acc <> ".0" + defp add_dot(acc, false), do: [?0, ?. | acc] @doc """ Rounds a float to the largest float less than or equal to `number`.