Current section
Files
Jump to
Current section
Files
src/ranged_int@builtin@int128.erl
-module(ranged_int@builtin@int128).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([to_bigint/1, from_bigint/1, compare/2, absolute/1, add/2, subtract/2, multiply/2, divide/2, divide_no_zero/2, modulo/2, modulo_no_zero/2, remainder/2, remainder_no_zero/2, power/2, overflow/1, eject/1]).
-export_type([int128/0]).
-opaque int128() :: {int128, bigi:big_int()}.
-spec to_bigint(int128()) -> bigi:big_int().
to_bigint(Uint) ->
erlang:element(2, Uint).
-spec limits() -> ranged_int@interface:limits(ranged_int@interface:overflowable()).
limits() ->
_assert_subject = bigi_ffi:power(bigi_ffi:from(2), bigi_ffi:from(127)),
{ok, B127} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"ranged_int/builtin/int128"/utf8>>,
function => <<"limits"/utf8>>,
line => 82})
end,
Min = bigi_ffi:multiply(B127, bigi_ffi:from(-1)),
Max = bigi_ffi:subtract(erlang:abs(Min), bigi_ffi:from(1)),
ranged_int@interface:overflowable_limits(Min, Max).
-spec from_bigint_unsafe(bigi:big_int()) -> int128().
from_bigint_unsafe(Value) ->
{int128, Value}.
-spec from_bigint(bigi:big_int()) -> {ok, int128()} |
{error, ranged_int@utils:overflow()}.
from_bigint(Value) ->
ranged_int@interface:from_bigint(
Value,
{interface, fun to_bigint/1, fun from_bigint_unsafe/1, fun limits/0}
).
-spec compare(int128(), int128()) -> gleam@order:order().
compare(A, B) ->
ranged_int@interface:compare(
A,
B,
{interface, fun to_bigint/1, fun from_bigint_unsafe/1, fun limits/0}
).
-spec absolute(int128()) -> {ok, int128()} |
{error, ranged_int@utils:overflow()}.
absolute(A) ->
ranged_int@interface:math_op_unary(
A,
{interface, fun to_bigint/1, fun from_bigint_unsafe/1, fun limits/0},
fun erlang:abs/1
).
-spec add(int128(), bigi:big_int()) -> {ok, int128()} |
{error, ranged_int@utils:overflow()}.
add(A, B) ->
ranged_int@interface:math_op(
A,
B,
{interface, fun to_bigint/1, fun from_bigint_unsafe/1, fun limits/0},
fun bigi_ffi:add/2
).
-spec subtract(int128(), bigi:big_int()) -> {ok, int128()} |
{error, ranged_int@utils:overflow()}.
subtract(A, B) ->
ranged_int@interface:math_op(
A,
B,
{interface, fun to_bigint/1, fun from_bigint_unsafe/1, fun limits/0},
fun bigi_ffi:subtract/2
).
-spec multiply(int128(), bigi:big_int()) -> {ok, int128()} |
{error, ranged_int@utils:overflow()}.
multiply(A, B) ->
ranged_int@interface:math_op(
A,
B,
{interface, fun to_bigint/1, fun from_bigint_unsafe/1, fun limits/0},
fun bigi_ffi:multiply/2
).
-spec divide(int128(), bigi:big_int()) -> {ok, int128()} |
{error, ranged_int@utils:overflow()}.
divide(A, B) ->
ranged_int@interface:math_op(
A,
B,
{interface, fun to_bigint/1, fun from_bigint_unsafe/1, fun limits/0},
fun bigi_ffi:divide/2
).
-spec divide_no_zero(int128(), bigi:big_int()) -> {ok,
{ok, int128()} | {error, ranged_int@utils:overflow()}} |
{error, nil}.
divide_no_zero(A, B) ->
ranged_int@interface:fallible_op(
A,
B,
{interface, fun to_bigint/1, fun from_bigint_unsafe/1, fun limits/0},
fun bigi_ffi:divide_no_zero/2
).
-spec modulo(int128(), bigi:big_int()) -> {ok, int128()} |
{error, ranged_int@utils:overflow()}.
modulo(A, B) ->
ranged_int@interface:math_op(
A,
B,
{interface, fun to_bigint/1, fun from_bigint_unsafe/1, fun limits/0},
fun bigi_ffi:modulo/2
).
-spec modulo_no_zero(int128(), bigi:big_int()) -> {ok,
{ok, int128()} | {error, ranged_int@utils:overflow()}} |
{error, nil}.
modulo_no_zero(A, B) ->
ranged_int@interface:fallible_op(
A,
B,
{interface, fun to_bigint/1, fun from_bigint_unsafe/1, fun limits/0},
fun bigi_ffi:modulo_no_zero/2
).
-spec remainder(int128(), bigi:big_int()) -> {ok, int128()} |
{error, ranged_int@utils:overflow()}.
remainder(A, B) ->
ranged_int@interface:math_op(
A,
B,
{interface, fun to_bigint/1, fun from_bigint_unsafe/1, fun limits/0},
fun bigi_ffi:remainder/2
).
-spec remainder_no_zero(int128(), bigi:big_int()) -> {ok,
{ok, int128()} | {error, ranged_int@utils:overflow()}} |
{error, nil}.
remainder_no_zero(A, B) ->
ranged_int@interface:fallible_op(
A,
B,
{interface, fun to_bigint/1, fun from_bigint_unsafe/1, fun limits/0},
fun bigi_ffi:remainder_no_zero/2
).
-spec power(int128(), ranged_int@builtin@uint:uint()) -> {ok, int128()} |
{error, ranged_int@utils:overflow()}.
power(A, B) ->
_assert_subject = ranged_int@interface:fallible_op(
A,
ranged_int@builtin@uint:to_bigint(B),
{interface, fun to_bigint/1, fun from_bigint_unsafe/1, fun limits/0},
fun bigi_ffi:power/2
),
{ok, Result} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"ranged_int/builtin/int128"/utf8>>,
function => <<"power"/utf8>>,
line => 68})
end,
Result.
-spec overflow({ok, int128()} | {error, ranged_int@utils:overflow()}) -> int128().
overflow(Op) ->
ranged_int@interface:overflow(
Op,
{interface, fun to_bigint/1, fun from_bigint_unsafe/1, fun limits/0}
).
-spec eject({ok, int128()} | {error, ranged_int@utils:overflow()}) -> bigi:big_int().
eject(Op) ->
ranged_int@interface:eject(
Op,
{interface, fun to_bigint/1, fun from_bigint_unsafe/1, fun limits/0}
).