Current section

Files

Jump to
frac src frac.erl
Raw

src/frac.erl

-module(frac).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([to_float/1, from_int/1, numerator/1, denominator/1, new/2, approximate/2, to_mixed_numbers/1, divide/2, multiply/2, add/2, subtract/2, compare/2]).
-export_type([fraction/0]).
-opaque fraction() :: {fraction, integer(), integer()}.
-file("/Users/giacomocavalieri/Documents/progetti/frac/src/frac.gleam", 40).
-spec to_float(fraction()) -> float().
to_float(Fraction) ->
{fraction, Numerator, Denominator} = Fraction,
case gleam@int:to_float(Denominator) of
+0.0 -> +0.0;
-0.0 -> -0.0;
Gleam@denominator -> gleam@int:to_float(Numerator) / Gleam@denominator
end.
-file("/Users/giacomocavalieri/Documents/progetti/frac/src/frac.gleam", 54).
-spec from_int(integer()) -> fraction().
from_int(Numerator) ->
{fraction, Numerator, 1}.
-file("/Users/giacomocavalieri/Documents/progetti/frac/src/frac.gleam", 131).
-spec numerator(fraction()) -> integer().
numerator(Fraction) ->
erlang:element(2, Fraction).
-file("/Users/giacomocavalieri/Documents/progetti/frac/src/frac.gleam", 137).
-spec denominator(fraction()) -> integer().
denominator(Fraction) ->
erlang:element(3, Fraction).
-file("/Users/giacomocavalieri/Documents/progetti/frac/src/frac.gleam", 276).
-spec gcd(integer(), integer()) -> integer().
gcd(A, B) ->
case {A, B} of
{Gcd, 0} ->
gleam@int:absolute_value(Gcd);
{A@1, B@1} ->
gcd(B@1, case B@1 of
0 -> 0;
Gleam@denominator -> A@1 rem Gleam@denominator
end)
end.
-file("/Users/giacomocavalieri/Documents/progetti/frac/src/frac.gleam", 77).
-spec to_lowest_terms(integer(), integer()) -> fraction().
to_lowest_terms(Numerator, Denominator) ->
Gcd = gcd(Numerator, Denominator),
Numerator@1 = case Gcd of
0 -> 0;
Gleam@denominator -> Numerator div Gleam@denominator
end,
Denominator@1 = case Gcd of
0 -> 0;
Gleam@denominator@1 -> Denominator div Gleam@denominator@1
end,
{fraction, Numerator@1, Denominator@1}.
-file("/Users/giacomocavalieri/Documents/progetti/frac/src/frac.gleam", 70).
-spec new(integer(), integer()) -> fraction().
new(Numerator, Denominator) ->
case Denominator >= 0 of
true ->
to_lowest_terms(Numerator, Denominator);
false ->
to_lowest_terms(- Numerator, - Denominator)
end.
-file("/Users/giacomocavalieri/Documents/progetti/frac/src/frac.gleam", 110).
-spec factors(
integer(),
integer(),
integer(),
integer(),
integer(),
integer(),
integer(),
integer()
) -> fraction().
factors(X, Prev, N1, D1, N2, D2, Max_d, Scale) ->
X@1 = case (X - (Prev * Scale)) of
0 -> 0;
Gleam@denominator -> Scale * Scale div Gleam@denominator
end,
A = case Scale of
0 -> 0;
Gleam@denominator@1 -> X@1 div Gleam@denominator@1
end,
case A of
0 ->
new(N1, D1);
_ ->
N = N2 + (A * N1),
D = D2 + (A * D1),
case D > Max_d of
true ->
new(N1, D1);
false ->
factors(X@1, A, N, D, N1, D1, Max_d, Scale)
end
end.
-file("/Users/giacomocavalieri/Documents/progetti/frac/src/frac.gleam", 98).
-spec approximate(float(), integer()) -> fraction().
approximate(Float, Limit) ->
Scale = 100000,
X = gleam@float:round(Float * gleam@int:to_float(Scale)),
A = case Scale of
0 -> 0;
Gleam@denominator -> X div Gleam@denominator
end,
X@1 = case (X - (A * Scale)) of
0 -> 0;
Gleam@denominator@1 -> (Scale * Scale) div Gleam@denominator@1
end,
B = case Scale of
0 -> 0;
Gleam@denominator@2 -> X@1 div Gleam@denominator@2
end,
factors(X@1, B, (A * B) + 1, B, A, 1, Limit, Scale).
-file("/Users/giacomocavalieri/Documents/progetti/frac/src/frac.gleam", 156).
-spec to_mixed_numbers(fraction()) -> {integer(), fraction()}.
to_mixed_numbers(Fraction) ->
{fraction, Numerator, Denominator} = Fraction,
{case Denominator of
0 -> 0;
Gleam@denominator -> Numerator div Gleam@denominator
end, new(case Denominator of
0 -> 0;
Gleam@denominator@1 -> Numerator rem Gleam@denominator@1
end, Denominator)}.
-file("/Users/giacomocavalieri/Documents/progetti/frac/src/frac.gleam", 174).
-spec divide(fraction(), fraction()) -> fraction().
divide(One, Other) ->
new(
erlang:element(2, One) * erlang:element(3, Other),
erlang:element(3, One) * erlang:element(2, Other)
).
-file("/Users/giacomocavalieri/Documents/progetti/frac/src/frac.gleam", 189).
-spec multiply(fraction(), fraction()) -> fraction().
multiply(One, Other) ->
new(
erlang:element(2, One) * erlang:element(2, Other),
erlang:element(3, One) * erlang:element(3, Other)
).
-file("/Users/giacomocavalieri/Documents/progetti/frac/src/frac.gleam", 204).
-spec add(fraction(), fraction()) -> fraction().
add(One, Other) ->
{fraction, One_num, One_den} = One,
{fraction, Other_num, Other_den} = Other,
Gcd = gcd(One_num, Other_num),
new((case Gcd of
0 -> 0;
Gleam@denominator -> (One_den * Other_num) div Gleam@denominator
end) + (case Gcd of
0 -> 0;
Gleam@denominator@1 -> (Other_den * One_num) div Gleam@denominator@1
end), case Gcd of
0 -> 0;
Gleam@denominator@2 -> (One_den * Other_den) div Gleam@denominator@2
end).
-file("/Users/giacomocavalieri/Documents/progetti/frac/src/frac.gleam", 224).
-spec subtract(fraction(), fraction()) -> fraction().
subtract(One, Other) ->
{fraction, One_num, One_den} = One,
{fraction, Other_num, Other_den} = Other,
Gcd = gcd(One_num, Other_num),
new((case Gcd of
0 -> 0;
Gleam@denominator -> (Other_den * One_num) div Gleam@denominator
end) - (case Gcd of
0 -> 0;
Gleam@denominator@1 -> (One_den * Other_num) div Gleam@denominator@1
end), case Gcd of
0 -> 0;
Gleam@denominator@2 -> One_den * Other_den div Gleam@denominator@2
end).
-file("/Users/giacomocavalieri/Documents/progetti/frac/src/frac.gleam", 247).
-spec compare(fraction(), fraction()) -> gleam@order:order().
compare(One, Other) ->
case {One, Other} of
{_, _} when One =:= Other ->
eq;
{{fraction, One_num, _}, {fraction, Other_num, _}} when (One_num >= 0) andalso (Other_num < 0) ->
gt;
{{fraction, One_num@1, _}, {fraction, Other_num@1, _}} when (Other_num@1 >= 0) andalso (One_num@1 < 0) ->
lt;
{{fraction, One_num@2, One_den}, {fraction, Other_num@2, Other_den}} ->
Gcd = gcd(One_num@2, Other_num@2),
One_num@3 = case Gcd of
0 -> 0;
Gleam@denominator -> (Other_den * One_num@2) div Gleam@denominator
end,
Other_num@3 = case Gcd of
0 -> 0;
Gleam@denominator@1 -> (One_den * Other_num@2) div Gleam@denominator@1
end,
gleam@int:compare(One_num@3, Other_num@3)
end.