From 421d548082795e5afd70aba5a50535067e5e59db Mon Sep 17 00:00:00 2001 From: "Timothy J. Warren" Date: Wed, 12 Feb 2020 23:10:08 -0500 Subject: [PATCH] Add more mysteries --- src/bigint.rs | 37 ++++++++++++++++++++++--------------- src/lib.rs | 22 +++++++++++++++++++++- src/rational.rs | 31 ++++++++++++++++++++++++++++++- 3 files changed, 73 insertions(+), 17 deletions(-) diff --git a/src/bigint.rs b/src/bigint.rs index 03f2bf5..a2791e7 100644 --- a/src/bigint.rs +++ b/src/bigint.rs @@ -1,44 +1,51 @@ //! Arbitrarily large integers -use crate::Unsigned; - -#[derive(Debug)] -enum BigIntSign { - Positive, - Negative -} +//! +//! Traits to implement: +//! * Add +//! * AddAssign +//! * Div +//! * DivAssign +//! * Mul +//! * MulAssign +//! * Neg +//! * Rem +//! * RemAssign +//! * Sub +//! * SubAssign +use crate::{Sign, Unsigned}; #[derive(Debug)] pub struct BigInt { inner: Vec, - sign: BigIntSign, + sign: Sign, } impl Default for BigInt { fn default() -> Self { Self { inner: vec![], - sign: BigIntSign::Positive, + sign: Sign::Positive, } } } -impl From for BigInt { +impl From for BigInt { fn from(n: T) -> Self { let mut new = Self::default(); - if n > usize::max_value() { - new.inner = Self.split(n); + if n > T::max_value() { + new.inner = BigInt::split(n); } new } } -impl BigInt { +impl BigInt { /// Split an unsigned number into BigInt parts - fn split(num: T) -> Vec { + fn split(num: T) -> Vec { // Pretty easy if you don't actually need to split the value! - if num < usize::max_value() { + if num < T::max_value() { return vec![T::into()]; } diff --git a/src/lib.rs b/src/lib.rs index 3fb4e3c..40cef1d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,11 +1,13 @@ #![forbid(unsafe_code)] +use std::ops::Not; + pub mod bigint; pub mod rational; pub mod seq; /// Dummy trait for implementing generics on unsigned number types -pub trait Unsigned {} +pub trait Unsigned: PartialEq + PartialOrd {} impl Unsigned for u8 {} impl Unsigned for u16 {} @@ -14,6 +16,24 @@ impl Unsigned for u64 {} impl Unsigned for usize {} impl Unsigned for u128 {} +#[derive(Debug, Copy, Clone)] +pub enum Sign { + Positive, + Negative +} + +impl Not for Sign { + type Output = Sign; + + fn not(self) -> Self::Output { + match self { + Self::Positive => Self::Negative, + Self::Negative => Self::Positive, + _ => unreachable!() + } + } +} + #[cfg(test)] mod tests { #[test] diff --git a/src/rational.rs b/src/rational.rs index 5e735a4..be05b00 100644 --- a/src/rational.rs +++ b/src/rational.rs @@ -1,13 +1,30 @@ -use crate::Unsigned; +//! # Rational Numbers (fractions) +//! +//! Traits to implement: +//! * Add +//! * AddAssign +//! * Div +//! * DivAssign +//! * Mul +//! * MulAssign +//! * Neg +//! * Sub +//! * SubAssign +use crate::{Sign, Unsigned}; +use std::ops::Neg; + +#[derive(Debug, Copy, Clone)] pub enum FracType { Proper(T, Frac), Improper(Frac), } +#[derive(Debug, Copy, Clone)] pub struct Frac { numer: T, denom: T, + sign: Sign, } impl Frac { @@ -16,10 +33,22 @@ impl Frac { Frac { numer: n, denom: d, + sign: Sign::Positive, } } } +impl Neg for Frac { + type Output = Self; + + fn neg(self) -> Self::Output { + let mut out = self.clone(); + out.sign = !self.sign; + + out + } +} + #[cfg(test)] mod tests {