Current section
Files
Jump to
Current section
Files
src/gcalc.erl
-module(gcalc).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([pow/2, factorial/1, abs/1, sqrt/1, pow2/1, pow10/1, cbrt/1]).
-export_type([math_error/0]).
-type math_error() :: division_by_zero |
value_out_of_range |
unsupported_operation.
-spec pow_iter(float(), float(), float()) -> float().
pow_iter(Base, Power, Accumulator) ->
case Power of
+0.0 ->
Accumulator;
_ ->
pow_iter(Base, Power - 1.0, Base * Accumulator)
end.
-spec pow(float(), float()) -> float().
pow(Base, Power) ->
pow_iter(Base, Power, 1.0).
-spec factorial_iter(float(), float()) -> float().
factorial_iter(N, Accumulator) ->
case N of
+0.0 ->
Accumulator;
_ ->
factorial_iter(N - 1.0, N * Accumulator)
end.
-spec factorial(float()) -> {ok, float()} | {error, math_error()}.
factorial(N) ->
case N < +0.0 of
true ->
{error, unsupported_operation};
false ->
{ok, factorial_iter(N, 1.0)}
end.
-spec abs(float()) -> float().
abs(N) ->
case N < +0.0 of
true ->
+0.0 - N;
false ->
N
end.
-spec sqrt_iter(float(), float(), float()) -> float().
sqrt_iter(X0, X1, N) ->
case abs(X1 - X0) < 0.0001 of
true ->
X1;
false ->
X0@1 = X1,
X1@1 = (X0@1 + (case X0@1 of
+0.0 -> +0.0;
-0.0 -> -0.0;
Gleam@denominator -> N / Gleam@denominator
end)) / 2.0,
sqrt_iter(X0@1, X1@1, N)
end.
-spec sqrt(float()) -> {ok, float()} | {error, math_error()}.
sqrt(N) ->
case N < +0.0 of
true ->
{error, value_out_of_range};
false ->
{ok, sqrt_iter(+0.0, 1.0, N)}
end.
-spec pow2_iter(float(), float()) -> float().
pow2_iter(N, Accumulator) ->
case N of
+0.0 ->
Accumulator;
_ ->
pow2_iter(N - 1.0, 2.0 * Accumulator)
end.
-spec pow2(float()) -> {ok, float()} | {error, math_error()}.
pow2(N) ->
case N < +0.0 of
true ->
{error, value_out_of_range};
false ->
{ok, pow2_iter(N, 1.0)}
end.
-spec pow10_iter(float(), float()) -> float().
pow10_iter(N, Accumulator) ->
case N of
+0.0 ->
Accumulator;
_ ->
pow10_iter(N - 1.0, 10.0 * Accumulator)
end.
-spec pow10(float()) -> {ok, float()} | {error, math_error()}.
pow10(N) ->
case N < +0.0 of
true ->
{error, value_out_of_range};
false ->
{ok, pow10_iter(N, 1.0)}
end.
-spec cbrt_iter(float(), float(), float()) -> float().
cbrt_iter(X0, X1, N) ->
case abs(X1 - X0) < 0.0001 of
true ->
X1;
false ->
X0@1 = X1,
X1@1 = (X0@1 + (case (X0@1 * X0@1) of
+0.0 -> +0.0;
-0.0 -> -0.0;
Gleam@denominator -> N / Gleam@denominator
end)) / 2.0,
cbrt_iter(X0@1, X1@1, N)
end.
-spec cbrt(float()) -> {ok, float()} | {error, math_error()}.
cbrt(N) ->
case N < +0.0 of
true ->
{error, value_out_of_range};
false ->
{ok, cbrt_iter(+0.0, 1.0, N)}
end.