//! top-level module. It's a singleton struct wrapping
//! [`FiniteNimberEnum`].
-use core::cmp::max;
use core::fmt::{Debug, Display, Formatter};
use core::ops::{Add, Div, Mul, Neg, Sub};
use itertools::Itertools;
},
}
}
+
+ /// Compute the multiplicative inverse of a nimber. Wrapper around
+ /// `inverse_recurse` which also chooses the starting level.
+ fn inverse(&self) -> Option<FiniteNimber> {
+ self.inverse_recurse(self.level())
+ }
}
impl<'a, 'b> Div<FiniteNimberRef<'a>> for FiniteNimberRef<'b> {
type Output = FiniteNimber;
fn div(self, other: FiniteNimberRef<'a>) -> FiniteNimber {
- let level = max(self.level(), other.level());
- let inverse = other.inverse_recurse(level).expect("Division by zero");
+ let inverse = other.inverse().expect("Division by zero");
self * inverse.to_ref()
}
}
}
}
+ /// Compute the multiplicative inverse of a nimber, i.e. the same
+ /// as `1/x`. Returns an `Option` so that it can return `None` in
+ /// the case of division by zero.
+ ///
+ /// Nimber multiplication is faster than division, so if you're
+ /// dividing more than one nimber by the same value, it's faster
+ /// to compute its inverse once and then multiply all the input
+ /// values by that.
+ pub fn inverse(&self) -> Option<FiniteNimber> {
+ self.to_ref().inverse()
+ }
+
/// Compute the square of a nimber, just like multiplying it by
/// itself in the ordinary way. This method is faster than the
/// general multiplication algorithm performed by the `Mul` trait,
) -> (FiniteNimber, FiniteNimber) {
// Strategy: we reduce this to the quadratic2() case by
// dividing through by a.
- Self::quadratic2(&(b / a), &(c / a))
+ let ainv = a.inverse().expect("Division by zero");
+ Self::quadratic2(&(b * &ainv), &(c * &ainv))
}
}