dashu_base/ring/
mod.rs

1//! Trait definitions for operations related to rings (integer/polynomial/etc.)
2
3/// Compute quotient and remainder at the same time.
4///
5/// # Examples
6/// ```
7/// use dashu_base::DivRem;
8/// assert_eq!(23.div_rem(10), (2, 3));
9/// ```
10pub trait DivRem<Rhs = Self> {
11    type OutputDiv;
12    type OutputRem;
13
14    fn div_rem(self, rhs: Rhs) -> (Self::OutputDiv, Self::OutputRem);
15}
16
17/// Compute quotient inplace and return remainder at the same time.
18///
19/// # Examples
20/// ```
21/// use dashu_base::DivRemAssign;
22/// let mut n = 23;
23/// let r = n.div_rem_assign(10);
24/// assert!(n == 2 && r == 3);
25/// ```
26pub trait DivRemAssign<Rhs = Self> {
27    type OutputRem;
28
29    fn div_rem_assign(&mut self, rhs: Rhs) -> Self::OutputRem;
30}
31
32/// Compute Euclidean quotient.
33///
34/// # Examples
35/// ```
36/// use dashu_base::DivEuclid;
37/// assert_eq!((-23).div_euclid(10), -3);
38/// ```
39pub trait DivEuclid<Rhs = Self> {
40    type Output;
41
42    fn div_euclid(self, rhs: Rhs) -> Self::Output;
43}
44
45/// Compute Euclidean remainder.
46///
47/// # Examples
48/// ```
49/// use dashu_base::RemEuclid;
50/// assert_eq!((-23).rem_euclid(10), 7);
51/// ```
52pub trait RemEuclid<Rhs = Self> {
53    type Output;
54
55    fn rem_euclid(self, rhs: Rhs) -> Self::Output;
56}
57
58/// Compute Euclidean quotient and remainder at the same time.
59///
60/// # Examples
61/// ```
62/// use dashu_base::DivRemEuclid;
63/// assert_eq!((-23).div_rem_euclid(10), (-3, 7));
64/// ```
65pub trait DivRemEuclid<Rhs = Self> {
66    type OutputDiv;
67    type OutputRem;
68
69    fn div_rem_euclid(self, rhs: Rhs) -> (Self::OutputDiv, Self::OutputRem);
70}
71
72/// Compute the greatest common divisor.
73///
74/// For negative integers, the common divisor is still kept positive.
75///
76/// # Examples
77/// ```
78/// use dashu_base::Gcd;
79/// assert_eq!(12u8.gcd(10u8), 2);
80/// ```
81///
82/// # Panics
83///
84/// Panics if both operands are zeros
85pub trait Gcd<Rhs = Self> {
86    type Output;
87
88    /// Compute the greatest common divisor between the two operands.
89    ///
90    /// Panics if both operands are zeros
91    fn gcd(self, rhs: Rhs) -> Self::Output;
92}
93
94/// Compute the greatest common divisor between self and the other operand, and return
95/// both the common divisor `g` and the Bézout coefficients respectively.
96///
97/// For negative integers, the common divisor is still kept positive.
98///
99/// # Examples
100/// ```
101/// use dashu_base::{Gcd, ExtendedGcd};
102/// let (g, cx, cy) = 12u8.gcd_ext(10u8);
103/// assert_eq!(g, 12u8.gcd(10u8));
104/// assert_eq!(g as i8, 12 * cx + 10 * cy);
105/// ```
106///
107/// # Panics
108///
109/// Panics if both operands are zeros
110pub trait ExtendedGcd<Rhs = Self> {
111    type OutputGcd;
112    type OutputCoeff;
113
114    /// Calculate the greatest common divisor between the two operands, returns
115    /// the common divisor `g` and the Bézout coefficients respectively.
116    ///
117    /// Panics if both operands are zeros
118    fn gcd_ext(self, rhs: Rhs) -> (Self::OutputGcd, Self::OutputCoeff, Self::OutputCoeff);
119}
120
121/// Computer the floored square root of the number and return the remainder at the same time.
122pub trait SquareRootRem {
123    type Output;
124
125    fn sqrt_rem(&self) -> (Self::Output, Self);
126}
127
128/// Computer the floored cubic root of the number and return the remainder at the same time.
129pub trait CubicRootRem {
130    type Output;
131
132    fn cbrt_rem(&self) -> (Self::Output, Self);
133}
134
135mod div_rem;
136mod gcd;
137mod root;
138pub(crate) use root::NormalizedRootRem;