Add more mysteries

This commit is contained in:
Timothy Warren 2020-02-12 23:10:08 -05:00
parent 4d15858e45
commit 421d548082
3 changed files with 73 additions and 17 deletions

View File

@ -1,44 +1,51 @@
//! Arbitrarily large integers //! Arbitrarily large integers
use crate::Unsigned; //!
//! Traits to implement:
#[derive(Debug)] //! * Add
enum BigIntSign { //! * AddAssign
Positive, //! * Div
Negative //! * DivAssign
} //! * Mul
//! * MulAssign
//! * Neg
//! * Rem
//! * RemAssign
//! * Sub
//! * SubAssign
use crate::{Sign, Unsigned};
#[derive(Debug)] #[derive(Debug)]
pub struct BigInt { pub struct BigInt {
inner: Vec<usize>, inner: Vec<usize>,
sign: BigIntSign, sign: Sign,
} }
impl Default for BigInt { impl Default for BigInt {
fn default() -> Self { fn default() -> Self {
Self { Self {
inner: vec![], inner: vec![],
sign: BigIntSign::Positive, sign: Sign::Positive,
} }
} }
} }
impl From<T: Unsigned> for BigInt { impl<T: Unsigned> From<T> for BigInt {
fn from(n: T) -> Self { fn from(n: T) -> Self {
let mut new = Self::default(); let mut new = Self::default();
if n > usize::max_value() { if n > T::max_value() {
new.inner = Self.split(n); new.inner = BigInt::split(n);
} }
new new
} }
} }
impl<T: Unsigned> BigInt { impl BigInt {
/// Split an unsigned number into BigInt parts /// Split an unsigned number into BigInt parts
fn split(num: T) -> Vec<usize> { fn split<T: Unsigned>(num: T) -> Vec<usize> {
// Pretty easy if you don't actually need to split the value! // 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()]; return vec![T::into()];
} }

View File

@ -1,11 +1,13 @@
#![forbid(unsafe_code)] #![forbid(unsafe_code)]
use std::ops::Not;
pub mod bigint; pub mod bigint;
pub mod rational; pub mod rational;
pub mod seq; pub mod seq;
/// Dummy trait for implementing generics on unsigned number types /// Dummy trait for implementing generics on unsigned number types
pub trait Unsigned {} pub trait Unsigned: PartialEq + PartialOrd {}
impl Unsigned for u8 {} impl Unsigned for u8 {}
impl Unsigned for u16 {} impl Unsigned for u16 {}
@ -14,6 +16,24 @@ impl Unsigned for u64 {}
impl Unsigned for usize {} impl Unsigned for usize {}
impl Unsigned for u128 {} 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)] #[cfg(test)]
mod tests { mod tests {
#[test] #[test]

View File

@ -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<T: Unsigned = usize> { pub enum FracType<T: Unsigned = usize> {
Proper(T, Frac), Proper(T, Frac),
Improper(Frac), Improper(Frac),
} }
#[derive(Debug, Copy, Clone)]
pub struct Frac<T: Unsigned = usize> { pub struct Frac<T: Unsigned = usize> {
numer: T, numer: T,
denom: T, denom: T,
sign: Sign,
} }
impl<T: Unsigned> Frac<T> { impl<T: Unsigned> Frac<T> {
@ -16,10 +33,22 @@ impl<T: Unsigned> Frac<T> {
Frac { Frac {
numer: n, numer: n,
denom: d, denom: d,
sign: Sign::Positive,
} }
} }
} }
impl<T: Unsigned> Neg for Frac<T> {
type Output = Self;
fn neg(self) -> Self::Output {
let mut out = self.clone();
out.sign = !self.sign;
out
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {