Add unary ops and to_int
This commit is contained in:
parent
10c6a15aea
commit
2e9eb0851b
12 changed files with 124 additions and 3 deletions
|
@ -59,6 +59,10 @@ pub fn compare(a: RangedInt(overflow_mode), b: RangedInt(overflow_mode)) {
|
|||
interface.compare(a, b, a.interface())
|
||||
}
|
||||
|
||||
pub fn absolute(a: RangedInt(overflow_mode)) {
|
||||
interface.math_op_unary(a, a.interface(), bigi.absolute)
|
||||
}
|
||||
|
||||
pub fn add(a: RangedInt(overflow_mode), b: BigInt) {
|
||||
interface.math_op(a, b, a.interface(), bigi.add)
|
||||
}
|
||||
|
|
|
@ -23,6 +23,10 @@ pub fn compare(a: Int128, b: Int128) {
|
|||
interface.compare(a, b, iface)
|
||||
}
|
||||
|
||||
pub fn absolute(a: Int128) {
|
||||
interface.math_op_unary(a, iface, bigi.absolute)
|
||||
}
|
||||
|
||||
pub fn add(a: Int128, b: BigInt) {
|
||||
interface.math_op(a, b, iface, bigi.add)
|
||||
}
|
||||
|
|
|
@ -15,6 +15,18 @@ const iface: Interface(Int16, interface.Overflowable) = Interface(
|
|||
limits: limits,
|
||||
)
|
||||
|
||||
pub fn from_int(value: Int) {
|
||||
from_bigint(bigi.from_int(value))
|
||||
}
|
||||
|
||||
pub fn to_int(uint: Int16) {
|
||||
let assert Ok(int) =
|
||||
uint
|
||||
|> to_bigint()
|
||||
|> bigi.to_int()
|
||||
int
|
||||
}
|
||||
|
||||
pub fn from_bigint(value: BigInt) {
|
||||
interface.from_bigint(value, iface)
|
||||
}
|
||||
|
@ -27,6 +39,10 @@ pub fn compare(a: Int16, b: Int16) {
|
|||
interface.compare(a, b, iface)
|
||||
}
|
||||
|
||||
pub fn absolute(a: Int16) {
|
||||
interface.math_op_unary(a, iface, bigi.absolute)
|
||||
}
|
||||
|
||||
pub fn add(a: Int16, b: BigInt) {
|
||||
interface.math_op(a, b, iface, bigi.add)
|
||||
}
|
||||
|
|
|
@ -15,6 +15,18 @@ const iface: Interface(Int32, interface.Overflowable) = Interface(
|
|||
limits: limits,
|
||||
)
|
||||
|
||||
pub fn from_int(value: Int) {
|
||||
from_bigint(bigi.from_int(value))
|
||||
}
|
||||
|
||||
pub fn to_int(uint: Int32) {
|
||||
let assert Ok(int) =
|
||||
uint
|
||||
|> to_bigint()
|
||||
|> bigi.to_int()
|
||||
int
|
||||
}
|
||||
|
||||
pub fn from_bigint(value: BigInt) {
|
||||
interface.from_bigint(value, iface)
|
||||
}
|
||||
|
@ -27,6 +39,10 @@ pub fn compare(a: Int32, b: Int32) {
|
|||
interface.compare(a, b, iface)
|
||||
}
|
||||
|
||||
pub fn absolute(a: Int32) {
|
||||
interface.math_op_unary(a, iface, bigi.absolute)
|
||||
}
|
||||
|
||||
pub fn add(a: Int32, b: BigInt) {
|
||||
interface.math_op(a, b, iface, bigi.add)
|
||||
}
|
||||
|
|
|
@ -23,6 +23,10 @@ pub fn compare(a: Int64, b: Int64) {
|
|||
interface.compare(a, b, iface)
|
||||
}
|
||||
|
||||
pub fn absolute(a: Int64) {
|
||||
interface.math_op_unary(a, iface, bigi.absolute)
|
||||
}
|
||||
|
||||
pub fn add(a: Int64, b: BigInt) {
|
||||
interface.math_op(a, b, iface, bigi.add)
|
||||
}
|
||||
|
|
|
@ -15,6 +15,18 @@ const iface: Interface(Int8, interface.Overflowable) = Interface(
|
|||
limits: limits,
|
||||
)
|
||||
|
||||
pub fn from_int(value: Int) {
|
||||
from_bigint(bigi.from_int(value))
|
||||
}
|
||||
|
||||
pub fn to_int(uint: Int8) {
|
||||
let assert Ok(int) =
|
||||
uint
|
||||
|> to_bigint()
|
||||
|> bigi.to_int()
|
||||
int
|
||||
}
|
||||
|
||||
pub fn from_bigint(value: BigInt) {
|
||||
interface.from_bigint(value, iface)
|
||||
}
|
||||
|
@ -27,6 +39,10 @@ pub fn compare(a: Int8, b: Int8) {
|
|||
interface.compare(a, b, iface)
|
||||
}
|
||||
|
||||
pub fn absolute(a: Int8) {
|
||||
interface.math_op_unary(a, iface, bigi.absolute)
|
||||
}
|
||||
|
||||
pub fn add(a: Int8, b: BigInt) {
|
||||
interface.math_op(a, b, iface, bigi.add)
|
||||
}
|
||||
|
|
|
@ -15,6 +15,18 @@ const iface: Interface(Uint16, interface.Overflowable) = Interface(
|
|||
limits: limits,
|
||||
)
|
||||
|
||||
pub fn from_int(value: Int) {
|
||||
from_bigint(bigi.from_int(value))
|
||||
}
|
||||
|
||||
pub fn to_int(uint: Uint16) {
|
||||
let assert Ok(int) =
|
||||
uint
|
||||
|> to_bigint()
|
||||
|> bigi.to_int()
|
||||
int
|
||||
}
|
||||
|
||||
pub fn from_bigint(value: BigInt) {
|
||||
interface.from_bigint(value, iface)
|
||||
}
|
||||
|
|
|
@ -15,6 +15,18 @@ const iface: Interface(Uint32, interface.Overflowable) = Interface(
|
|||
limits: limits,
|
||||
)
|
||||
|
||||
pub fn from_int(value: Int) {
|
||||
from_bigint(bigi.from_int(value))
|
||||
}
|
||||
|
||||
pub fn to_int(uint: Uint32) {
|
||||
let assert Ok(int) =
|
||||
uint
|
||||
|> to_bigint()
|
||||
|> bigi.to_int()
|
||||
int
|
||||
}
|
||||
|
||||
pub fn from_bigint(value: BigInt) {
|
||||
interface.from_bigint(value, iface)
|
||||
}
|
||||
|
|
|
@ -15,6 +15,18 @@ const iface: Interface(Uint8, interface.Overflowable) = Interface(
|
|||
limits: limits,
|
||||
)
|
||||
|
||||
pub fn from_int(value: Int) {
|
||||
from_bigint(bigi.from_int(value))
|
||||
}
|
||||
|
||||
pub fn to_int(uint: Uint8) {
|
||||
let assert Ok(int) =
|
||||
uint
|
||||
|> to_bigint()
|
||||
|> bigi.to_int()
|
||||
int
|
||||
}
|
||||
|
||||
pub fn from_bigint(value: BigInt) {
|
||||
interface.from_bigint(value, iface)
|
||||
}
|
||||
|
|
|
@ -116,6 +116,22 @@ pub fn math_op(
|
|||
}
|
||||
}
|
||||
|
||||
/// Run a unary math operation on a ranged integer.
|
||||
pub fn math_op_unary(
|
||||
int: a,
|
||||
interface: Interface(a, overflow_mode),
|
||||
op: fn(BigInt) -> BigInt,
|
||||
) -> OpResult(a) {
|
||||
let limits = interface.limits()
|
||||
let int = interface.to_bigint(int)
|
||||
let result = op(int)
|
||||
case limit.check_limits(result, min: limits.min, max: limits.max) {
|
||||
NoOverflow -> Ok(interface.from_bigint_unsafe(result))
|
||||
Overflow(amount) -> Error(utils.DidOverflow(amount))
|
||||
Underflow(amount) -> Error(utils.DidUnderflow(amount))
|
||||
}
|
||||
}
|
||||
|
||||
/// Run a math operation that may fail on a ranged integer and an unranged big
|
||||
/// integer.
|
||||
///
|
||||
|
|
9
test/builtin/int128_test.gleam
Normal file
9
test/builtin/int128_test.gleam
Normal file
|
@ -0,0 +1,9 @@
|
|||
import bigi
|
||||
import gleeunit/should
|
||||
import ranged_int/builtin/int128
|
||||
|
||||
pub fn add_test() {
|
||||
let assert Ok(a) = int128.from_bigint(bigi.from_int(-3_190_309_415))
|
||||
let b = int128.absolute(a)
|
||||
should.equal(b, int128.from_bigint(bigi.from_int(3_190_309_415)))
|
||||
}
|
|
@ -10,17 +10,17 @@ pub fn add_test() {
|
|||
}
|
||||
|
||||
pub fn divide_test() {
|
||||
let assert Ok(a) = uint8.from_bigint(bigi.from_int(120))
|
||||
let assert Ok(a) = uint8.from_int(120)
|
||||
let b = bigi.from_int(12)
|
||||
let assert Ok(c) = uint8.divide_no_zero(a, b)
|
||||
should.equal(uint8.eject(c), bigi.from_int(10))
|
||||
}
|
||||
|
||||
pub fn overflow_test() {
|
||||
let assert Ok(a) = uint8.from_bigint(bigi.from_int(120))
|
||||
let assert Ok(a) = uint8.from_int(120)
|
||||
let b = bigi.from_int(160)
|
||||
let c = uint8.overflow(uint8.add(a, b))
|
||||
should.equal(uint8.to_bigint(c), bigi.from_int(24))
|
||||
should.equal(uint8.to_int(c), 24)
|
||||
}
|
||||
|
||||
pub fn underflow_test() {
|
||||
|
|
Loading…
Reference in a new issue