Skip to content

Commit b48e105

Browse files
authored
Support negative inputs in fraction.from_float_string (#22)
1 parent 5f5a416 commit b48e105

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

.spec/math/fraction_spec.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ describe("Fraction", function()
1313
{ base = 2, str = "0.(10)", val = frac(2, 3) },
1414
{ base = nil, str = "3.(3)", val = frac(10, 3) }, -- test default base
1515
{ base = 10, str = "1.2(3)", val = frac(12, 10) + frac(1, 30) },
16+
{ base = 10, str = "1", val = frac(1, 1) },
17+
{ base = 10, str = "-2", val = frac(-2, 1) },
18+
{ base = 10, str = "-1.25", val = frac(-5, 4) },
19+
{ base = 10, str = "-1.3(51)", val = frac(-223, 165) },
1620
{ base = 16, str = "1.(45d17)", val = frac(42, 33) },
1721
}
1822

src/math/fraction.lua

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ local function read_base_param(base)
7070
return base
7171
end
7272

73-
function fraction.from_float_string(
74-
str, -- <digit>{<digit>}.{digit}[(<digit>{digit})], ex.: `-1.2(3)`
73+
local function parse_positive_double_string(
74+
str, -- EBNF: digit { digit } "." { digit } [ "(" digit { digit } ")" ], ex.: `1.2(3)`
7575
base -- integer from 2 to 36, defaults to 10 (decimal)
7676
)
7777
base = read_base_param(base)
@@ -81,6 +81,7 @@ function fraction.from_float_string(
8181

8282
local integer, fractional = str:match("^([0-9a-zA-Z][0-9a-zA-Z]-)%.([0-9a-zA-Z%(%)]+)")
8383
if not fractional then
84+
assert(str:match("[0-9a-zA-Z]+"))
8485
return new(read_number(str), 1)
8586
end
8687

@@ -96,6 +97,16 @@ function fraction.from_float_string(
9697
return read_number(integer) + after_dot / base ^ #pre_period
9798
end
9899

100+
function fraction.from_float_string(
101+
str, -- EBNF: [ "-" ] digit { digit } "." { digit } [ "(" digit { digit } ")" ], ex.: `-1.2(3)`
102+
base -- integer from 2 to 36, defaults to 10 (decimal)
103+
)
104+
if str:sub(1, 1) == "-" then
105+
return -parse_positive_double_string(str:sub(2), base)
106+
end
107+
return parse_positive_double_string(str, base)
108+
end
109+
99110
-- Conversions
100111

101112
function metatable:__tostring()

0 commit comments

Comments
 (0)