Current section
Files
Jump to
Current section
Files
src/ranged_int@internal@limit.erl
-module(ranged_int@internal@limit).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([check_limits/3]).
-export_type([limit/0, limit_check/0]).
-type limit() :: {bounded, bigi:big_int()} | unbounded.
-type limit_check() :: no_overflow |
{overflow, bigi:big_int()} |
{underflow, bigi:big_int()}.
-spec diff(limit(), bigi:big_int()) -> bigi:big_int().
diff(Limit, Value) ->
case Limit of
unbounded ->
bigi_ffi:zero();
{bounded, Lim} ->
bigi_ffi:subtract(Value, Lim)
end.
-spec check_limits(bigi:big_int(), limit(), limit()) -> limit_check().
check_limits(Value, Min, Max) ->
Max_diff = diff(Max, Value),
case bigi_ffi:compare(Max_diff, bigi_ffi:zero()) of
gt ->
{overflow, Max_diff};
eq ->
Min_diff = diff(Min, Value),
case bigi_ffi:compare(Min_diff, bigi_ffi:zero()) of
lt ->
{underflow, bigi_ffi:multiply(Min_diff, bigi_ffi:from(-1))};
eq ->
no_overflow;
gt ->
no_overflow
end;
lt ->
Min_diff = diff(Min, Value),
case bigi_ffi:compare(Min_diff, bigi_ffi:zero()) of
lt ->
{underflow, bigi_ffi:multiply(Min_diff, bigi_ffi:from(-1))};
eq ->
no_overflow;
gt ->
no_overflow
end
end.