Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement is_one and Inv for Ratio. #19

Merged
merged 4 commits into from
Mar 8, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ version = "0.1.36"
default-features = false

[dependencies.num-traits]
version = "0.2.0"
version = "0.2.1"
default-features = false
features = ["std"]

Expand Down
33 changes: 30 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use std::str::FromStr;
use bigint::{BigInt, BigUint, Sign};

use integer::Integer;
use traits::{FromPrimitive, Float, PrimInt, Num, Signed, Zero, One, Bounded, NumCast, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv};
use traits::{FromPrimitive, Float, PrimInt, Num, Signed, Zero, One, Bounded, Inv, NumCast, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv};

/// Represents the ratio between 2 numbers.
#[derive(Copy, Clone, Debug)]
Expand Down Expand Up @@ -105,7 +105,7 @@ impl<T: Clone + Integer> Ratio<T> {
/// Returns true if the rational number is an integer (denominator is 1).
#[inline]
pub fn is_integer(&self) -> bool {
self.denom == One::one()
self.denom.is_one()
}

/// Puts self into lowest terms, with denom > 0.
Expand Down Expand Up @@ -715,6 +715,28 @@ impl<'a, T> Neg for &'a Ratio<T>
}
}

impl<T> Inv for Ratio<T>
where T: Clone + Integer
{
type Output = Ratio<T>;

#[inline]
fn inv(self) -> Ratio<T> {
self.recip()
}
}

impl<'a, T> Inv for &'a Ratio<T>
where T: Clone + Integer
{
type Output = Ratio<T>;

#[inline]
fn inv(self) -> Ratio<T> {
self.recip()
}
}

// Constants
impl<T: Clone + Integer> Zero for Ratio<T> {
#[inline]
Expand All @@ -733,6 +755,11 @@ impl<T: Clone + Integer> One for Ratio<T> {
fn one() -> Ratio<T> {
Ratio::new_raw(One::one(), One::one())
}

#[inline]
fn is_one(&self) -> bool {
self.numer == self.denom
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we consider the degenerate 0/0 case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, considering how 0/0 is an invalid state for Ratio, I'd assume that it shouldn't be worried about.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fair, and is_zero doesn't worry about it either.

Copy link
Contributor Author

@clarfonthey clarfonthey Mar 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about it, I'll add some debug_asserts to verify that the denominator is nonzero so that these can be caught in debug mode, but won't be checked on release.

I'll do this in a separate PR.

}
}

impl<T: Clone + Integer> Num for Ratio<T> {
Expand Down Expand Up @@ -812,7 +839,7 @@ impl<T> fmt::Display for Ratio<T>
{
/// Renders as `numer/denom`. If denom=1, renders as numer.
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.denom == One::one() {
if self.denom.is_one() {
write!(f, "{}", self.numer)
} else {
write!(f, "{}/{}", self.numer, self.denom)
Expand Down