diff --git a/num/src/arithm.rs b/num/src/arithm.rs new file mode 100644 index 0000000..e40270d --- /dev/null +++ b/num/src/arithm.rs @@ -0,0 +1,66 @@ +// Rust language amplification library providing multiple generic trait +// implementations, type wrappers, derive macros and other language enhancements +// +// Written in 2014 by +// Andrew Poelstra +// Updated in 2020-2024 by +// Dr. Maxim Orlovsky +// +// To the extent possible under law, the author(s) have dedicated all +// copyright and related and neighboring rights to this software to +// the public domain worldwide. This software is distributed without +// any warranty. +// +// You should have received a copy of the MIT License +// along with this software. +// If not, see . + +pub trait DivEuclid {} +pub trait RemEuclid {} +pub trait DivRem {} +pub trait DivRemEuclid {} + +pub trait CheckedNeg {} +pub trait WrappingNeg {} +pub trait SaturatingNeg {} + +pub trait CheckedInc {} +pub trait WrappingInc {} +pub trait SaturatingInc {} +pub trait OverflowingInc {} + +pub trait CheckedIncAssign {} +pub trait WrappingIncAssign {} +pub trait SaturatingIncAssign {} +pub trait OverflowingIncAssign {} + +pub trait CheckedAdd {} +pub trait CheckedDec {} +pub trait CheckedSub {} +pub trait CheckedMul {} +pub trait CheckedDiv {} +pub trait CheckedRem {} + +pub trait CheckedAddAssign {} +pub trait CheckedDecAssign {} +pub trait CheckedSubAssign {} +pub trait CheckedMulAssign {} +pub trait CheckedDivAssign {} +pub trait CheckedRemAssign {} + +pub trait WrappingDiv {} +pub trait SaturatingDiv {} + +pub trait WrappingRem {} +pub trait OverflowingRem {} + +pub trait WrappingDivEuclid {} +pub trait OverflowingDivEuclid {} + +pub trait WrappingRemEuclid {} +pub trait OverflowingRemEuclid {} + +pub trait CheckedShl {} +pub trait CyclicShl {} +pub trait SaturatingShl {} +pub trait OverflowingShl {} diff --git a/num/src/lib.rs b/num/src/lib.rs index c84dc57..313b9df 100644 --- a/num/src/lib.rs +++ b/num/src/lib.rs @@ -40,9 +40,11 @@ pub mod error; pub mod hex; pub mod posit; mod smallint; +mod traits; pub use bigint::{i1024, i256, i512, u1024, u256, u512}; pub use smallint::{u1, u2, u24, u3, u4, u40, u48, u5, u56, u6, u7}; +pub use traits::{BigInteger, Integer, Number, SInteger, SmallInteger, UInteger}; // TODO: Create arbitrary precision types // TODO: Move from using `u64` to `u128` for big int types diff --git a/num/src/traits.rs b/num/src/traits.rs new file mode 100644 index 0000000..3b57955 --- /dev/null +++ b/num/src/traits.rs @@ -0,0 +1,299 @@ +// Rust language amplification library providing multiple generic trait +// implementations, type wrappers, derive macros and other language enhancements +// +// Written in 2014 by +// Andrew Poelstra +// Updated in 2020-2024 by +// Dr. Maxim Orlovsky +// +// To the extent possible under law, the author(s) have dedicated all +// copyright and related and neighboring rights to this software to +// the public domain worldwide. This software is distributed without +// any warranty. +// +// You should have received a copy of the MIT License +// along with this software. +// If not, see . + +use crate::{i1024, i256, i512, u1, u1024, u2, u24, u256, u3, u4, u40, u48, u5, u512, u56, u6, u7}; + +pub trait Integer { + const BITS: usize; + const BYTES: usize; + const MIN: Self; + const MAX: Self; + const ZERO: Self; + const ONE: Self; + const IS_SIGNED: bool; +} + +impl Integer for u1 { + const BITS: usize = 1; + const BYTES: usize = 1; + const MIN: Self = Self(0); + const MAX: Self = Self(2 ^ Self::BITS as u8 - 1); + const ZERO: Self = Self(0); + const ONE: Self = Self(1); + const IS_SIGNED: bool = false; +} +impl Integer for u2 { + const BITS: usize = 2; + const BYTES: usize = 1; + const MIN: Self = Self(0); + const MAX: Self = Self(2 ^ Self::BITS as u8 - 1); + const ZERO: Self = Self(0); + const ONE: Self = Self(1); + const IS_SIGNED: bool = false; +} +impl Integer for u3 { + const BITS: usize = 3; + const BYTES: usize = 1; + const MIN: Self = Self(0); + const MAX: Self = Self(2 ^ Self::BITS as u8 - 1); + const ZERO: Self = Self(0); + const ONE: Self = Self(1); + const IS_SIGNED: bool = false; +} +impl Integer for u4 { + const BITS: usize = 4; + const BYTES: usize = 1; + const MIN: Self = Self(0); + const MAX: Self = Self(2 ^ Self::BITS as u8 - 1); + const ZERO: Self = Self(0); + const ONE: Self = Self(1); + const IS_SIGNED: bool = false; +} +impl Integer for u5 { + const BITS: usize = 5; + const BYTES: usize = 1; + const MIN: Self = Self(0); + const MAX: Self = Self(2 ^ Self::BITS as u8 - 1); + const ZERO: Self = Self(0); + const ONE: Self = Self(1); + const IS_SIGNED: bool = false; +} +impl Integer for u6 { + const BITS: usize = 6; + const BYTES: usize = 1; + const MIN: Self = Self(0); + const MAX: Self = Self(2 ^ Self::BITS as u8 - 1); + const ZERO: Self = Self(0); + const ONE: Self = Self(1); + const IS_SIGNED: bool = false; +} +impl Integer for u7 { + const BITS: usize = 7; + const BYTES: usize = 1; + const MIN: Self = Self(0); + const MAX: Self = Self(2 ^ Self::BITS as u8 - 1); + const ZERO: Self = Self(0); + const ONE: Self = Self(1); + const IS_SIGNED: bool = false; +} +impl Integer for u8 { + const BITS: usize = 8; + const BYTES: usize = 1; + const MIN: Self = 0; + const MAX: Self = 2 ^ Self::BITS as Self - 1; + const ZERO: Self = 0; + const ONE: Self = 1; + const IS_SIGNED: bool = false; +} +impl Integer for u16 { + const BITS: usize = 16; + const BYTES: usize = 1; + const MIN: Self = 0; + const MAX: Self = 2 ^ Self::BITS as Self - 1; + const ZERO: Self = 0; + const ONE: Self = 1; + const IS_SIGNED: bool = false; +} +impl Integer for u24 { + const BITS: usize = 24; + const BYTES: usize = 1; + const MIN: Self = Self(0); + const MAX: Self = Self(2 ^ Self::BITS - 1); + const ZERO: Self = Self(0); + const ONE: Self = Self(1); + const IS_SIGNED: bool = false; +} +impl Integer for u32 { + const BITS: usize = 32; + const BYTES: usize = 1; + const MIN: Self = 0; + const MAX: Self = 2 ^ Self::BITS - 1; + const ZERO: Self = 0; + const ONE: Self = 1; + const IS_SIGNED: bool = false; +} +impl Integer for u40 { + const BITS: usize = 40; + const BYTES: usize = 1; + const MIN: Self = Self(0); + const MAX: Self = Self(2 ^ Self::BITS as u64 - 1); + const ZERO: Self = Self(0); + const ONE: Self = Self(1); + const IS_SIGNED: bool = false; +} +impl Integer for u48 { + const BITS: usize = 48; + const BYTES: usize = 1; + const MIN: Self = Self(0); + const MAX: Self = Self(2 ^ Self::BITS as u64 - 1); + const ZERO: Self = Self(0); + const ONE: Self = Self(1); + const IS_SIGNED: bool = false; +} +impl Integer for u56 { + const BITS: usize = 56; + const BYTES: usize = 1; + const MIN: Self = Self(0); + const MAX: Self = Self(2 ^ Self::BITS as u64 - 1); + const ZERO: Self = Self(0); + const ONE: Self = Self(1); + const IS_SIGNED: bool = false; +} +impl Integer for u64 { + const BITS: usize = 64; + const BYTES: usize = 1; + const MIN: Self = 0; + const MAX: Self = 2 ^ Self::BITS as Self - 1; + const ZERO: Self = 0; + const ONE: Self = 1; + const IS_SIGNED: bool = false; +} +impl Integer for u128 { + const BITS: usize = 128; + const BYTES: usize = 1; + const MIN: Self = 0; + const MAX: Self = 2 ^ Self::BITS as Self - 1; + const ZERO: Self = 0; + const ONE: Self = 1; + const IS_SIGNED: bool = false; +} +impl Integer for u256 { + const BITS: usize = 256; + const BYTES: usize = 1; + const MIN: Self = Self::ZERO; + const MAX: Self = Self::MAX; + const ZERO: Self = Self::ZERO; + const ONE: Self = Self::ONE; + const IS_SIGNED: bool = false; +} +impl Integer for u512 { + const BITS: usize = 512; + const BYTES: usize = 1; + const MIN: Self = Self::ZERO; + const MAX: Self = Self::MAX; + const ZERO: Self = Self::ZERO; + const ONE: Self = Self::ONE; + const IS_SIGNED: bool = false; +} +impl Integer for u1024 { + const BITS: usize = 1024; + const BYTES: usize = 1; + const MIN: Self = Self::ZERO; + const MAX: Self = Self::MAX; + const ZERO: Self = Self::ZERO; + const ONE: Self = Self::ONE; + const IS_SIGNED: bool = false; +} + +pub trait MultibyteInteger: Integer { + fn from_le_bytes(bytes: [u8; Self::BYTES]) -> Self; + fn from_be_bytes(bytes: [u8; Self::BYTES]) -> Self; + fn to_le_bytes(self) -> [u8; Self::BYTES]; + fn to_be_bytes(self) -> [u8; Self::BYTES]; +} + +pub trait SInteger { + const NEG: Self; +} + +impl SInteger for i8 { + const NEG: Self = -1; +} +impl SInteger for i16 { + const NEG: Self = -1; +} +impl SInteger for i32 { + const NEG: Self = -1; +} +impl SInteger for i64 { + const NEG: Self = -1; +} +impl SInteger for i128 { + const NEG: Self = -1; +} + +pub trait UInteger {} + +impl UInteger for u1 {} +impl UInteger for u2 {} +impl UInteger for u3 {} +impl UInteger for u4 {} +impl UInteger for u5 {} +impl UInteger for u6 {} +impl UInteger for u7 {} +impl UInteger for u8 {} +impl UInteger for u16 {} +impl UInteger for u24 {} +impl UInteger for u32 {} +impl UInteger for u40 {} +impl UInteger for u48 {} +impl UInteger for u56 {} +impl UInteger for u64 {} +impl UInteger for u128 {} +impl UInteger for u256 {} +impl UInteger for u512 {} +impl UInteger for u1024 {} + +pub trait SmallInteger { + type Inner: Integer; +} + +impl SmallInteger for u1 { + type Inner = u8; +} +impl SmallInteger for u2 { + type Inner = u8; +} +impl SmallInteger for u3 { + type Inner = u8; +} +impl SmallInteger for u4 { + type Inner = u8; +} +impl SmallInteger for u5 { + type Inner = u8; +} +impl SmallInteger for u6 { + type Inner = u8; +} +impl SmallInteger for u7 { + type Inner = u8; +} +impl SmallInteger for u24 { + type Inner = u32; +} +impl SmallInteger for u40 { + type Inner = u64; +} +impl SmallInteger for u48 { + type Inner = u64; +} +impl SmallInteger for u56 { + type Inner = u64; +} + +pub trait BigInteger { + const INNER_LEN: u8; + type Inner: Integer; +} + +impl BigInteger for u256 {} +impl BigInteger for u512 {} +impl BigInteger for u1024 {} +impl BigInteger for i256 {} +impl BigInteger for i512 {} +impl BigInteger for i1024 {}