Current section
Files
Jump to
Current section
Files
src/bigi_ffi.erl
-module(bigi_ffi).
-export([
from/1,
from_string/1,
to/1,
zero/0,
compare/2,
add/2,
subtract/2,
multiply/2,
divide/2,
divide_no_zero/2,
remainder/2,
remainder_no_zero/2,
modulo/2,
modulo_no_zero/2,
power/2,
decode/1
]).
from(Int) -> Int.
from_string(Str) ->
case string:to_integer(Str) of
{_, Rest} when Rest /= <<"">> -> {error, nil};
{Int, _} -> {ok, Int}
end.
to(BigInt) -> {ok, BigInt}.
zero() -> 0.
compare(A, B) when A < B -> gt;
compare(A, B) when A > B -> lt;
compare(_, _) -> eq.
add(A, B) -> A + B.
subtract(A, B) -> A - B.
multiply(A, B) -> A * B.
divide(_, 0) -> 0;
divide(A, B) -> A div B.
divide_no_zero(_, 0) -> {error, nil};
divide_no_zero(A, B) -> {ok, divide(A, B)}.
remainder(_, 0) -> 0;
remainder(A, B) -> A rem B.
remainder_no_zero(_, 0) -> {error, nil};
remainder_no_zero(A, B) -> {ok, remainder(A, B)}.
modulo(_, 0) -> 0;
modulo(A, B) -> ((A rem B) + B) rem B.
modulo_no_zero(_, 0) -> {error, nil};
modulo_no_zero(A, B) -> {ok, modulo(A, B)}.
power(_, Exp) when Exp < 0 -> {error, nil};
power(Base, Exp) -> {ok, do_power(Base, Exp)}.
do_power(_, 0) ->
1;
do_power(A, 1) ->
A;
do_power(A, N) ->
B = do_power(A, N div 2),
B * B *
(case N rem 2 of
0 -> 1;
1 -> A
end).
decode(Dyn) when is_integer(Dyn) -> {ok, Dyn};
decode(Dyn) -> {error, {decode_error, <<"bigint">>, get_type(Dyn), []}}.
get_type(Val) when is_atom(Val) -> <<"atom">>;
get_type(Val) when is_function(Val) -> <<"function">>;
get_type(Val) when is_pid(Val) -> <<"pid">>;
get_type(Val) when is_binary(Val) -> <<"binary">>;
get_type(Val) when is_list(Val) -> <<"list">>;
get_type(Val) when is_map(Val) -> <<"map">>;
get_type(Val) when is_reference(Val) -> <<"reference">>;
get_type(Val) when is_float(Val) -> <<"float">>;
get_type(Val) when is_tuple(Val) -> <<"tuple">>;
get_type(Val) when is_port(Val) -> <<"port">>;
get_type(Val) when is_bitstring(Val) -> <<"bitstring">>.