Skip to content

Commit e055c2c

Browse files
author
José Valim
committed
Merge pull request #1961 from justinj/float-parse-negative-0
Fix Float.parse to handle numbers of the form "-0.x", fixes issue #1960
2 parents 08d61e4 + 8c6e31b commit e055c2c

File tree

2 files changed

+22
-9
lines changed

2 files changed

+22
-9
lines changed

lib/elixir/lib/float.ex

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,28 +22,40 @@ defmodule Float do
2222
2323
"""
2424
@spec parse(binary) :: { float, binary } | :error
25-
def parse(binary) when is_binary(binary) do
25+
def parse("-" <> binary) do
26+
case parse_unsign(binary) do
27+
:error -> :error
28+
{ number, remainder } -> { -number, remainder }
29+
end
30+
end
31+
32+
def parse(binary) do
33+
parse_unsign(binary)
34+
end
35+
36+
defp parse_unsign("-" <> binary), do: :error
37+
defp parse_unsign(binary) when is_binary(binary) do
2638
case Integer.parse binary do
2739
:error -> :error
28-
{ integer_part, after_integer } -> parse after_integer, integer_part
40+
{ integer_part, after_integer } -> parse_unsign after_integer, integer_part
2941
end
3042
end
3143

3244
# Dot followed by digit is required afterwards or we are done
33-
defp parse(<< ?., char, rest :: binary >>, int) when char in ?0..?9 do
34-
parse(rest, char - ?0, 1, int)
45+
defp parse_unsign(<< ?., char, rest :: binary >>, int) when char in ?0..?9 do
46+
parse_unsign(rest, char - ?0, 1, int)
3547
end
3648

37-
defp parse(rest, int) do
49+
defp parse_unsign(rest, int) do
3850
{ :erlang.float(int), rest }
3951
end
4052

4153
# Handle decimal points
42-
defp parse(<< char, rest :: binary >>, float, decimal, int) when char in ?0..?9 do
43-
parse rest, 10 * float + (char - ?0), decimal + 1, int
54+
defp parse_unsign(<< char, rest :: binary >>, float, decimal, int) when char in ?0..?9 do
55+
parse_unsign rest, 10 * float + (char - ?0), decimal + 1, int
4456
end
4557

46-
defp parse(<< ?e, after_e :: binary >>, float, decimal, int) do
58+
defp parse_unsign(<< ?e, after_e :: binary >>, float, decimal, int) do
4759
case Integer.parse after_e do
4860
:error ->
4961
# Note we rebuild the binary here instead of breaking it apart at
@@ -56,7 +68,7 @@ defmodule Float do
5668
end
5769
end
5870

59-
defp parse(bitstring, float, decimal, int) do
71+
defp parse_unsign(bitstring, float, decimal, int) do
6072
{ floatify(int, float, decimal), bitstring }
6173
end
6274

lib/elixir/test/elixir/float_test.exs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ defmodule FloatTest do
66
test :parse do
77
assert Float.parse("12") === {12.0, ""}
88
assert Float.parse("-12") === {-12.0, ""}
9+
assert Float.parse("-0.1") === {-0.1, ""}
910
assert Float.parse("123456789") === {123456789.0, ""}
1011
assert Float.parse("12.5") === {12.5, ""}
1112
assert Float.parse("12.524235") === {12.524235, ""}

0 commit comments

Comments
 (0)