Skip to content

Commit f19b83d

Browse files
committed
Merge pull request #3684 from redpine50/master
made Float.parse() support complete scientific notation
2 parents e45f052 + 87683ef commit f19b83d

File tree

2 files changed

+19
-10
lines changed

2 files changed

+19
-10
lines changed

lib/elixir/lib/float.ex

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,27 +37,31 @@ defmodule Float do
3737
end
3838
end
3939

40+
def parse("+" <> binary) do
41+
parse_unsigned(binary)
42+
end
43+
4044
def parse(binary) do
4145
parse_unsigned(binary)
4246
end
4347

44-
defp parse_unsigned(<<char, rest::binary>>) when char in ?0..?9, do:
45-
parse_unsigned(rest, false, false, <<char>>)
48+
defp parse_unsigned(<<digit, rest::binary>>) when digit in ?0..?9, do:
49+
parse_unsigned(rest, false, false, <<digit>>)
4650

4751
defp parse_unsigned(binary) when is_binary(binary), do:
4852
:error
4953

50-
defp parse_unsigned(<<char, rest :: binary>>, dot?, e?, acc) when char in ?0..?9, do:
51-
parse_unsigned(rest, dot?, e?, <<acc::binary, char>>)
54+
defp parse_unsigned(<<digit, rest :: binary>>, dot?, e?, acc) when digit in ?0..?9, do:
55+
parse_unsigned(rest, dot?, e?, <<acc::binary, digit>>)
5256

53-
defp parse_unsigned(<<?., char, rest :: binary>>, false, false, acc) when char in ?0..?9, do:
54-
parse_unsigned(rest, true, false, <<acc::binary, ?., char>>)
57+
defp parse_unsigned(<<?., digit, rest :: binary>>, false, false, acc) when digit in ?0..?9, do:
58+
parse_unsigned(rest, true, false, <<acc::binary, ?., digit>>)
5559

56-
defp parse_unsigned(<<?e, char, rest :: binary>>, dot?, false, acc) when char in ?0..?9, do:
57-
parse_unsigned(rest, true, true, <<add_dot(acc, dot?)::binary, ?e, char>>)
60+
defp parse_unsigned(<<exp_marker, digit, rest :: binary>>, dot?, false, acc) when exp_marker in 'eE' and digit in ?0..?9, do:
61+
parse_unsigned(rest, true, true, <<add_dot(acc, dot?)::binary, ?e, digit>>)
5862

59-
defp parse_unsigned(<<?e, ?-, char, rest :: binary>>, dot?, false, acc) when char in ?0..?9, do:
60-
parse_unsigned(rest, true, true, <<add_dot(acc, dot?)::binary, ?e, ?-, char>>)
63+
defp parse_unsigned(<<exp_marker, sign, digit, rest :: binary>>, dot?, false, acc) when exp_marker in 'eE' and sign in '-+' and digit in ?0..?9, do:
64+
parse_unsigned(rest, true, true, <<add_dot(acc, dot?)::binary, ?e, sign, digit>>)
6165

6266
defp parse_unsigned(rest, dot?, _e?, acc), do:
6367
{:erlang.binary_to_float(add_dot(acc, dot?)), rest}

lib/elixir/test/elixir/float_test.exs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ defmodule FloatTest do
2424
assert Float.parse("1.32453e-10") === {1.32453e-10, ""}
2525
assert Float.parse("1.32.45") === {1.32, ".45"}
2626
assert Float.parse("1.o") === {1.0, ".o"}
27+
assert Float.parse("+12.3E+4") === {1.23e5, ""}
28+
assert Float.parse("+12.3E-4x") === {0.00123, "x"}
29+
assert Float.parse("-1.23e-0xFF") === {-1.23, "xFF"}
30+
assert Float.parse("-1.e2") === {-1.0, ".e2"}
31+
assert Float.parse(".12") === :error
2732
assert Float.parse("--1.2") === :error
2833
assert Float.parse("++1.2") === :error
2934
assert Float.parse("pi") === :error

0 commit comments

Comments
 (0)