Iterate iterate iterate
This commit is contained in:
parent
3d3fe05372
commit
c0e4dbc4ed
14 changed files with 406 additions and 164 deletions
|
@ -1,5 +1,5 @@
|
|||
import bigi.{type BigInt}
|
||||
import ranged_int/interface.{type Interface, type MathOp, Interface}
|
||||
import ranged_int/interface.{type Interface, Interface}
|
||||
|
||||
pub opaque type Int128 {
|
||||
Int128(data: BigInt)
|
||||
|
@ -19,24 +19,44 @@ pub fn to_bigint(uint: Int128) {
|
|||
uint.data
|
||||
}
|
||||
|
||||
pub fn from_bigint_overflow(value: BigInt) {
|
||||
interface.from_bigint_overflow(value, iface)
|
||||
}
|
||||
|
||||
pub fn compare(a: Int128, b: Int128) {
|
||||
interface.compare(a, b, iface)
|
||||
}
|
||||
|
||||
pub fn math_op(a: Int128, b: Int128, op: MathOp) {
|
||||
interface.math_op(a, b, iface, op)
|
||||
pub fn add(a: Int128, b: Int128) {
|
||||
interface.math_op(a, b, iface, bigi.add)
|
||||
}
|
||||
|
||||
pub fn math_op_overflow(a: Int128, b: Int128, op: MathOp) {
|
||||
interface.math_op_overflow(a, b, iface, op)
|
||||
pub fn subtract(a: Int128, b: Int128) {
|
||||
interface.math_op(a, b, iface, bigi.subtract)
|
||||
}
|
||||
|
||||
pub fn math_op_eject(a: Int128, b: Int128, op: MathOp) {
|
||||
interface.math_op_eject(a, b, iface, op)
|
||||
pub fn multiply(a: Int128, b: Int128) {
|
||||
interface.math_op(a, b, iface, bigi.multiply)
|
||||
}
|
||||
|
||||
pub fn divide(a: Int128, b: Int128) {
|
||||
interface.math_op(a, b, iface, bigi.divide)
|
||||
}
|
||||
|
||||
pub fn modulo(a: Int128, b: Int128) {
|
||||
interface.math_op(a, b, iface, bigi.modulo)
|
||||
}
|
||||
|
||||
pub fn remainder(a: Int128, b: Int128) {
|
||||
interface.math_op(a, b, iface, bigi.remainder)
|
||||
}
|
||||
|
||||
pub fn power(a: Int128, b: Int128) {
|
||||
interface.math_op(a, b, iface, bigi.power)
|
||||
}
|
||||
|
||||
pub fn overflow(op: interface.OpResult(Int128)) {
|
||||
interface.overflow(op, iface)
|
||||
}
|
||||
|
||||
pub fn eject(op: interface.OpResult(Int128)) {
|
||||
interface.eject(op, iface)
|
||||
}
|
||||
|
||||
fn limits() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import bigi.{type BigInt}
|
||||
import ranged_int/interface.{type Interface, type MathOp, Interface}
|
||||
import ranged_int/interface.{type Interface, Interface}
|
||||
|
||||
const max_limit = 32_767
|
||||
|
||||
|
@ -23,24 +23,44 @@ pub fn to_bigint(uint: Int16) {
|
|||
uint.data
|
||||
}
|
||||
|
||||
pub fn from_bigint_overflow(value: BigInt) {
|
||||
interface.from_bigint_overflow(value, iface)
|
||||
}
|
||||
|
||||
pub fn compare(a: Int16, b: Int16) {
|
||||
interface.compare(a, b, iface)
|
||||
}
|
||||
|
||||
pub fn math_op(a: Int16, b: Int16, op: MathOp) {
|
||||
interface.math_op(a, b, iface, op)
|
||||
pub fn add(a: Int16, b: Int16) {
|
||||
interface.math_op(a, b, iface, bigi.add)
|
||||
}
|
||||
|
||||
pub fn math_op_overflow(a: Int16, b: Int16, op: MathOp) {
|
||||
interface.math_op_overflow(a, b, iface, op)
|
||||
pub fn subtract(a: Int16, b: Int16) {
|
||||
interface.math_op(a, b, iface, bigi.subtract)
|
||||
}
|
||||
|
||||
pub fn math_op_eject(a: Int16, b: Int16, op: MathOp) {
|
||||
interface.math_op_eject(a, b, iface, op)
|
||||
pub fn multiply(a: Int16, b: Int16) {
|
||||
interface.math_op(a, b, iface, bigi.multiply)
|
||||
}
|
||||
|
||||
pub fn divide(a: Int16, b: Int16) {
|
||||
interface.math_op(a, b, iface, bigi.divide)
|
||||
}
|
||||
|
||||
pub fn modulo(a: Int16, b: Int16) {
|
||||
interface.math_op(a, b, iface, bigi.modulo)
|
||||
}
|
||||
|
||||
pub fn remainder(a: Int16, b: Int16) {
|
||||
interface.math_op(a, b, iface, bigi.remainder)
|
||||
}
|
||||
|
||||
pub fn power(a: Int16, b: Int16) {
|
||||
interface.math_op(a, b, iface, bigi.power)
|
||||
}
|
||||
|
||||
pub fn overflow(op: interface.OpResult(Int16)) {
|
||||
interface.overflow(op, iface)
|
||||
}
|
||||
|
||||
pub fn eject(op: interface.OpResult(Int16)) {
|
||||
interface.eject(op, iface)
|
||||
}
|
||||
|
||||
fn limits() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import bigi.{type BigInt}
|
||||
import ranged_int/interface.{type Interface, type MathOp, Interface}
|
||||
import ranged_int/interface.{type Interface, Interface}
|
||||
|
||||
const max_limit = 2_147_483_647
|
||||
|
||||
|
@ -23,24 +23,44 @@ pub fn to_bigint(uint: Int32) {
|
|||
uint.data
|
||||
}
|
||||
|
||||
pub fn from_bigint_overflow(value: BigInt) {
|
||||
interface.from_bigint_overflow(value, iface)
|
||||
}
|
||||
|
||||
pub fn compare(a: Int32, b: Int32) {
|
||||
interface.compare(a, b, iface)
|
||||
}
|
||||
|
||||
pub fn math_op(a: Int32, b: Int32, op: MathOp) {
|
||||
interface.math_op(a, b, iface, op)
|
||||
pub fn add(a: Int32, b: Int32) {
|
||||
interface.math_op(a, b, iface, bigi.add)
|
||||
}
|
||||
|
||||
pub fn math_op_overflow(a: Int32, b: Int32, op: MathOp) {
|
||||
interface.math_op_overflow(a, b, iface, op)
|
||||
pub fn subtract(a: Int32, b: Int32) {
|
||||
interface.math_op(a, b, iface, bigi.subtract)
|
||||
}
|
||||
|
||||
pub fn math_op_eject(a: Int32, b: Int32, op: MathOp) {
|
||||
interface.math_op_eject(a, b, iface, op)
|
||||
pub fn multiply(a: Int32, b: Int32) {
|
||||
interface.math_op(a, b, iface, bigi.multiply)
|
||||
}
|
||||
|
||||
pub fn divide(a: Int32, b: Int32) {
|
||||
interface.math_op(a, b, iface, bigi.divide)
|
||||
}
|
||||
|
||||
pub fn modulo(a: Int32, b: Int32) {
|
||||
interface.math_op(a, b, iface, bigi.modulo)
|
||||
}
|
||||
|
||||
pub fn remainder(a: Int32, b: Int32) {
|
||||
interface.math_op(a, b, iface, bigi.remainder)
|
||||
}
|
||||
|
||||
pub fn power(a: Int32, b: Int32) {
|
||||
interface.math_op(a, b, iface, bigi.power)
|
||||
}
|
||||
|
||||
pub fn overflow(op: interface.OpResult(Int32)) {
|
||||
interface.overflow(op, iface)
|
||||
}
|
||||
|
||||
pub fn eject(op: interface.OpResult(Int32)) {
|
||||
interface.eject(op, iface)
|
||||
}
|
||||
|
||||
fn limits() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import bigi.{type BigInt}
|
||||
import ranged_int/interface.{type Interface, type MathOp, Interface}
|
||||
import ranged_int/interface.{type Interface, Interface}
|
||||
|
||||
pub opaque type Int64 {
|
||||
Int64(data: BigInt)
|
||||
|
@ -19,24 +19,44 @@ pub fn to_bigint(uint: Int64) {
|
|||
uint.data
|
||||
}
|
||||
|
||||
pub fn from_bigint_overflow(value: BigInt) {
|
||||
interface.from_bigint_overflow(value, iface)
|
||||
}
|
||||
|
||||
pub fn compare(a: Int64, b: Int64) {
|
||||
interface.compare(a, b, iface)
|
||||
}
|
||||
|
||||
pub fn math_op(a: Int64, b: Int64, op: MathOp) {
|
||||
interface.math_op(a, b, iface, op)
|
||||
pub fn add(a: Int64, b: Int64) {
|
||||
interface.math_op(a, b, iface, bigi.add)
|
||||
}
|
||||
|
||||
pub fn math_op_overflow(a: Int64, b: Int64, op: MathOp) {
|
||||
interface.math_op_overflow(a, b, iface, op)
|
||||
pub fn subtract(a: Int64, b: Int64) {
|
||||
interface.math_op(a, b, iface, bigi.subtract)
|
||||
}
|
||||
|
||||
pub fn math_op_eject(a: Int64, b: Int64, op: MathOp) {
|
||||
interface.math_op_eject(a, b, iface, op)
|
||||
pub fn multiply(a: Int64, b: Int64) {
|
||||
interface.math_op(a, b, iface, bigi.multiply)
|
||||
}
|
||||
|
||||
pub fn divide(a: Int64, b: Int64) {
|
||||
interface.math_op(a, b, iface, bigi.divide)
|
||||
}
|
||||
|
||||
pub fn modulo(a: Int64, b: Int64) {
|
||||
interface.math_op(a, b, iface, bigi.modulo)
|
||||
}
|
||||
|
||||
pub fn remainder(a: Int64, b: Int64) {
|
||||
interface.math_op(a, b, iface, bigi.remainder)
|
||||
}
|
||||
|
||||
pub fn power(a: Int64, b: Int64) {
|
||||
interface.math_op(a, b, iface, bigi.power)
|
||||
}
|
||||
|
||||
pub fn overflow(op: interface.OpResult(Int64)) {
|
||||
interface.overflow(op, iface)
|
||||
}
|
||||
|
||||
pub fn eject(op: interface.OpResult(Int64)) {
|
||||
interface.eject(op, iface)
|
||||
}
|
||||
|
||||
fn limits() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import bigi.{type BigInt}
|
||||
import ranged_int/interface.{type Interface, type MathOp, Interface}
|
||||
import ranged_int/interface.{type Interface, Interface}
|
||||
|
||||
const max_limit = 127
|
||||
|
||||
|
@ -23,24 +23,44 @@ pub fn to_bigint(uint: Int8) {
|
|||
uint.data
|
||||
}
|
||||
|
||||
pub fn from_bigint_overflow(value: BigInt) {
|
||||
interface.from_bigint_overflow(value, iface)
|
||||
}
|
||||
|
||||
pub fn compare(a: Int8, b: Int8) {
|
||||
interface.compare(a, b, iface)
|
||||
}
|
||||
|
||||
pub fn math_op(a: Int8, b: Int8, op: MathOp) {
|
||||
interface.math_op(a, b, iface, op)
|
||||
pub fn add(a: Int8, b: Int8) {
|
||||
interface.math_op(a, b, iface, bigi.add)
|
||||
}
|
||||
|
||||
pub fn math_op_overflow(a: Int8, b: Int8, op: MathOp) {
|
||||
interface.math_op_overflow(a, b, iface, op)
|
||||
pub fn subtract(a: Int8, b: Int8) {
|
||||
interface.math_op(a, b, iface, bigi.subtract)
|
||||
}
|
||||
|
||||
pub fn math_op_eject(a: Int8, b: Int8, op: MathOp) {
|
||||
interface.math_op_eject(a, b, iface, op)
|
||||
pub fn multiply(a: Int8, b: Int8) {
|
||||
interface.math_op(a, b, iface, bigi.multiply)
|
||||
}
|
||||
|
||||
pub fn divide(a: Int8, b: Int8) {
|
||||
interface.math_op(a, b, iface, bigi.divide)
|
||||
}
|
||||
|
||||
pub fn modulo(a: Int8, b: Int8) {
|
||||
interface.math_op(a, b, iface, bigi.modulo)
|
||||
}
|
||||
|
||||
pub fn remainder(a: Int8, b: Int8) {
|
||||
interface.math_op(a, b, iface, bigi.remainder)
|
||||
}
|
||||
|
||||
pub fn power(a: Int8, b: Int8) {
|
||||
interface.math_op(a, b, iface, bigi.power)
|
||||
}
|
||||
|
||||
pub fn overflow(op: interface.OpResult(Int8)) {
|
||||
interface.overflow(op, iface)
|
||||
}
|
||||
|
||||
pub fn eject(op: interface.OpResult(Int8)) {
|
||||
interface.eject(op, iface)
|
||||
}
|
||||
|
||||
fn limits() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import bigi.{type BigInt}
|
||||
import ranged_int/interface.{type Interface, type MathOp, Interface}
|
||||
import ranged_int/interface.{type Interface, Interface}
|
||||
|
||||
const min_limit = 0
|
||||
|
||||
|
@ -25,12 +25,36 @@ pub fn compare(a: Uint, b: Uint) {
|
|||
interface.compare(a, b, iface)
|
||||
}
|
||||
|
||||
pub fn math_op(a: Uint, b: Uint, op: MathOp) {
|
||||
interface.math_op(a, b, iface, op)
|
||||
pub fn add(a: Uint, b: Uint) {
|
||||
interface.math_op(a, b, iface, bigi.add)
|
||||
}
|
||||
|
||||
pub fn math_op_eject(a: Uint, b: Uint, op: MathOp) {
|
||||
interface.math_op_eject(a, b, iface, op)
|
||||
pub fn subtract(a: Uint, b: Uint) {
|
||||
interface.math_op(a, b, iface, bigi.subtract)
|
||||
}
|
||||
|
||||
pub fn multiply(a: Uint, b: Uint) {
|
||||
interface.math_op(a, b, iface, bigi.multiply)
|
||||
}
|
||||
|
||||
pub fn divide(a: Uint, b: Uint) {
|
||||
interface.math_op(a, b, iface, bigi.divide)
|
||||
}
|
||||
|
||||
pub fn modulo(a: Uint, b: Uint) {
|
||||
interface.math_op(a, b, iface, bigi.modulo)
|
||||
}
|
||||
|
||||
pub fn remainder(a: Uint, b: Uint) {
|
||||
interface.math_op(a, b, iface, bigi.remainder)
|
||||
}
|
||||
|
||||
pub fn power(a: Uint, b: Uint) {
|
||||
interface.math_op(a, b, iface, bigi.power)
|
||||
}
|
||||
|
||||
pub fn eject(op: interface.OpResult(Uint)) {
|
||||
interface.eject(op, iface)
|
||||
}
|
||||
|
||||
fn limits() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import bigi.{type BigInt}
|
||||
import ranged_int/interface.{type Interface, type MathOp, Interface}
|
||||
import ranged_int/interface.{type Interface, Interface}
|
||||
|
||||
pub opaque type Uint128 {
|
||||
Uint128(data: BigInt)
|
||||
|
@ -19,24 +19,44 @@ pub fn to_bigint(uint: Uint128) {
|
|||
uint.data
|
||||
}
|
||||
|
||||
pub fn from_bigint_overflow(value: BigInt) {
|
||||
interface.from_bigint_overflow(value, iface)
|
||||
}
|
||||
|
||||
pub fn compare(a: Uint128, b: Uint128) {
|
||||
interface.compare(a, b, iface)
|
||||
}
|
||||
|
||||
pub fn math_op(a: Uint128, b: Uint128, op: MathOp) {
|
||||
interface.math_op(a, b, iface, op)
|
||||
pub fn add(a: Uint128, b: Uint128) {
|
||||
interface.math_op(a, b, iface, bigi.add)
|
||||
}
|
||||
|
||||
pub fn math_op_overflow(a: Uint128, b: Uint128, op: MathOp) {
|
||||
interface.math_op_overflow(a, b, iface, op)
|
||||
pub fn subtract(a: Uint128, b: Uint128) {
|
||||
interface.math_op(a, b, iface, bigi.subtract)
|
||||
}
|
||||
|
||||
pub fn math_op_eject(a: Uint128, b: Uint128, op: MathOp) {
|
||||
interface.math_op_eject(a, b, iface, op)
|
||||
pub fn multiply(a: Uint128, b: Uint128) {
|
||||
interface.math_op(a, b, iface, bigi.multiply)
|
||||
}
|
||||
|
||||
pub fn divide(a: Uint128, b: Uint128) {
|
||||
interface.math_op(a, b, iface, bigi.divide)
|
||||
}
|
||||
|
||||
pub fn modulo(a: Uint128, b: Uint128) {
|
||||
interface.math_op(a, b, iface, bigi.modulo)
|
||||
}
|
||||
|
||||
pub fn remainder(a: Uint128, b: Uint128) {
|
||||
interface.math_op(a, b, iface, bigi.remainder)
|
||||
}
|
||||
|
||||
pub fn power(a: Uint128, b: Uint128) {
|
||||
interface.math_op(a, b, iface, bigi.power)
|
||||
}
|
||||
|
||||
pub fn overflow(op: interface.OpResult(Uint128)) {
|
||||
interface.overflow(op, iface)
|
||||
}
|
||||
|
||||
pub fn eject(op: interface.OpResult(Uint128)) {
|
||||
interface.eject(op, iface)
|
||||
}
|
||||
|
||||
fn limits() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import bigi.{type BigInt}
|
||||
import ranged_int/interface.{type Interface, type MathOp, Interface}
|
||||
import ranged_int/interface.{type Interface, Interface}
|
||||
|
||||
const max_limit = 65_535
|
||||
|
||||
|
@ -23,30 +23,50 @@ pub fn to_bigint(uint: Uint16) {
|
|||
uint.data
|
||||
}
|
||||
|
||||
pub fn from_bigint_overflow(value: BigInt) {
|
||||
interface.from_bigint_overflow(value, iface)
|
||||
}
|
||||
|
||||
pub fn compare(a: Uint16, b: Uint16) {
|
||||
interface.compare(a, b, iface)
|
||||
}
|
||||
|
||||
pub fn math_op(a: Uint16, b: Uint16, op: MathOp) {
|
||||
interface.math_op(a, b, iface, op)
|
||||
pub fn add(a: Uint16, b: Uint16) {
|
||||
interface.math_op(a, b, iface, bigi.add)
|
||||
}
|
||||
|
||||
pub fn math_op_overflow(a: Uint16, b: Uint16, op: MathOp) {
|
||||
interface.math_op_overflow(a, b, iface, op)
|
||||
pub fn subtract(a: Uint16, b: Uint16) {
|
||||
interface.math_op(a, b, iface, bigi.subtract)
|
||||
}
|
||||
|
||||
pub fn math_op_eject(a: Uint16, b: Uint16, op: MathOp) {
|
||||
interface.math_op_eject(a, b, iface, op)
|
||||
pub fn multiply(a: Uint16, b: Uint16) {
|
||||
interface.math_op(a, b, iface, bigi.multiply)
|
||||
}
|
||||
|
||||
pub fn divide(a: Uint16, b: Uint16) {
|
||||
interface.math_op(a, b, iface, bigi.divide)
|
||||
}
|
||||
|
||||
pub fn modulo(a: Uint16, b: Uint16) {
|
||||
interface.math_op(a, b, iface, bigi.modulo)
|
||||
}
|
||||
|
||||
pub fn remainder(a: Uint16, b: Uint16) {
|
||||
interface.math_op(a, b, iface, bigi.remainder)
|
||||
}
|
||||
|
||||
pub fn power(a: Uint16, b: Uint16) {
|
||||
interface.math_op(a, b, iface, bigi.power)
|
||||
}
|
||||
|
||||
pub fn overflow(op: interface.OpResult(Uint16)) {
|
||||
interface.overflow(op, iface)
|
||||
}
|
||||
|
||||
pub fn eject(op: interface.OpResult(Uint16)) {
|
||||
interface.eject(op, iface)
|
||||
}
|
||||
|
||||
fn limits() {
|
||||
interface.overflowable_limits(
|
||||
bigi.from_int(max_limit),
|
||||
bigi.from_int(min_limit),
|
||||
bigi.from_int(max_limit),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import bigi.{type BigInt}
|
||||
import ranged_int/interface.{type Interface, type MathOp, Interface}
|
||||
import ranged_int/interface.{type Interface, Interface}
|
||||
|
||||
pub const max_limit = 4_294_967_295
|
||||
|
||||
|
@ -23,30 +23,50 @@ pub fn to_bigint(uint: Uint32) {
|
|||
uint.data
|
||||
}
|
||||
|
||||
pub fn from_bigint_overflow(value: BigInt) {
|
||||
interface.from_bigint_overflow(value, iface)
|
||||
}
|
||||
|
||||
pub fn compare(a: Uint32, b: Uint32) {
|
||||
interface.compare(a, b, iface)
|
||||
}
|
||||
|
||||
pub fn math_op(a: Uint32, b: Uint32, op: MathOp) {
|
||||
interface.math_op(a, b, iface, op)
|
||||
pub fn add(a: Uint32, b: Uint32) {
|
||||
interface.math_op(a, b, iface, bigi.add)
|
||||
}
|
||||
|
||||
pub fn math_op_overflow(a: Uint32, b: Uint32, op: MathOp) {
|
||||
interface.math_op_overflow(a, b, iface, op)
|
||||
pub fn subtract(a: Uint32, b: Uint32) {
|
||||
interface.math_op(a, b, iface, bigi.subtract)
|
||||
}
|
||||
|
||||
pub fn math_op_eject(a: Uint32, b: Uint32, op: MathOp) {
|
||||
interface.math_op_eject(a, b, iface, op)
|
||||
pub fn multiply(a: Uint32, b: Uint32) {
|
||||
interface.math_op(a, b, iface, bigi.multiply)
|
||||
}
|
||||
|
||||
pub fn divide(a: Uint32, b: Uint32) {
|
||||
interface.math_op(a, b, iface, bigi.divide)
|
||||
}
|
||||
|
||||
pub fn modulo(a: Uint32, b: Uint32) {
|
||||
interface.math_op(a, b, iface, bigi.modulo)
|
||||
}
|
||||
|
||||
pub fn remainder(a: Uint32, b: Uint32) {
|
||||
interface.math_op(a, b, iface, bigi.remainder)
|
||||
}
|
||||
|
||||
pub fn power(a: Uint32, b: Uint32) {
|
||||
interface.math_op(a, b, iface, bigi.power)
|
||||
}
|
||||
|
||||
pub fn overflow(op: interface.OpResult(Uint32)) {
|
||||
interface.overflow(op, iface)
|
||||
}
|
||||
|
||||
pub fn eject(op: interface.OpResult(Uint32)) {
|
||||
interface.eject(op, iface)
|
||||
}
|
||||
|
||||
fn limits() {
|
||||
interface.overflowable_limits(
|
||||
bigi.from_int(max_limit),
|
||||
bigi.from_int(min_limit),
|
||||
bigi.from_int(max_limit),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import bigi.{type BigInt}
|
||||
import ranged_int/interface.{type Interface, type MathOp, Interface}
|
||||
import ranged_int/interface.{type Interface, Interface}
|
||||
|
||||
pub opaque type Uint64 {
|
||||
Uint64(data: BigInt)
|
||||
|
@ -19,24 +19,44 @@ pub fn to_bigint(uint: Uint64) {
|
|||
uint.data
|
||||
}
|
||||
|
||||
pub fn from_bigint_overflow(value: BigInt) {
|
||||
interface.from_bigint_overflow(value, iface)
|
||||
}
|
||||
|
||||
pub fn compare(a: Uint64, b: Uint64) {
|
||||
interface.compare(a, b, iface)
|
||||
}
|
||||
|
||||
pub fn math_op(a: Uint64, b: Uint64, op: MathOp) {
|
||||
interface.math_op(a, b, iface, op)
|
||||
pub fn add(a: Uint64, b: Uint64) {
|
||||
interface.math_op(a, b, iface, bigi.add)
|
||||
}
|
||||
|
||||
pub fn math_op_overflow(a: Uint64, b: Uint64, op: MathOp) {
|
||||
interface.math_op_overflow(a, b, iface, op)
|
||||
pub fn subtract(a: Uint64, b: Uint64) {
|
||||
interface.math_op(a, b, iface, bigi.subtract)
|
||||
}
|
||||
|
||||
pub fn math_op_eject(a: Uint64, b: Uint64, op: MathOp) {
|
||||
interface.math_op_eject(a, b, iface, op)
|
||||
pub fn multiply(a: Uint64, b: Uint64) {
|
||||
interface.math_op(a, b, iface, bigi.multiply)
|
||||
}
|
||||
|
||||
pub fn divide(a: Uint64, b: Uint64) {
|
||||
interface.math_op(a, b, iface, bigi.divide)
|
||||
}
|
||||
|
||||
pub fn modulo(a: Uint64, b: Uint64) {
|
||||
interface.math_op(a, b, iface, bigi.modulo)
|
||||
}
|
||||
|
||||
pub fn remainder(a: Uint64, b: Uint64) {
|
||||
interface.math_op(a, b, iface, bigi.remainder)
|
||||
}
|
||||
|
||||
pub fn power(a: Uint64, b: Uint64) {
|
||||
interface.math_op(a, b, iface, bigi.power)
|
||||
}
|
||||
|
||||
pub fn overflow(op: interface.OpResult(Uint64)) {
|
||||
interface.overflow(op, iface)
|
||||
}
|
||||
|
||||
pub fn eject(op: interface.OpResult(Uint64)) {
|
||||
interface.eject(op, iface)
|
||||
}
|
||||
|
||||
fn limits() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import bigi.{type BigInt}
|
||||
import ranged_int/interface.{type Interface, type MathOp, Interface}
|
||||
import ranged_int/interface.{type Interface, Interface}
|
||||
|
||||
const max_limit = 255
|
||||
|
||||
|
@ -23,30 +23,54 @@ pub fn to_bigint(uint: Uint8) {
|
|||
uint.data
|
||||
}
|
||||
|
||||
pub fn from_bigint_overflow(value: BigInt) {
|
||||
interface.from_bigint_overflow(value, iface)
|
||||
}
|
||||
|
||||
pub fn compare(a: Uint8, b: Uint8) {
|
||||
interface.compare(a, b, iface)
|
||||
}
|
||||
|
||||
pub fn math_op(a: Uint8, b: Uint8, op: MathOp) {
|
||||
interface.math_op(a, b, iface, op)
|
||||
pub fn add(a: Uint8, b: Uint8) {
|
||||
interface.math_op(a, b, iface, bigi.add)
|
||||
}
|
||||
|
||||
pub fn math_op_overflow(a: Uint8, b: Uint8, op: MathOp) {
|
||||
interface.math_op_overflow(a, b, iface, op)
|
||||
pub fn subtract(a: Uint8, b: Uint8) {
|
||||
interface.math_op(a, b, iface, bigi.subtract)
|
||||
}
|
||||
|
||||
pub fn math_op_eject(a: Uint8, b: Uint8, op: MathOp) {
|
||||
interface.math_op_eject(a, b, iface, op)
|
||||
pub fn multiply(a: Uint8, b: Uint8) {
|
||||
interface.math_op(a, b, iface, bigi.multiply)
|
||||
}
|
||||
|
||||
pub fn divide(a: Uint8, b: Uint8) {
|
||||
interface.math_op(a, b, iface, bigi.divide)
|
||||
}
|
||||
|
||||
pub fn divide_no_zero(a: Uint8, b: Uint8) {
|
||||
interface.fallible_op(a, b, iface, bigi.divide_no_zero)
|
||||
}
|
||||
|
||||
pub fn modulo(a: Uint8, b: Uint8) {
|
||||
interface.math_op(a, b, iface, bigi.modulo)
|
||||
}
|
||||
|
||||
pub fn remainder(a: Uint8, b: Uint8) {
|
||||
interface.math_op(a, b, iface, bigi.remainder)
|
||||
}
|
||||
|
||||
pub fn power(a: Uint8, b: Uint8) {
|
||||
interface.math_op(a, b, iface, bigi.power)
|
||||
}
|
||||
|
||||
pub fn overflow(op: interface.OpResult(Uint8)) {
|
||||
interface.overflow(op, iface)
|
||||
}
|
||||
|
||||
pub fn eject(op: interface.OpResult(Uint8)) {
|
||||
interface.eject(op, iface)
|
||||
}
|
||||
|
||||
fn limits() {
|
||||
interface.overflowable_limits(
|
||||
bigi.from_int(max_limit),
|
||||
bigi.from_int(min_limit),
|
||||
bigi.from_int(max_limit),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import gleam/order
|
||||
import gleam/result
|
||||
import bigi.{type BigInt}
|
||||
import ranged_int/limit.{type Limit, NoOverflow, Overflow, Underflow}
|
||||
import ranged_int/utils
|
||||
|
@ -22,8 +23,8 @@ type OverflowableLimits {
|
|||
OverflowableLimits(min: BigInt, max: BigInt)
|
||||
}
|
||||
|
||||
pub type MathOp =
|
||||
fn(BigInt, BigInt) -> BigInt
|
||||
pub type OpResult(a) =
|
||||
Result(a, utils.Overflow)
|
||||
|
||||
pub type Interface(a, overflow_mode) {
|
||||
Interface(
|
||||
|
@ -48,7 +49,7 @@ pub fn min_limit(min: BigInt) -> Limits(NonOverflowable) {
|
|||
pub fn from_bigint(
|
||||
value: BigInt,
|
||||
interface: Interface(a, overflow_mode),
|
||||
) -> Result(a, utils.Overflow) {
|
||||
) -> OpResult(a) {
|
||||
let limits = interface.limits()
|
||||
case limit.check_limits(value, min: limits.min, max: limits.max) {
|
||||
NoOverflow -> Ok(interface.from_bigint_unsafe(value))
|
||||
|
@ -57,13 +58,6 @@ pub fn from_bigint(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn from_bigint_overflow(
|
||||
value: BigInt,
|
||||
interface: Interface(a, Overflowable),
|
||||
) -> a {
|
||||
handle_overflow(value, interface)
|
||||
}
|
||||
|
||||
pub fn compare(
|
||||
int1: a,
|
||||
int2: a,
|
||||
|
@ -76,8 +70,8 @@ pub fn math_op(
|
|||
int1: a,
|
||||
int2: a,
|
||||
interface: Interface(a, overflow_mode),
|
||||
op: MathOp,
|
||||
) -> Result(a, utils.Overflow) {
|
||||
op: fn(BigInt, BigInt) -> BigInt,
|
||||
) -> OpResult(a) {
|
||||
let limits = interface.limits()
|
||||
let bigint1 = interface.to_bigint(int1)
|
||||
let bigint2 = interface.to_bigint(int2)
|
||||
|
@ -89,48 +83,51 @@ pub fn math_op(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn math_op_overflow(
|
||||
int1: a,
|
||||
int2: a,
|
||||
interface: Interface(a, Overflowable),
|
||||
op: MathOp,
|
||||
) -> a {
|
||||
let bigint1 = interface.to_bigint(int1)
|
||||
let bigint2 = interface.to_bigint(int2)
|
||||
let result = op(bigint1, bigint2)
|
||||
handle_overflow(result, interface)
|
||||
}
|
||||
|
||||
pub fn math_op_eject(
|
||||
pub fn fallible_op(
|
||||
int1: a,
|
||||
int2: a,
|
||||
interface: Interface(a, overflow_mode),
|
||||
op: MathOp,
|
||||
) -> BigInt {
|
||||
op: fn(BigInt, BigInt) -> Result(BigInt, op_err),
|
||||
) -> Result(OpResult(a), op_err) {
|
||||
let limits = interface.limits()
|
||||
let bigint1 = interface.to_bigint(int1)
|
||||
let bigint2 = interface.to_bigint(int2)
|
||||
op(bigint1, bigint2)
|
||||
use result <- result.try(op(bigint1, bigint2))
|
||||
Ok(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))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn handle_overflow(value: BigInt, interface: Interface(a, Overflowable)) {
|
||||
let limits = interface.limits()
|
||||
let result = case
|
||||
limit.check_limits(value, min: limits.min, max: limits.max)
|
||||
{
|
||||
NoOverflow -> value
|
||||
Overflow(amount) -> {
|
||||
let OverflowableLimits(min, max) = destructure_limits(limits)
|
||||
utils.overflow(utils.DidOverflow(amount), min: min, max: max)
|
||||
}
|
||||
Underflow(amount) -> {
|
||||
let OverflowableLimits(min, max) = destructure_limits(limits)
|
||||
utils.overflow(utils.DidUnderflow(amount), min: min, max: max)
|
||||
pub fn overflow(value: OpResult(a), interface: Interface(a, Overflowable)) {
|
||||
case value {
|
||||
Ok(new_value) -> new_value
|
||||
Error(overflow) -> {
|
||||
let OverflowableLimits(min, max) = destructure_limits(interface.limits())
|
||||
utils.overflow(overflow, min: min, max: max)
|
||||
|> interface.from_bigint_unsafe()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn eject(value: OpResult(a), interface: Interface(a, overflow_mode)) {
|
||||
case value {
|
||||
Ok(new_value) -> interface.to_bigint(new_value)
|
||||
Error(overflow) -> {
|
||||
case overflow, interface.limits() {
|
||||
utils.DidOverflow(amount), Limits(max: limit.Bounded(max), ..) ->
|
||||
bigi.add(max, amount)
|
||||
utils.DidUnderflow(amount), Limits(min: limit.Bounded(min), ..) ->
|
||||
bigi.subtract(min, amount)
|
||||
_, _ -> panic as "Overflowed but there was no corresponding limit (o_O)"
|
||||
}
|
||||
}
|
||||
}
|
||||
interface.from_bigint_unsafe(result)
|
||||
}
|
||||
|
||||
fn destructure_limits(limits: Limits(Overflowable)) {
|
||||
// We can trust that overflowable limits are always bounded on both sides
|
||||
let assert limit.Bounded(min) = limits.min
|
||||
let assert limit.Bounded(max) = limits.max
|
||||
OverflowableLimits(min: min, max: max)
|
||||
|
|
10
test/builtin/uint16_test.gleam
Normal file
10
test/builtin/uint16_test.gleam
Normal file
|
@ -0,0 +1,10 @@
|
|||
import bigi
|
||||
import gleeunit/should
|
||||
import ranged_int/builtin/uint16
|
||||
|
||||
pub fn add_test() {
|
||||
let assert Ok(a) = uint16.from_bigint(bigi.zero())
|
||||
let assert Ok(b) = uint16.from_bigint(bigi.from_int(12))
|
||||
let c = uint16.eject(uint16.add(a, b))
|
||||
should.equal(c, bigi.from_int(12))
|
||||
}
|
|
@ -3,8 +3,15 @@ import gleeunit/should
|
|||
import ranged_int/builtin/uint8
|
||||
|
||||
pub fn add_test() {
|
||||
let a = uint8.from_bigint_overflow(bigi.zero())
|
||||
let b = uint8.from_bigint_overflow(bigi.from_int(12))
|
||||
let c = uint8.math_op_overflow(a, b, bigi.add)
|
||||
should.equal(c, uint8.from_bigint_overflow(bigi.from_int(12)))
|
||||
let assert Ok(a) = uint8.from_bigint(bigi.zero())
|
||||
let assert Ok(b) = uint8.from_bigint(bigi.from_int(12))
|
||||
let c = uint8.eject(uint8.add(a, b))
|
||||
should.equal(c, bigi.from_int(12))
|
||||
}
|
||||
|
||||
pub fn divide_test() {
|
||||
let assert Ok(a) = uint8.from_bigint(bigi.from_int(120))
|
||||
let assert Ok(b) = uint8.from_bigint(bigi.from_int(12))
|
||||
let assert Ok(c) = uint8.divide_no_zero(a, b)
|
||||
should.equal(uint8.eject(c), bigi.from_int(10))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue