Adjusted the natrual definition to now handle sub.
This neded a subtraction that would work on natural numbers where subtraction isn't closed. This will now handle it and filter to make sure the answer is 1 or higher.
This commit is contained in:
@ -1,10 +1,7 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// Sealed with Magistamp.
|
// Sealed with Magistamp.
|
||||||
|
|
||||||
use core::mem::size_of;
|
use core::ops::{Add, AddAssign, Mul, MulAssign};
|
||||||
use core::ops::{Add, Sub, Mul, Div, Rem};
|
|
||||||
use core::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
|
|
||||||
use core::str::FromStr;
|
|
||||||
|
|
||||||
use crate::number::Number;
|
use crate::number::Number;
|
||||||
use crate::one::One;
|
use crate::one::One;
|
||||||
@ -18,15 +15,68 @@ use crate::one::One;
|
|||||||
/// u8, u16, u32, u64, u128, usize
|
/// u8, u16, u32, u64, u128, usize
|
||||||
pub trait Natural: Number + One +
|
pub trait Natural: Number + One +
|
||||||
Add<Output=Self> + AddAssign +
|
Add<Output=Self> + AddAssign +
|
||||||
Sub<Output=Self> + SubAssign +
|
|
||||||
Mul<Output=Self> + MulAssign +
|
Mul<Output=Self> + MulAssign +
|
||||||
Div<Output=Self> + DivAssign +
|
|
||||||
Rem<Output=Self> + RemAssign
|
|
||||||
{
|
{
|
||||||
|
/// Attempts to subtract a number from itself.
|
||||||
|
///
|
||||||
|
/// Since subtraction isn't closed under this set (1 - 2 = -1) the trait
|
||||||
|
/// doesn't enforce that Sub and SubAssign are implemented. This function,
|
||||||
|
/// however, allows for subtraction and handles the case where the result is
|
||||||
|
/// no longer within the `Natural` numbers domain.
|
||||||
|
///
|
||||||
|
/// # Arguments
|
||||||
|
/// `rhs`: The number to subtract.
|
||||||
|
///
|
||||||
|
/// # Returns
|
||||||
|
/// `None` if the subtraction would fall below 1.
|
||||||
|
/// `Some` if their is a valid result.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```rust
|
||||||
|
/// use sigils::Natural;
|
||||||
|
///
|
||||||
|
/// let x = 3u8 as Natural;
|
||||||
|
///
|
||||||
|
/// assert_eq!(x.try_sub(2), Some(1));
|
||||||
|
/// assert_eq!(x.try_sub(7), None);
|
||||||
|
/// ```
|
||||||
|
fn try_sub(self, rhs: Self) -> Option<Self>;
|
||||||
|
/*
|
||||||
|
///
|
||||||
|
fn try_div(self, rhs: Self) -> Option<Self>;
|
||||||
|
|
||||||
|
///
|
||||||
|
fn try_rem(self, rhs: Self) -> Option<Self>;
|
||||||
|
|
||||||
/// Performs division and returns both the quotient and remainder.
|
/// Performs division and returns both the quotient and remainder.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn div_rem(self, rhs: Self) -> (Self, Self)
|
fn try_div_rem(self, rhs: Self) -> Option<(Self, Self)>
|
||||||
{
|
{
|
||||||
(self / rhs, self % rhs)
|
Some((self.try_div(rhs)?, self.try_rem(rhs)?))
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// A macro to make implementing the `Natural` trait easier for all the
|
||||||
|
/// base types in Rust.
|
||||||
|
macro_rules! natural_trait_impl
|
||||||
|
{
|
||||||
|
($($varType:ty),*) =>
|
||||||
|
{
|
||||||
|
$(
|
||||||
|
impl Natural for $varType
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn try_sub(self, rhs: Self) -> Option<Self>
|
||||||
|
{
|
||||||
|
self.checked_sub(rhs).filter(|x| *x >= Self::one())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implement the Number trait for the types that are Numbers.
|
||||||
|
natural_trait_impl!(u8, u16, u32, u64, u128, usize);
|
||||||
|
|||||||
Reference in New Issue
Block a user