Łukasz Jan Niemier преди 9 години
родител
ревизия
54685c46a1
променени са 13 файла, в които са добавени 1277 реда и са изтрити 142 реда
  1. 2 5
      .travis.yml
  2. 0 2
      .travis/test_features.sh
  3. 7 3
      Cargo.toml
  4. 14 0
      Makefile
  5. 3 2
      bigint/Cargo.toml
  6. 43 31
      bigint/src/lib.rs
  7. 10 10
      integer/src/lib.rs
  8. 24 0
      rational/Cargo.toml
  9. 1091 0
      rational/src/lib.rs
  10. 12 17
      src/lib.rs
  11. 1 2
      traits/src/cast.rs
  12. 54 54
      traits/src/float.rs
  13. 16 16
      traits/src/int.rs

+ 2 - 5
.travis.yml

@@ -5,12 +5,9 @@ rust:
   - nightly
 sudo: false
 script:
-  - cargo build --verbose
-  - cargo test --verbose
-  - .travis/test_features.sh
+  - make test
   - |
-    [ $TRAVIS_RUST_VERSION != nightly ] ||
-    .travis/test_nightly.sh
+    [ $TRAVIS_RUST_VERSION != nightly ] || .travis/test_nightly.sh
   - cargo doc
 after_success: |
   [ $TRAVIS_BRANCH = master ] &&

+ 0 - 2
.travis/test_features.sh

@@ -3,7 +3,5 @@
 set -ex
 
 for feature in '' bigint rational complex; do
-  cargo build --verbose --no-default-features --features="$feature"
   cargo test --verbose --no-default-features --features="$feature"
 done
-

+ 7 - 3
Cargo.toml

@@ -19,12 +19,16 @@ name = "shootout-pidigits"
 [dependencies]
 
 [dependencies.num-bigint]
-optional = false
+optional = true
 path = "bigint"
 
 [dependencies.num-integer]
 path = "./integer"
 
+[dependencies.num-rational]
+optional = true
+path = "rational"
+
 [dependencies.num-traits]
 path = "./traits"
 
@@ -46,7 +50,7 @@ version = "^0.7.0"
 version = "0.3.8"
 
 [features]
-bigint = []
+bigint = ["num-bigint"]
 complex = []
 default = ["bigint", "complex", "rand", "rational", "rustc-serialize"]
-rational = []
+rational = ["num-rational"]

+ 14 - 0
Makefile

@@ -0,0 +1,14 @@
+CARGO_CMD ?= cargo
+
+packages = bigint integer rational traits
+
+test:
+	$(MAKE) run-all TASK="test --no-fail-fast"
+
+run-all: $(packages)
+	$(CARGO_CMD) $(TASK)
+
+$(packages):
+	$(CARGO_CMD) $(TASK) --manifest-path $@/Cargo.toml
+
+.PHONY: $(packages) test

+ 3 - 2
bigint/Cargo.toml

@@ -6,11 +6,9 @@ version = "0.1.0"
 [dependencies]
 
 [dependencies.num-integer]
-optional = false
 path = "../integer"
 
 [dependencies.num-traits]
-optional = false
 path = "../traits"
 
 [dependencies.rand]
@@ -20,3 +18,6 @@ version = "0.3.14"
 [dependencies.serde]
 optional = true
 version = "0.7.0"
+
+[features]
+default = ["rand"]

+ 43 - 31
bigint/src/lib.rs

@@ -18,8 +18,9 @@
 //!
 //! ## Example
 //!
-//! ```rust
-//! use num::{BigUint, Zero, One};
+//! ```rust,ignore
+//! use num_bigint::BigUint;
+//! use num_traits::{Zero, One};
 //! use std::mem::replace;
 //!
 //! // Calculate large fibonacci numbers.
@@ -42,11 +43,11 @@
 //!
 //! ```rust
 //! extern crate rand;
-//! extern crate num;
+//! extern crate num_bigint as bigint;
 //!
 //! # #[cfg(feature = "rand")]
 //! # fn main() {
-//! use num::bigint::{ToBigInt, RandBigInt};
+//! use bigint::{ToBigInt, RandBigInt};
 //!
 //! let mut rng = rand::thread_rng();
 //! let a = rng.gen_bigint(1000);
@@ -64,6 +65,9 @@
 //! # }
 //! ```
 
+#[cfg(any(feature = "rand", test))]
+extern crate rand;
+
 extern crate num_integer as integer;
 extern crate num_traits as traits;
 
@@ -75,6 +79,7 @@ use std::num::ParseIntError;
 use std::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Neg, Rem, Shl, Shr, Sub};
 use std::str::{self, FromStr};
 use std::fmt;
+use std::hash;
 use std::cmp::Ordering::{self, Less, Greater, Equal};
 use std::{f32, f64};
 use std::{u8, i64, u64};
@@ -1655,7 +1660,7 @@ impl BigUint {
     /// # Examples
     ///
     /// ```
-    /// use num::bigint::BigUint;
+    /// use num_bigint::BigUint;
     ///
     /// assert_eq!(BigUint::from_bytes_be(b"A"),
     ///            BigUint::parse_bytes(b"65", 10).unwrap());
@@ -1694,7 +1699,7 @@ impl BigUint {
     /// # Examples
     ///
     /// ```
-    /// use num::bigint::BigUint;
+    /// use num_bigint::BigUint;
     ///
     /// let i = BigUint::parse_bytes(b"1125", 10).unwrap();
     /// assert_eq!(i.to_bytes_le(), vec![101, 4]);
@@ -1713,7 +1718,7 @@ impl BigUint {
     /// # Examples
     ///
     /// ```
-    /// use num::bigint::BigUint;
+    /// use num_bigint::BigUint;
     ///
     /// let i = BigUint::parse_bytes(b"1125", 10).unwrap();
     /// assert_eq!(i.to_bytes_be(), vec![4, 101]);
@@ -1731,7 +1736,7 @@ impl BigUint {
     /// # Examples
     ///
     /// ```
-    /// use num::bigint::BigUint;
+    /// use num_bigint::BigUint;
     ///
     /// let i = BigUint::parse_bytes(b"ff", 16).unwrap();
     /// assert_eq!(i.to_str_radix(16), "ff");
@@ -1748,7 +1753,7 @@ impl BigUint {
     /// # Examples
     ///
     /// ```
-    /// use num::bigint::{BigUint, ToBigUint};
+    /// use num_bigint::{BigUint, ToBigUint};
     ///
     /// assert_eq!(BigUint::parse_bytes(b"1234", 10), ToBigUint::to_biguint(&1234));
     /// assert_eq!(BigUint::parse_bytes(b"ABCD", 16), ToBigUint::to_biguint(&0xABCD));
@@ -2764,7 +2769,7 @@ impl BigInt {
     /// # Examples
     ///
     /// ```
-    /// use num::bigint::{BigInt, Sign};
+    /// use num_bigint::{BigInt, Sign};
     ///
     /// assert_eq!(BigInt::from_bytes_be(Sign::Plus, b"A"),
     ///            BigInt::parse_bytes(b"65", 10).unwrap());
@@ -2793,7 +2798,7 @@ impl BigInt {
     /// # Examples
     ///
     /// ```
-    /// use num::bigint::{ToBigInt, Sign};
+    /// use num_bigint::{ToBigInt, Sign};
     ///
     /// let i = -1125.to_bigint().unwrap();
     /// assert_eq!(i.to_bytes_le(), (Sign::Minus, vec![101, 4]));
@@ -2808,7 +2813,7 @@ impl BigInt {
     /// # Examples
     ///
     /// ```
-    /// use num::bigint::{ToBigInt, Sign};
+    /// use num_bigint::{ToBigInt, Sign};
     ///
     /// let i = -1125.to_bigint().unwrap();
     /// assert_eq!(i.to_bytes_be(), (Sign::Minus, vec![4, 101]));
@@ -2824,7 +2829,7 @@ impl BigInt {
     /// # Examples
     ///
     /// ```
-    /// use num::bigint::BigInt;
+    /// use num_bigint::BigInt;
     ///
     /// let i = BigInt::parse_bytes(b"ff", 16).unwrap();
     /// assert_eq!(i.to_str_radix(16), "ff");
@@ -2846,7 +2851,7 @@ impl BigInt {
     /// # Examples
     ///
     /// ```
-    /// use num::bigint::{ToBigInt, Sign};
+    /// use num_bigint::{ToBigInt, Sign};
     ///
     /// assert_eq!(ToBigInt::to_bigint(&1234).unwrap().sign(), Sign::Plus);
     /// assert_eq!(ToBigInt::to_bigint(&-4321).unwrap().sign(), Sign::Minus);
@@ -2862,7 +2867,7 @@ impl BigInt {
     /// # Examples
     ///
     /// ```
-    /// use num::bigint::{BigInt, ToBigInt};
+    /// use num_bigint::{BigInt, ToBigInt};
     ///
     /// assert_eq!(BigInt::parse_bytes(b"1234", 10), ToBigInt::to_bigint(&1234));
     /// assert_eq!(BigInt::parse_bytes(b"ABCD", 16), ToBigInt::to_bigint(&0xABCD));
@@ -2935,9 +2940,17 @@ impl From<ParseIntError> for ParseBigIntError {
     }
 }
 
+#[cfg(test)]
+fn hash<T: hash::Hash>(x: &T) -> u64 {
+    use std::hash::Hasher;
+    let mut hasher = hash::SipHasher::new();
+    x.hash(&mut hasher);
+    hasher.finish()
+}
+
 #[cfg(test)]
 mod biguint_tests {
-    use Integer;
+    use integer::Integer;
     use super::{BigDigit, BigUint, ToBigUint, big_digit};
     use super::{BigInt, RandBigInt, ToBigInt};
     use super::Sign::Plus;
@@ -2950,9 +2963,9 @@ mod biguint_tests {
     use std::{u8, u16, u32, u64, usize};
 
     use rand::thread_rng;
-    use {Num, Zero, One, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv};
-    use {ToPrimitive, FromPrimitive};
-    use Float;
+    use traits::{Num, Zero, One, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv, ToPrimitive,
+                 FromPrimitive, Float};
+
 
     /// Assert that an op works for all val/ref combinations
     macro_rules! assert_op {
@@ -3083,10 +3096,10 @@ mod biguint_tests {
         let c = BigUint::new(vec![1]);
         let d = BigUint::new(vec![1, 0, 0, 0, 0, 0]);
         let e = BigUint::new(vec![0, 0, 0, 0, 0, 1]);
-        assert!(::hash(&a) == ::hash(&b));
-        assert!(::hash(&b) != ::hash(&c));
-        assert!(::hash(&c) == ::hash(&d));
-        assert!(::hash(&d) != ::hash(&e));
+        assert!(super::hash(&a) == super::hash(&b));
+        assert!(super::hash(&b) != super::hash(&c));
+        assert!(super::hash(&c) == super::hash(&d));
+        assert!(super::hash(&d) != super::hash(&e));
     }
 
     const BIT_TESTS: &'static [(&'static [BigDigit],
@@ -4173,7 +4186,6 @@ mod biguint_tests {
 
 #[cfg(test)]
 mod bigint_tests {
-    use Integer;
     use super::{BigDigit, BigUint, ToBigUint};
     use super::{Sign, BigInt, RandBigInt, ToBigInt, big_digit};
     use super::Sign::{Minus, NoSign, Plus};
@@ -4187,8 +4199,8 @@ mod bigint_tests {
 
     use rand::thread_rng;
 
-    use {Zero, One, Signed, ToPrimitive, FromPrimitive, Num};
-    use Float;
+    use integer::Integer;
+    use traits::{Zero, One, Signed, ToPrimitive, FromPrimitive, Num, Float};
 
     /// Assert that an op works for all val/ref combinations
     macro_rules! assert_op {
@@ -4334,11 +4346,11 @@ mod bigint_tests {
         let d = BigInt::new(Plus, vec![1, 0, 0, 0, 0, 0]);
         let e = BigInt::new(Plus, vec![0, 0, 0, 0, 0, 1]);
         let f = BigInt::new(Minus, vec![1]);
-        assert!(::hash(&a) == ::hash(&b));
-        assert!(::hash(&b) != ::hash(&c));
-        assert!(::hash(&c) == ::hash(&d));
-        assert!(::hash(&d) != ::hash(&e));
-        assert!(::hash(&c) != ::hash(&f));
+        assert!(super::hash(&a) == super::hash(&b));
+        assert!(super::hash(&b) != super::hash(&c));
+        assert!(super::hash(&c) == super::hash(&d));
+        assert!(super::hash(&d) != super::hash(&e));
+        assert!(super::hash(&c) != super::hash(&f));
     }
 
     #[test]

+ 10 - 10
integer/src/lib.rs

@@ -20,7 +20,7 @@ pub trait Integer: Sized + Num + PartialOrd + Ord + Eq {
     /// # Examples
     ///
     /// ~~~
-    /// # use num::Integer;
+    /// # use num_integer::Integer;
     /// assert!(( 8).div_floor(& 3) ==  2);
     /// assert!(( 8).div_floor(&-3) == -3);
     /// assert!((-8).div_floor(& 3) == -3);
@@ -36,7 +36,7 @@ pub trait Integer: Sized + Num + PartialOrd + Ord + Eq {
     /// Floored integer modulo, satisfying:
     ///
     /// ~~~
-    /// # use num::Integer;
+    /// # use num_integer::Integer;
     /// # let n = 1; let d = 1;
     /// assert!(n.div_floor(&d) * d + n.mod_floor(&d) == n)
     /// ~~~
@@ -44,7 +44,7 @@ pub trait Integer: Sized + Num + PartialOrd + Ord + Eq {
     /// # Examples
     ///
     /// ~~~
-    /// # use num::Integer;
+    /// # use num_integer::Integer;
     /// assert!(( 8).mod_floor(& 3) ==  2);
     /// assert!(( 8).mod_floor(&-3) == -1);
     /// assert!((-8).mod_floor(& 3) ==  1);
@@ -62,7 +62,7 @@ pub trait Integer: Sized + Num + PartialOrd + Ord + Eq {
     /// # Examples
     ///
     /// ~~~
-    /// # use num::Integer;
+    /// # use num_integer::Integer;
     /// assert_eq!(6.gcd(&8), 2);
     /// assert_eq!(7.gcd(&3), 1);
     /// ~~~
@@ -73,7 +73,7 @@ pub trait Integer: Sized + Num + PartialOrd + Ord + Eq {
     /// # Examples
     ///
     /// ~~~
-    /// # use num::Integer;
+    /// # use num_integer::Integer;
     /// assert_eq!(7.lcm(&3), 21);
     /// assert_eq!(2.lcm(&4), 4);
     /// ~~~
@@ -87,7 +87,7 @@ pub trait Integer: Sized + Num + PartialOrd + Ord + Eq {
     /// # Examples
     ///
     /// ~~~
-    /// # use num::Integer;
+    /// # use num_integer::Integer;
     /// assert_eq!(9.is_multiple_of(&3), true);
     /// assert_eq!(3.is_multiple_of(&9), false);
     /// ~~~
@@ -98,7 +98,7 @@ pub trait Integer: Sized + Num + PartialOrd + Ord + Eq {
     /// # Examples
     ///
     /// ~~~
-    /// # use num::Integer;
+    /// # use num_integer::Integer;
     /// assert_eq!(3.is_even(), false);
     /// assert_eq!(4.is_even(), true);
     /// ~~~
@@ -109,7 +109,7 @@ pub trait Integer: Sized + Num + PartialOrd + Ord + Eq {
     /// # Examples
     ///
     /// ~~~
-    /// # use num::Integer;
+    /// # use num_integer::Integer;
     /// assert_eq!(3.is_odd(), true);
     /// assert_eq!(4.is_odd(), false);
     /// ~~~
@@ -121,7 +121,7 @@ pub trait Integer: Sized + Num + PartialOrd + Ord + Eq {
     /// # Examples
     ///
     /// ~~~
-    /// # use num::Integer;
+    /// # use num_integer::Integer;
     /// assert_eq!(( 8).div_rem( &3), ( 2,  2));
     /// assert_eq!(( 8).div_rem(&-3), (-2,  2));
     /// assert_eq!((-8).div_rem( &3), (-2, -2));
@@ -141,7 +141,7 @@ pub trait Integer: Sized + Num + PartialOrd + Ord + Eq {
     /// # Examples
     ///
     /// ~~~
-    /// # use num::Integer;
+    /// # use num_integer::Integer;
     /// assert_eq!(( 8).div_mod_floor( &3), ( 2,  2));
     /// assert_eq!(( 8).div_mod_floor(&-3), (-3, -1));
     /// assert_eq!((-8).div_mod_floor( &3), (-3,  1));

+ 24 - 0
rational/Cargo.toml

@@ -0,0 +1,24 @@
+[package]
+authors = ["Łukasz Jan Niemier <[email protected]>"]
+name = "num-rational"
+version = "0.1.0"
+
+[dependencies]
+
+[dependencies.num-bigint]
+optional = true
+path = "../bigint"
+
+[dependencies.num-integer]
+path = "../integer"
+
+[dependencies.num-traits]
+path = "../traits"
+
+[dependencies.serde]
+optional = true
+version = "0.7.0"
+
+[features]
+default = ["bigint"]
+bigint = ["num-bigint"]

+ 1091 - 0
rational/src/lib.rs

@@ -0,0 +1,1091 @@
+// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Rational numbers
+
+#[cfg(feature = "serde")]
+extern crate serde;
+#[cfg(feature = "num-bigint")]
+extern crate num_bigint as bigint;
+
+extern crate num_traits as traits;
+extern crate num_integer as integer;
+
+use std::cmp;
+use std::error::Error;
+use std::fmt;
+use std::hash;
+use std::ops::{Add, Div, Mul, Neg, Rem, Sub};
+use std::str::FromStr;
+
+#[cfg(feature = "serde")]
+use serde;
+
+#[cfg(feature = "num-bigint")]
+use bigint::{BigInt, BigUint, Sign};
+
+use integer::Integer;
+use traits::{FromPrimitive, Float, PrimInt, Num, Signed, Zero, One};
+
+/// Represents the ratio between 2 numbers.
+#[derive(Copy, Clone, Hash, Debug)]
+#[cfg_attr(feature = "rustc-serialize", derive(RustcEncodable, RustcDecodable))]
+#[allow(missing_docs)]
+pub struct Ratio<T> {
+    numer: T,
+    denom: T,
+}
+
+/// Alias for a `Ratio` of machine-sized integers.
+pub type Rational = Ratio<isize>;
+pub type Rational32 = Ratio<i32>;
+pub type Rational64 = Ratio<i64>;
+
+#[cfg(feature = "num-bigint")]
+/// Alias for arbitrary precision rationals.
+pub type BigRational = Ratio<BigInt>;
+
+impl<T: Clone + Integer> Ratio<T> {
+    /// Creates a ratio representing the integer `t`.
+    #[inline]
+    pub fn from_integer(t: T) -> Ratio<T> {
+        Ratio::new_raw(t, One::one())
+    }
+
+    /// Creates a ratio without checking for `denom == 0` or reducing.
+    #[inline]
+    pub fn new_raw(numer: T, denom: T) -> Ratio<T> {
+        Ratio {
+            numer: numer,
+            denom: denom,
+        }
+    }
+
+    /// Create a new Ratio. Fails if `denom == 0`.
+    #[inline]
+    pub fn new(numer: T, denom: T) -> Ratio<T> {
+        if denom == Zero::zero() {
+            panic!("denominator == 0");
+        }
+        let mut ret = Ratio::new_raw(numer, denom);
+        ret.reduce();
+        ret
+    }
+
+    /// Converts to an integer.
+    #[inline]
+    pub fn to_integer(&self) -> T {
+        self.trunc().numer
+    }
+
+    /// Gets an immutable reference to the numerator.
+    #[inline]
+    pub fn numer<'a>(&'a self) -> &'a T {
+        &self.numer
+    }
+
+    /// Gets an immutable reference to the denominator.
+    #[inline]
+    pub fn denom<'a>(&'a self) -> &'a T {
+        &self.denom
+    }
+
+    /// Returns true if the rational number is an integer (denominator is 1).
+    #[inline]
+    pub fn is_integer(&self) -> bool {
+        self.denom == One::one()
+    }
+
+    /// Put self into lowest terms, with denom > 0.
+    fn reduce(&mut self) {
+        let g: T = self.numer.gcd(&self.denom);
+
+        // FIXME(#5992): assignment operator overloads
+        // self.numer /= g;
+        self.numer = self.numer.clone() / g.clone();
+        // FIXME(#5992): assignment operator overloads
+        // self.denom /= g;
+        self.denom = self.denom.clone() / g;
+
+        // keep denom positive!
+        if self.denom < T::zero() {
+            self.numer = T::zero() - self.numer.clone();
+            self.denom = T::zero() - self.denom.clone();
+        }
+    }
+
+    /// Returns a `reduce`d copy of self.
+    pub fn reduced(&self) -> Ratio<T> {
+        let mut ret = self.clone();
+        ret.reduce();
+        ret
+    }
+
+    /// Returns the reciprocal.
+    #[inline]
+    pub fn recip(&self) -> Ratio<T> {
+        Ratio::new_raw(self.denom.clone(), self.numer.clone())
+    }
+
+    /// Rounds towards minus infinity.
+    #[inline]
+    pub fn floor(&self) -> Ratio<T> {
+        if *self < Zero::zero() {
+            let one: T = One::one();
+            Ratio::from_integer((self.numer.clone() - self.denom.clone() + one) /
+                                self.denom.clone())
+        } else {
+            Ratio::from_integer(self.numer.clone() / self.denom.clone())
+        }
+    }
+
+    /// Rounds towards plus infinity.
+    #[inline]
+    pub fn ceil(&self) -> Ratio<T> {
+        if *self < Zero::zero() {
+            Ratio::from_integer(self.numer.clone() / self.denom.clone())
+        } else {
+            let one: T = One::one();
+            Ratio::from_integer((self.numer.clone() + self.denom.clone() - one) /
+                                self.denom.clone())
+        }
+    }
+
+    /// Rounds to the nearest integer. Rounds half-way cases away from zero.
+    #[inline]
+    pub fn round(&self) -> Ratio<T> {
+        let zero: Ratio<T> = Zero::zero();
+        let one: T = One::one();
+        let two: T = one.clone() + one.clone();
+
+        // Find unsigned fractional part of rational number
+        let mut fractional = self.fract();
+        if fractional < zero {
+            fractional = zero - fractional
+        };
+
+        // The algorithm compares the unsigned fractional part with 1/2, that
+        // is, a/b >= 1/2, or a >= b/2. For odd denominators, we use
+        // a >= (b/2)+1. This avoids overflow issues.
+        let half_or_larger = if fractional.denom().is_even() {
+            *fractional.numer() >= fractional.denom().clone() / two.clone()
+        } else {
+            *fractional.numer() >= (fractional.denom().clone() / two.clone()) + one.clone()
+        };
+
+        if half_or_larger {
+            let one: Ratio<T> = One::one();
+            if *self >= Zero::zero() {
+                self.trunc() + one
+            } else {
+                self.trunc() - one
+            }
+        } else {
+            self.trunc()
+        }
+    }
+
+    /// Rounds towards zero.
+    #[inline]
+    pub fn trunc(&self) -> Ratio<T> {
+        Ratio::from_integer(self.numer.clone() / self.denom.clone())
+    }
+
+    /// Returns the fractional part of a number.
+    #[inline]
+    pub fn fract(&self) -> Ratio<T> {
+        Ratio::new_raw(self.numer.clone() % self.denom.clone(), self.denom.clone())
+    }
+}
+
+impl<T: Clone + Integer + PrimInt> Ratio<T> {
+    /// Raises the ratio to the power of an exponent
+    #[inline]
+    pub fn pow(&self, expon: i32) -> Ratio<T> {
+        match expon.cmp(&0) {
+            cmp::Ordering::Equal => One::one(),
+            cmp::Ordering::Less => self.recip().pow(-expon),
+            cmp::Ordering::Greater => {
+                Ratio::new_raw(self.numer.pow(expon as u32), self.denom.pow(expon as u32))
+            }
+        }
+    }
+}
+
+#[cfg(feature = "num-bigint")]
+impl Ratio<BigInt> {
+    /// Converts a float into a rational number.
+    pub fn from_float<T: Float>(f: T) -> Option<BigRational> {
+        if !f.is_finite() {
+            return None;
+        }
+        let (mantissa, exponent, sign) = f.integer_decode();
+        let bigint_sign = if sign == 1 {
+            Sign::Plus
+        } else {
+            Sign::Minus
+        };
+        if exponent < 0 {
+            let one: BigInt = One::one();
+            let denom: BigInt = one << ((-exponent) as usize);
+            let numer: BigUint = FromPrimitive::from_u64(mantissa).unwrap();
+            Some(Ratio::new(BigInt::from_biguint(bigint_sign, numer), denom))
+        } else {
+            let mut numer: BigUint = FromPrimitive::from_u64(mantissa).unwrap();
+            numer = numer << (exponent as usize);
+            Some(Ratio::from_integer(BigInt::from_biguint(bigint_sign, numer)))
+        }
+    }
+}
+
+// Comparisons
+
+// Mathematically, comparing a/b and c/d is the same as comparing a*d and b*c, but it's very easy
+// for those multiplications to overflow fixed-size integers, so we need to take care.
+
+impl<T: Clone + Integer> Ord for Ratio<T> {
+    #[inline]
+    fn cmp(&self, other: &Self) -> cmp::Ordering {
+        // With equal denominators, the numerators can be directly compared
+        if self.denom == other.denom {
+            let ord = self.numer.cmp(&other.numer);
+            return if self.denom < T::zero() {
+                ord.reverse()
+            } else {
+                ord
+            };
+        }
+
+        // With equal numerators, the denominators can be inversely compared
+        if self.numer == other.numer {
+            let ord = self.denom.cmp(&other.denom);
+            return if self.numer < T::zero() {
+                ord
+            } else {
+                ord.reverse()
+            };
+        }
+
+        // Unfortunately, we don't have CheckedMul to try.  That could sometimes avoid all the
+        // division below, or even always avoid it for BigInt and BigUint.
+        // FIXME- future breaking change to add Checked* to Integer?
+
+        // Compare as floored integers and remainders
+        let (self_int, self_rem) = self.numer.div_mod_floor(&self.denom);
+        let (other_int, other_rem) = other.numer.div_mod_floor(&other.denom);
+        match self_int.cmp(&other_int) {
+            cmp::Ordering::Greater => cmp::Ordering::Greater,
+            cmp::Ordering::Less => cmp::Ordering::Less,
+            cmp::Ordering::Equal => {
+                match (self_rem.is_zero(), other_rem.is_zero()) {
+                    (true, true) => cmp::Ordering::Equal,
+                    (true, false) => cmp::Ordering::Less,
+                    (false, true) => cmp::Ordering::Greater,
+                    (false, false) => {
+                        // Compare the reciprocals of the remaining fractions in reverse
+                        let self_recip = Ratio::new_raw(self.denom.clone(), self_rem);
+                        let other_recip = Ratio::new_raw(other.denom.clone(), other_rem);
+                        self_recip.cmp(&other_recip).reverse()
+                    }
+                }
+            }
+        }
+    }
+}
+
+impl<T: Clone + Integer> PartialOrd for Ratio<T> {
+    #[inline]
+    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+impl<T: Clone + Integer> PartialEq for Ratio<T> {
+    #[inline]
+    fn eq(&self, other: &Self) -> bool {
+        self.cmp(other) == cmp::Ordering::Equal
+    }
+}
+
+impl<T: Clone + Integer> Eq for Ratio<T> {}
+
+
+macro_rules! forward_val_val_binop {
+    (impl $imp:ident, $method:ident) => {
+        impl<T: Clone + Integer> $imp<Ratio<T>> for Ratio<T> {
+            type Output = Ratio<T>;
+
+            #[inline]
+            fn $method(self, other: Ratio<T>) -> Ratio<T> {
+                (&self).$method(&other)
+            }
+        }
+    }
+}
+
+macro_rules! forward_ref_val_binop {
+    (impl $imp:ident, $method:ident) => {
+        impl<'a, T> $imp<Ratio<T>> for &'a Ratio<T> where
+            T: Clone + Integer
+        {
+            type Output = Ratio<T>;
+
+            #[inline]
+            fn $method(self, other: Ratio<T>) -> Ratio<T> {
+                self.$method(&other)
+            }
+        }
+    }
+}
+
+macro_rules! forward_val_ref_binop {
+    (impl $imp:ident, $method:ident) => {
+        impl<'a, T> $imp<&'a Ratio<T>> for Ratio<T> where
+            T: Clone + Integer
+        {
+            type Output = Ratio<T>;
+
+            #[inline]
+            fn $method(self, other: &Ratio<T>) -> Ratio<T> {
+                (&self).$method(other)
+            }
+        }
+    }
+}
+
+macro_rules! forward_all_binop {
+    (impl $imp:ident, $method:ident) => {
+        forward_val_val_binop!(impl $imp, $method);
+        forward_ref_val_binop!(impl $imp, $method);
+        forward_val_ref_binop!(impl $imp, $method);
+    };
+}
+
+// Arithmetic
+forward_all_binop!(impl Mul, mul);
+// a/b * c/d = (a*c)/(b*d)
+impl<'a, 'b, T> Mul<&'b Ratio<T>> for &'a Ratio<T>
+    where T: Clone + Integer
+{
+    type Output = Ratio<T>;
+    #[inline]
+    fn mul(self, rhs: &Ratio<T>) -> Ratio<T> {
+        Ratio::new(self.numer.clone() * rhs.numer.clone(),
+                   self.denom.clone() * rhs.denom.clone())
+    }
+}
+
+forward_all_binop!(impl Div, div);
+// (a/b) / (c/d) = (a*d)/(b*c)
+impl<'a, 'b, T> Div<&'b Ratio<T>> for &'a Ratio<T>
+    where T: Clone + Integer
+{
+    type Output = Ratio<T>;
+
+    #[inline]
+    fn div(self, rhs: &Ratio<T>) -> Ratio<T> {
+        Ratio::new(self.numer.clone() * rhs.denom.clone(),
+                   self.denom.clone() * rhs.numer.clone())
+    }
+}
+
+// Abstracts the a/b `op` c/d = (a*d `op` b*d) / (b*d) pattern
+macro_rules! arith_impl {
+    (impl $imp:ident, $method:ident) => {
+        forward_all_binop!(impl $imp, $method);
+        impl<'a, 'b, T: Clone + Integer>
+            $imp<&'b Ratio<T>> for &'a Ratio<T> {
+            type Output = Ratio<T>;
+            #[inline]
+            fn $method(self, rhs: &Ratio<T>) -> Ratio<T> {
+                Ratio::new((self.numer.clone() * rhs.denom.clone()).$method(self.denom.clone() * rhs.numer.clone()),
+                           self.denom.clone() * rhs.denom.clone())
+            }
+        }
+    }
+}
+
+// a/b + c/d = (a*d + b*c)/(b*d)
+arith_impl!(impl Add, add);
+
+// a/b - c/d = (a*d - b*c)/(b*d)
+arith_impl!(impl Sub, sub);
+
+// a/b % c/d = (a*d % b*c)/(b*d)
+arith_impl!(impl Rem, rem);
+
+impl<T> Neg for Ratio<T>
+    where T: Clone + Integer + Neg<Output = T>
+{
+    type Output = Ratio<T>;
+
+    #[inline]
+    fn neg(self) -> Ratio<T> {
+        Ratio::new_raw(-self.numer, self.denom)
+    }
+}
+
+impl<'a, T> Neg for &'a Ratio<T>
+    where T: Clone + Integer + Neg<Output = T>
+{
+    type Output = Ratio<T>;
+
+    #[inline]
+    fn neg(self) -> Ratio<T> {
+        -self.clone()
+    }
+}
+
+// Constants
+impl<T: Clone + Integer> Zero for Ratio<T> {
+    #[inline]
+    fn zero() -> Ratio<T> {
+        Ratio::new_raw(Zero::zero(), One::one())
+    }
+
+    #[inline]
+    fn is_zero(&self) -> bool {
+        self.numer.is_zero()
+    }
+}
+
+impl<T: Clone + Integer> One for Ratio<T> {
+    #[inline]
+    fn one() -> Ratio<T> {
+        Ratio::new_raw(One::one(), One::one())
+    }
+}
+
+impl<T: Clone + Integer> Num for Ratio<T> {
+    type FromStrRadixErr = ParseRatioError;
+
+    /// Parses `numer/denom` where the numbers are in base `radix`.
+    fn from_str_radix(s: &str, radix: u32) -> Result<Ratio<T>, ParseRatioError> {
+        let split: Vec<&str> = s.splitn(2, '/').collect();
+        if split.len() < 2 {
+            Err(ParseRatioError { kind: RatioErrorKind::ParseError })
+        } else {
+            let a_result: Result<T, _> = T::from_str_radix(split[0], radix).map_err(|_| {
+                ParseRatioError { kind: RatioErrorKind::ParseError }
+            });
+            a_result.and_then(|a| {
+                let b_result: Result<T, _> = T::from_str_radix(split[1], radix).map_err(|_| {
+                    ParseRatioError { kind: RatioErrorKind::ParseError }
+                });
+                b_result.and_then(|b| {
+                    if b.is_zero() {
+                        Err(ParseRatioError { kind: RatioErrorKind::ZeroDenominator })
+                    } else {
+                        Ok(Ratio::new(a.clone(), b.clone()))
+                    }
+                })
+            })
+        }
+    }
+}
+
+impl<T: Clone + Integer + Signed> Signed for Ratio<T> {
+    #[inline]
+    fn abs(&self) -> Ratio<T> {
+        if self.is_negative() {
+            -self.clone()
+        } else {
+            self.clone()
+        }
+    }
+
+    #[inline]
+    fn abs_sub(&self, other: &Ratio<T>) -> Ratio<T> {
+        if *self <= *other {
+            Zero::zero()
+        } else {
+            self - other
+        }
+    }
+
+    #[inline]
+    fn signum(&self) -> Ratio<T> {
+        if self.is_positive() {
+            Self::one()
+        } else if self.is_zero() {
+            Self::zero()
+        } else {
+            -Self::one()
+        }
+    }
+
+    #[inline]
+    fn is_positive(&self) -> bool {
+        !self.is_negative()
+    }
+
+    #[inline]
+    fn is_negative(&self) -> bool {
+        self.numer.is_negative() ^ self.denom.is_negative()
+    }
+}
+
+// String conversions
+impl<T> fmt::Display for Ratio<T>
+    where T: fmt::Display + Eq + One
+{
+    /// Renders as `numer/denom`. If denom=1, renders as numer.
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        if self.denom == One::one() {
+            write!(f, "{}", self.numer)
+        } else {
+            write!(f, "{}/{}", self.numer, self.denom)
+        }
+    }
+}
+
+impl<T: FromStr + Clone + Integer> FromStr for Ratio<T> {
+    type Err = ParseRatioError;
+
+    /// Parses `numer/denom` or just `numer`.
+    fn from_str(s: &str) -> Result<Ratio<T>, ParseRatioError> {
+        let mut split = s.splitn(2, '/');
+
+        let n = try!(split.next().ok_or(ParseRatioError { kind: RatioErrorKind::ParseError }));
+        let num = try!(FromStr::from_str(n)
+                           .map_err(|_| ParseRatioError { kind: RatioErrorKind::ParseError }));
+
+        let d = split.next().unwrap_or("1");
+        let den = try!(FromStr::from_str(d)
+                           .map_err(|_| ParseRatioError { kind: RatioErrorKind::ParseError }));
+
+        if Zero::is_zero(&den) {
+            Err(ParseRatioError { kind: RatioErrorKind::ZeroDenominator })
+        } else {
+            Ok(Ratio::new(num, den))
+        }
+    }
+}
+
+#[cfg(feature = "serde")]
+impl<T> serde::Serialize for Ratio<T>
+    where T: serde::Serialize + Clone + Integer + PartialOrd
+{
+    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
+        where S: serde::Serializer
+    {
+        (self.numer(), self.denom()).serialize(serializer)
+    }
+}
+
+#[cfg(feature = "serde")]
+impl<T> serde::Deserialize for Ratio<T>
+    where T: serde::Deserialize + Clone + Integer + PartialOrd
+{
+    fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
+        where D: serde::Deserializer
+    {
+        let (numer, denom) = try!(serde::Deserialize::deserialize(deserializer));
+        if denom == Zero::zero() {
+            Err(serde::de::Error::invalid_value("denominator is zero"))
+        } else {
+            Ok(Ratio::new_raw(numer, denom))
+        }
+    }
+}
+
+// FIXME: Bubble up specific errors
+#[derive(Copy, Clone, Debug, PartialEq)]
+pub struct ParseRatioError {
+    kind: RatioErrorKind,
+}
+
+#[derive(Copy, Clone, Debug, PartialEq)]
+enum RatioErrorKind {
+    ParseError,
+    ZeroDenominator,
+}
+
+impl fmt::Display for ParseRatioError {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.description().fmt(f)
+    }
+}
+
+impl Error for ParseRatioError {
+    fn description(&self) -> &str {
+        self.kind.description()
+    }
+}
+
+impl RatioErrorKind {
+    fn description(&self) -> &'static str {
+        match *self {
+            RatioErrorKind::ParseError => "failed to parse integer",
+            RatioErrorKind::ZeroDenominator => "zero value denominator",
+        }
+    }
+}
+
+#[cfg(test)]
+fn hash<T: hash::Hash>(x: &T) -> u64 {
+    use std::hash::Hasher;
+    let mut hasher = hash::SipHasher::new();
+    x.hash(&mut hasher);
+    hasher.finish()
+}
+
+#[cfg(test)]
+mod test {
+    use super::{Ratio, Rational};
+    #[cfg(feature = "num-bigint")]
+    use super::BigRational;
+
+    use std::str::FromStr;
+    use std::i32;
+    use traits::{Zero, One, Signed, FromPrimitive, Float};
+
+    pub const _0: Rational = Ratio {
+        numer: 0,
+        denom: 1,
+    };
+    pub const _1: Rational = Ratio {
+        numer: 1,
+        denom: 1,
+    };
+    pub const _2: Rational = Ratio {
+        numer: 2,
+        denom: 1,
+    };
+    pub const _1_2: Rational = Ratio {
+        numer: 1,
+        denom: 2,
+    };
+    pub const _3_2: Rational = Ratio {
+        numer: 3,
+        denom: 2,
+    };
+    pub const _NEG1_2: Rational = Ratio {
+        numer: -1,
+        denom: 2,
+    };
+    pub const _1_3: Rational = Ratio {
+        numer: 1,
+        denom: 3,
+    };
+    pub const _NEG1_3: Rational = Ratio {
+        numer: -1,
+        denom: 3,
+    };
+    pub const _2_3: Rational = Ratio {
+        numer: 2,
+        denom: 3,
+    };
+    pub const _NEG2_3: Rational = Ratio {
+        numer: -2,
+        denom: 3,
+    };
+
+    #[cfg(feature = "num-bigint")]
+    pub fn to_big(n: Rational) -> BigRational {
+        Ratio::new(FromPrimitive::from_isize(n.numer).unwrap(),
+                   FromPrimitive::from_isize(n.denom).unwrap())
+    }
+    #[cfg(not(feature = "num-bigint"))]
+    pub fn to_big(n: Rational) -> Rational {
+        Ratio::new(FromPrimitive::from_isize(n.numer).unwrap(),
+                   FromPrimitive::from_isize(n.denom).unwrap())
+    }
+
+    #[test]
+    fn test_test_constants() {
+        // check our constants are what Ratio::new etc. would make.
+        assert_eq!(_0, Zero::zero());
+        assert_eq!(_1, One::one());
+        assert_eq!(_2, Ratio::from_integer(2));
+        assert_eq!(_1_2, Ratio::new(1, 2));
+        assert_eq!(_3_2, Ratio::new(3, 2));
+        assert_eq!(_NEG1_2, Ratio::new(-1, 2));
+    }
+
+    #[test]
+    fn test_new_reduce() {
+        let one22 = Ratio::new(2, 2);
+
+        assert_eq!(one22, One::one());
+    }
+    #[test]
+    #[should_panic]
+    fn test_new_zero() {
+        let _a = Ratio::new(1, 0);
+    }
+
+
+    #[test]
+    fn test_cmp() {
+        assert!(_0 == _0 && _1 == _1);
+        assert!(_0 != _1 && _1 != _0);
+        assert!(_0 < _1 && !(_1 < _0));
+        assert!(_1 > _0 && !(_0 > _1));
+
+        assert!(_0 <= _0 && _1 <= _1);
+        assert!(_0 <= _1 && !(_1 <= _0));
+
+        assert!(_0 >= _0 && _1 >= _1);
+        assert!(_1 >= _0 && !(_0 >= _1));
+    }
+
+    #[test]
+    fn test_cmp_overflow() {
+        use std::cmp::Ordering;
+
+        // issue #7 example:
+        let big = Ratio::new(128u8, 1);
+        let small = big.recip();
+        assert!(big > small);
+
+        // try a few that are closer together
+        // (some matching numer, some matching denom, some neither)
+        let ratios = vec![
+            Ratio::new(125_i8, 127_i8),
+            Ratio::new(63_i8, 64_i8),
+            Ratio::new(124_i8, 125_i8),
+            Ratio::new(125_i8, 126_i8),
+            Ratio::new(126_i8, 127_i8),
+            Ratio::new(127_i8, 126_i8),
+        ];
+
+        fn check_cmp(a: Ratio<i8>, b: Ratio<i8>, ord: Ordering) {
+            println!("comparing {} and {}", a, b);
+            assert_eq!(a.cmp(&b), ord);
+            assert_eq!(b.cmp(&a), ord.reverse());
+        }
+
+        for (i, &a) in ratios.iter().enumerate() {
+            check_cmp(a, a, Ordering::Equal);
+            check_cmp(-a, a, Ordering::Less);
+            for &b in &ratios[i + 1..] {
+                check_cmp(a, b, Ordering::Less);
+                check_cmp(-a, -b, Ordering::Greater);
+                check_cmp(a.recip(), b.recip(), Ordering::Greater);
+                check_cmp(-a.recip(), -b.recip(), Ordering::Less);
+            }
+        }
+    }
+
+    #[test]
+    fn test_to_integer() {
+        assert_eq!(_0.to_integer(), 0);
+        assert_eq!(_1.to_integer(), 1);
+        assert_eq!(_2.to_integer(), 2);
+        assert_eq!(_1_2.to_integer(), 0);
+        assert_eq!(_3_2.to_integer(), 1);
+        assert_eq!(_NEG1_2.to_integer(), 0);
+    }
+
+
+    #[test]
+    fn test_numer() {
+        assert_eq!(_0.numer(), &0);
+        assert_eq!(_1.numer(), &1);
+        assert_eq!(_2.numer(), &2);
+        assert_eq!(_1_2.numer(), &1);
+        assert_eq!(_3_2.numer(), &3);
+        assert_eq!(_NEG1_2.numer(), &(-1));
+    }
+    #[test]
+    fn test_denom() {
+        assert_eq!(_0.denom(), &1);
+        assert_eq!(_1.denom(), &1);
+        assert_eq!(_2.denom(), &1);
+        assert_eq!(_1_2.denom(), &2);
+        assert_eq!(_3_2.denom(), &2);
+        assert_eq!(_NEG1_2.denom(), &2);
+    }
+
+
+    #[test]
+    fn test_is_integer() {
+        assert!(_0.is_integer());
+        assert!(_1.is_integer());
+        assert!(_2.is_integer());
+        assert!(!_1_2.is_integer());
+        assert!(!_3_2.is_integer());
+        assert!(!_NEG1_2.is_integer());
+    }
+
+    #[test]
+    fn test_show() {
+        assert_eq!(format!("{}", _2), "2".to_string());
+        assert_eq!(format!("{}", _1_2), "1/2".to_string());
+        assert_eq!(format!("{}", _0), "0".to_string());
+        assert_eq!(format!("{}", Ratio::from_integer(-2)), "-2".to_string());
+    }
+
+    mod arith {
+        use super::{_0, _1, _2, _1_2, _3_2, _NEG1_2, to_big};
+        use super::super::{Ratio, Rational};
+
+        #[test]
+        fn test_add() {
+            fn test(a: Rational, b: Rational, c: Rational) {
+                assert_eq!(a + b, c);
+                assert_eq!(to_big(a) + to_big(b), to_big(c));
+            }
+
+            test(_1, _1_2, _3_2);
+            test(_1, _1, _2);
+            test(_1_2, _3_2, _2);
+            test(_1_2, _NEG1_2, _0);
+        }
+
+        #[test]
+        fn test_sub() {
+            fn test(a: Rational, b: Rational, c: Rational) {
+                assert_eq!(a - b, c);
+                assert_eq!(to_big(a) - to_big(b), to_big(c))
+            }
+
+            test(_1, _1_2, _1_2);
+            test(_3_2, _1_2, _1);
+            test(_1, _NEG1_2, _3_2);
+        }
+
+        #[test]
+        fn test_mul() {
+            fn test(a: Rational, b: Rational, c: Rational) {
+                assert_eq!(a * b, c);
+                assert_eq!(to_big(a) * to_big(b), to_big(c))
+            }
+
+            test(_1, _1_2, _1_2);
+            test(_1_2, _3_2, Ratio::new(3, 4));
+            test(_1_2, _NEG1_2, Ratio::new(-1, 4));
+        }
+
+        #[test]
+        fn test_div() {
+            fn test(a: Rational, b: Rational, c: Rational) {
+                assert_eq!(a / b, c);
+                assert_eq!(to_big(a) / to_big(b), to_big(c))
+            }
+
+            test(_1, _1_2, _2);
+            test(_3_2, _1_2, _1 + _2);
+            test(_1, _NEG1_2, _NEG1_2 + _NEG1_2 + _NEG1_2 + _NEG1_2);
+        }
+
+        #[test]
+        fn test_rem() {
+            fn test(a: Rational, b: Rational, c: Rational) {
+                assert_eq!(a % b, c);
+                assert_eq!(to_big(a) % to_big(b), to_big(c))
+            }
+
+            test(_3_2, _1, _1_2);
+            test(_2, _NEG1_2, _0);
+            test(_1_2, _2, _1_2);
+        }
+
+        #[test]
+        fn test_neg() {
+            fn test(a: Rational, b: Rational) {
+                assert_eq!(-a, b);
+                assert_eq!(-to_big(a), to_big(b))
+            }
+
+            test(_0, _0);
+            test(_1_2, _NEG1_2);
+            test(-_1, _1);
+        }
+        #[test]
+        fn test_zero() {
+            assert_eq!(_0 + _0, _0);
+            assert_eq!(_0 * _0, _0);
+            assert_eq!(_0 * _1, _0);
+            assert_eq!(_0 / _NEG1_2, _0);
+            assert_eq!(_0 - _0, _0);
+        }
+        #[test]
+        #[should_panic]
+        fn test_div_0() {
+            let _a = _1 / _0;
+        }
+    }
+
+    #[test]
+    fn test_round() {
+        assert_eq!(_1_3.ceil(), _1);
+        assert_eq!(_1_3.floor(), _0);
+        assert_eq!(_1_3.round(), _0);
+        assert_eq!(_1_3.trunc(), _0);
+
+        assert_eq!(_NEG1_3.ceil(), _0);
+        assert_eq!(_NEG1_3.floor(), -_1);
+        assert_eq!(_NEG1_3.round(), _0);
+        assert_eq!(_NEG1_3.trunc(), _0);
+
+        assert_eq!(_2_3.ceil(), _1);
+        assert_eq!(_2_3.floor(), _0);
+        assert_eq!(_2_3.round(), _1);
+        assert_eq!(_2_3.trunc(), _0);
+
+        assert_eq!(_NEG2_3.ceil(), _0);
+        assert_eq!(_NEG2_3.floor(), -_1);
+        assert_eq!(_NEG2_3.round(), -_1);
+        assert_eq!(_NEG2_3.trunc(), _0);
+
+        assert_eq!(_1_2.ceil(), _1);
+        assert_eq!(_1_2.floor(), _0);
+        assert_eq!(_1_2.round(), _1);
+        assert_eq!(_1_2.trunc(), _0);
+
+        assert_eq!(_NEG1_2.ceil(), _0);
+        assert_eq!(_NEG1_2.floor(), -_1);
+        assert_eq!(_NEG1_2.round(), -_1);
+        assert_eq!(_NEG1_2.trunc(), _0);
+
+        assert_eq!(_1.ceil(), _1);
+        assert_eq!(_1.floor(), _1);
+        assert_eq!(_1.round(), _1);
+        assert_eq!(_1.trunc(), _1);
+
+        // Overflow checks
+
+        let _neg1 = Ratio::from_integer(-1);
+        let _large_rat1 = Ratio::new(i32::MAX, i32::MAX - 1);
+        let _large_rat2 = Ratio::new(i32::MAX - 1, i32::MAX);
+        let _large_rat3 = Ratio::new(i32::MIN + 2, i32::MIN + 1);
+        let _large_rat4 = Ratio::new(i32::MIN + 1, i32::MIN + 2);
+        let _large_rat5 = Ratio::new(i32::MIN + 2, i32::MAX);
+        let _large_rat6 = Ratio::new(i32::MAX, i32::MIN + 2);
+        let _large_rat7 = Ratio::new(1, i32::MIN + 1);
+        let _large_rat8 = Ratio::new(1, i32::MAX);
+
+        assert_eq!(_large_rat1.round(), One::one());
+        assert_eq!(_large_rat2.round(), One::one());
+        assert_eq!(_large_rat3.round(), One::one());
+        assert_eq!(_large_rat4.round(), One::one());
+        assert_eq!(_large_rat5.round(), _neg1);
+        assert_eq!(_large_rat6.round(), _neg1);
+        assert_eq!(_large_rat7.round(), Zero::zero());
+        assert_eq!(_large_rat8.round(), Zero::zero());
+    }
+
+    #[test]
+    fn test_fract() {
+        assert_eq!(_1.fract(), _0);
+        assert_eq!(_NEG1_2.fract(), _NEG1_2);
+        assert_eq!(_1_2.fract(), _1_2);
+        assert_eq!(_3_2.fract(), _1_2);
+    }
+
+    #[test]
+    fn test_recip() {
+        assert_eq!(_1 * _1.recip(), _1);
+        assert_eq!(_2 * _2.recip(), _1);
+        assert_eq!(_1_2 * _1_2.recip(), _1);
+        assert_eq!(_3_2 * _3_2.recip(), _1);
+        assert_eq!(_NEG1_2 * _NEG1_2.recip(), _1);
+    }
+
+    #[test]
+    fn test_pow() {
+        assert_eq!(_1_2.pow(2), Ratio::new(1, 4));
+        assert_eq!(_1_2.pow(-2), Ratio::new(4, 1));
+        assert_eq!(_1.pow(1), _1);
+        assert_eq!(_NEG1_2.pow(2), _1_2.pow(2));
+        assert_eq!(_NEG1_2.pow(3), -_1_2.pow(3));
+        assert_eq!(_3_2.pow(0), _1);
+        assert_eq!(_3_2.pow(-1), _3_2.recip());
+        assert_eq!(_3_2.pow(3), Ratio::new(27, 8));
+    }
+
+    #[test]
+    fn test_to_from_str() {
+        fn test(r: Rational, s: String) {
+            assert_eq!(FromStr::from_str(&s), Ok(r));
+            assert_eq!(r.to_string(), s);
+        }
+        test(_1, "1".to_string());
+        test(_0, "0".to_string());
+        test(_1_2, "1/2".to_string());
+        test(_3_2, "3/2".to_string());
+        test(_2, "2".to_string());
+        test(_NEG1_2, "-1/2".to_string());
+    }
+    #[test]
+    fn test_from_str_fail() {
+        fn test(s: &str) {
+            let rational: Result<Rational, _> = FromStr::from_str(s);
+            assert!(rational.is_err());
+        }
+
+        let xs = ["0 /1", "abc", "", "1/", "--1/2", "3/2/1", "1/0"];
+        for &s in xs.iter() {
+            test(s);
+        }
+    }
+
+    #[cfg(feature = "num-bigint")]
+    #[test]
+    fn test_from_float() {
+        fn test<T: Float>(given: T, (numer, denom): (&str, &str)) {
+            let ratio: BigRational = Ratio::from_float(given).unwrap();
+            assert_eq!(ratio,
+                       Ratio::new(FromStr::from_str(numer).unwrap(),
+                                  FromStr::from_str(denom).unwrap()));
+        }
+
+        // f32
+        test(3.14159265359f32, ("13176795", "4194304"));
+        test(2f32.powf(100.), ("1267650600228229401496703205376", "1"));
+        test(-2f32.powf(100.), ("-1267650600228229401496703205376", "1"));
+        test(1.0 / 2f32.powf(100.),
+             ("1", "1267650600228229401496703205376"));
+        test(684729.48391f32, ("1369459", "2"));
+        test(-8573.5918555f32, ("-4389679", "512"));
+
+        // f64
+        test(3.14159265359f64, ("3537118876014453", "1125899906842624"));
+        test(2f64.powf(100.), ("1267650600228229401496703205376", "1"));
+        test(-2f64.powf(100.), ("-1267650600228229401496703205376", "1"));
+        test(684729.48391f64, ("367611342500051", "536870912"));
+        test(-8573.5918555f64, ("-4713381968463931", "549755813888"));
+        test(1.0 / 2f64.powf(100.),
+             ("1", "1267650600228229401496703205376"));
+    }
+
+    #[cfg(feature = "num-bigint")]
+    #[test]
+    fn test_from_float_fail() {
+        use std::{f32, f64};
+
+        assert_eq!(Ratio::from_float(f32::NAN), None);
+        assert_eq!(Ratio::from_float(f32::INFINITY), None);
+        assert_eq!(Ratio::from_float(f32::NEG_INFINITY), None);
+        assert_eq!(Ratio::from_float(f64::NAN), None);
+        assert_eq!(Ratio::from_float(f64::INFINITY), None);
+        assert_eq!(Ratio::from_float(f64::NEG_INFINITY), None);
+    }
+
+    #[test]
+    fn test_signed() {
+        assert_eq!(_NEG1_2.abs(), _1_2);
+        assert_eq!(_3_2.abs_sub(&_1_2), _1);
+        assert_eq!(_1_2.abs_sub(&_3_2), Zero::zero());
+        assert_eq!(_1_2.signum(), One::one());
+        assert_eq!(_NEG1_2.signum(), -<Ratio<isize>>::one());
+        assert!(_NEG1_2.is_negative());
+        assert!(!_NEG1_2.is_positive());
+        assert!(!_1_2.is_negative());
+    }
+
+    #[test]
+    fn test_hash() {
+        assert!(::hash(&_0) != ::hash(&_1));
+        assert!(::hash(&_0) != ::hash(&_3_2));
+    }
+}

+ 12 - 17
src/lib.rs

@@ -59,7 +59,10 @@
 
 extern crate num_traits;
 extern crate num_integer;
+#[cfg(feature = "num-bigint")]
 extern crate num_bigint;
+#[cfg(feature = "num-rational")]
+extern crate num_rational;
 
 #[cfg(feature = "rustc-serialize")]
 extern crate rustc_serialize;
@@ -73,11 +76,11 @@ extern crate rand;
 #[cfg(feature = "serde")]
 extern crate serde;
 
-#[cfg(feature = "bigint")]
+#[cfg(feature = "num-bigint")]
 pub use bigint::{BigInt, BigUint};
-#[cfg(feature = "rational")]
+#[cfg(feature = "num-rational")]
 pub use rational::Rational;
-#[cfg(all(feature = "rational", feature="bigint"))]
+#[cfg(all(feature = "num-rational", feature="num-bigint"))]
 pub use rational::BigRational;
 #[cfg(feature = "complex")]
 pub use complex::Complex;
@@ -91,14 +94,14 @@ pub use traits::{Num, Zero, One, Signed, Unsigned, Bounded,
 
 use std::ops::{Mul};
 
-#[cfg(feature = "bigint")]
-pub mod bigint { pub use num_bigint::*; }
+#[cfg(feature = "num-bigint")]
+pub use num_bigint as bigint;
 pub mod complex;
-pub mod integer { pub use num_integer::*; }
+pub use num_integer as integers;
 pub mod iter;
-pub mod traits { pub use num_traits::*; }
-#[cfg(feature = "rational")]
-pub mod rational;
+pub use num_traits as traits;
+#[cfg(feature = "num-rational")]
+pub use num_rational as rational;
 
 /// Returns the additive identity, `0`.
 #[inline(always)] pub fn zero<T: Zero>() -> T { Zero::zero() }
@@ -210,11 +213,3 @@ pub fn checked_pow<T: Clone + One + CheckedMul>(mut base: T, mut exp: usize) ->
     }
     Some(acc)
 }
-
-#[cfg(test)]
-fn hash<T: hash::Hash>(x: &T) -> u64 {
-    use std::hash::Hasher;
-    let mut hasher = hash::SipHasher::new();
-    x.hash(&mut hasher);
-    hasher.finish()
-}

+ 1 - 2
traits/src/cast.rs

@@ -388,8 +388,7 @@ impl_from_primitive!(f64,   to_f64);
 /// # Examples
 ///
 /// ```
-/// use num;
-///
+/// # use num_traits as num;
 /// let twenty: f32 = num::cast(0x14).unwrap();
 /// assert_eq!(twenty, 20f32);
 /// ```

+ 54 - 54
traits/src/float.rs

@@ -14,7 +14,7 @@ pub trait Float
     /// Returns the `NaN` value.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     ///
     /// let nan: f32 = Float::nan();
     ///
@@ -24,7 +24,7 @@ pub trait Float
     /// Returns the infinite value.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     /// use std::f32;
     ///
     /// let infinity: f32 = Float::infinity();
@@ -37,7 +37,7 @@ pub trait Float
     /// Returns the negative infinite value.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     /// use std::f32;
     ///
     /// let neg_infinity: f32 = Float::neg_infinity();
@@ -50,7 +50,7 @@ pub trait Float
     /// Returns `-0.0`.
     ///
     /// ```
-    /// use num::traits::{Zero, Float};
+    /// use num_traits::{Zero, Float};
     ///
     /// let inf: f32 = Float::infinity();
     /// let zero: f32 = Zero::zero();
@@ -65,7 +65,7 @@ pub trait Float
     /// Returns the smallest finite value that this type can represent.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     /// use std::f64;
     ///
     /// let x: f64 = Float::min_value();
@@ -77,7 +77,7 @@ pub trait Float
     /// Returns the smallest positive, normalized value that this type can represent.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     /// use std::f64;
     ///
     /// let x: f64 = Float::min_positive_value();
@@ -89,7 +89,7 @@ pub trait Float
     /// Returns the largest finite value that this type can represent.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     /// use std::f64;
     ///
     /// let x: f64 = Float::max_value();
@@ -100,7 +100,7 @@ pub trait Float
     /// Returns `true` if this value is `NaN` and false otherwise.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     /// use std::f64;
     ///
     /// let nan = f64::NAN;
@@ -115,7 +115,7 @@ pub trait Float
     /// false otherwise.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     /// use std::f32;
     ///
     /// let f = 7.0f32;
@@ -134,7 +134,7 @@ pub trait Float
     /// Returns `true` if this number is neither infinite nor `NaN`.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     /// use std::f32;
     ///
     /// let f = 7.0f32;
@@ -154,7 +154,7 @@ pub trait Float
     /// [subnormal][subnormal], or `NaN`.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     /// use std::f32;
     ///
     /// let min = f32::MIN_POSITIVE; // 1.17549435e-38f32
@@ -179,7 +179,7 @@ pub trait Float
     /// predicate instead.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     /// use std::num::FpCategory;
     /// use std::f32;
     ///
@@ -194,7 +194,7 @@ pub trait Float
     /// Returns the largest integer less than or equal to a number.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     ///
     /// let f = 3.99;
     /// let g = 3.0;
@@ -207,7 +207,7 @@ pub trait Float
     /// Returns the smallest integer greater than or equal to a number.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     ///
     /// let f = 3.01;
     /// let g = 4.0;
@@ -221,7 +221,7 @@ pub trait Float
     /// `0.0`.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     ///
     /// let f = 3.3;
     /// let g = -3.3;
@@ -234,7 +234,7 @@ pub trait Float
     /// Return the integer part of a number.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     ///
     /// let f = 3.3;
     /// let g = -3.7;
@@ -247,7 +247,7 @@ pub trait Float
     /// Returns the fractional part of a number.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     ///
     /// let x = 3.5;
     /// let y = -3.5;
@@ -263,7 +263,7 @@ pub trait Float
     /// number is `Float::nan()`.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     /// use std::f64;
     ///
     /// let x = 3.5;
@@ -286,7 +286,7 @@ pub trait Float
     /// - `Float::nan()` if the number is `Float::nan()`
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     /// use std::f64;
     ///
     /// let f = 3.5;
@@ -302,7 +302,7 @@ pub trait Float
     /// `Float::infinity()`.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     /// use std::f64;
     ///
     /// let nan: f64 = f64::NAN;
@@ -321,7 +321,7 @@ pub trait Float
     /// `Float::neg_infinity()`.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     /// use std::f64;
     ///
     /// let nan = f64::NAN;
@@ -341,7 +341,7 @@ pub trait Float
     /// a separate multiplication operation followed by an add.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     ///
     /// let m = 10.0;
     /// let x = 4.0;
@@ -356,7 +356,7 @@ pub trait Float
     /// Take the reciprocal (inverse) of a number, `1/x`.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     ///
     /// let x = 2.0;
     /// let abs_difference = (x.recip() - (1.0/x)).abs();
@@ -370,7 +370,7 @@ pub trait Float
     /// Using this function is generally faster than using `powf`
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     ///
     /// let x = 2.0;
     /// let abs_difference = (x.powi(2) - x*x).abs();
@@ -382,7 +382,7 @@ pub trait Float
     /// Raise a number to a floating point power.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     ///
     /// let x = 2.0;
     /// let abs_difference = (x.powf(2.0) - x*x).abs();
@@ -396,7 +396,7 @@ pub trait Float
     /// Returns NaN if `self` is a negative number.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     ///
     /// let positive = 4.0;
     /// let negative = -4.0;
@@ -411,7 +411,7 @@ pub trait Float
     /// Returns `e^(self)`, (the exponential function).
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     ///
     /// let one = 1.0;
     /// // e^1
@@ -427,7 +427,7 @@ pub trait Float
     /// Returns `2^(self)`.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     ///
     /// let f = 2.0;
     ///
@@ -441,7 +441,7 @@ pub trait Float
     /// Returns the natural logarithm of the number.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     ///
     /// let one = 1.0;
     /// // e^1
@@ -457,7 +457,7 @@ pub trait Float
     /// Returns the logarithm of the number with respect to an arbitrary base.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     ///
     /// let ten = 10.0;
     /// let two = 2.0;
@@ -476,7 +476,7 @@ pub trait Float
     /// Returns the base 2 logarithm of the number.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     ///
     /// let two = 2.0;
     ///
@@ -490,7 +490,7 @@ pub trait Float
     /// Returns the base 10 logarithm of the number.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     ///
     /// let ten = 10.0;
     ///
@@ -504,7 +504,7 @@ pub trait Float
     /// Returns the maximum of the two numbers.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     ///
     /// let x = 1.0;
     /// let y = 2.0;
@@ -516,7 +516,7 @@ pub trait Float
     /// Returns the minimum of the two numbers.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     ///
     /// let x = 1.0;
     /// let y = 2.0;
@@ -531,7 +531,7 @@ pub trait Float
     /// * Else: `self - other`
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     ///
     /// let x = 3.0;
     /// let y = -3.0;
@@ -547,7 +547,7 @@ pub trait Float
     /// Take the cubic root of a number.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     ///
     /// let x = 8.0;
     ///
@@ -562,7 +562,7 @@ pub trait Float
     /// legs of length `x` and `y`.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     ///
     /// let x = 2.0;
     /// let y = 3.0;
@@ -577,7 +577,7 @@ pub trait Float
     /// Computes the sine of a number (in radians).
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     /// use std::f64;
     ///
     /// let x = f64::consts::PI/2.0;
@@ -591,7 +591,7 @@ pub trait Float
     /// Computes the cosine of a number (in radians).
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     /// use std::f64;
     ///
     /// let x = 2.0*f64::consts::PI;
@@ -605,7 +605,7 @@ pub trait Float
     /// Computes the tangent of a number (in radians).
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     /// use std::f64;
     ///
     /// let x = f64::consts::PI/4.0;
@@ -620,7 +620,7 @@ pub trait Float
     /// [-1, 1].
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     /// use std::f64;
     ///
     /// let f = f64::consts::PI / 2.0;
@@ -637,7 +637,7 @@ pub trait Float
     /// [-1, 1].
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     /// use std::f64;
     ///
     /// let f = f64::consts::PI / 4.0;
@@ -653,7 +653,7 @@ pub trait Float
     /// range [-pi/2, pi/2];
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     ///
     /// let f = 1.0;
     ///
@@ -672,7 +672,7 @@ pub trait Float
     /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     /// use std::f64;
     ///
     /// let pi = f64::consts::PI;
@@ -697,7 +697,7 @@ pub trait Float
     /// `(sin(x), cos(x))`.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     /// use std::f64;
     ///
     /// let x = f64::consts::PI/4.0;
@@ -715,7 +715,7 @@ pub trait Float
     /// number is close to zero.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     ///
     /// let x = 7.0;
     ///
@@ -730,7 +730,7 @@ pub trait Float
     /// the operations were performed separately.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     /// use std::f64;
     ///
     /// let x = f64::consts::E - 1.0;
@@ -745,7 +745,7 @@ pub trait Float
     /// Hyperbolic sine function.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     /// use std::f64;
     ///
     /// let e = f64::consts::E;
@@ -763,7 +763,7 @@ pub trait Float
     /// Hyperbolic cosine function.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     /// use std::f64;
     ///
     /// let e = f64::consts::E;
@@ -781,7 +781,7 @@ pub trait Float
     /// Hyperbolic tangent function.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     /// use std::f64;
     ///
     /// let e = f64::consts::E;
@@ -799,7 +799,7 @@ pub trait Float
     /// Inverse hyperbolic sine function.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     ///
     /// let x = 1.0;
     /// let f = x.sinh().asinh();
@@ -813,7 +813,7 @@ pub trait Float
     /// Inverse hyperbolic cosine function.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     ///
     /// let x = 1.0;
     /// let f = x.cosh().acosh();
@@ -827,7 +827,7 @@ pub trait Float
     /// Inverse hyperbolic tangent function.
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     /// use std::f64;
     ///
     /// let e = f64::consts::E;
@@ -845,7 +845,7 @@ pub trait Float
     /// The floating point encoding is documented in the [Reference][floating-point].
     ///
     /// ```
-    /// use num::traits::Float;
+    /// use num_traits::Float;
     ///
     /// let num = 2.0f32;
     ///

+ 16 - 16
traits/src/int.rs

@@ -28,7 +28,7 @@ pub trait PrimInt
     /// # Examples
     ///
     /// ```
-    /// use num::traits::PrimInt;
+    /// use num_traits::PrimInt;
     ///
     /// let n = 0b01001100u8;
     ///
@@ -41,7 +41,7 @@ pub trait PrimInt
     /// # Examples
     ///
     /// ```
-    /// use num::traits::PrimInt;
+    /// use num_traits::PrimInt;
     ///
     /// let n = 0b01001100u8;
     ///
@@ -55,7 +55,7 @@ pub trait PrimInt
     /// # Examples
     ///
     /// ```
-    /// use num::traits::PrimInt;
+    /// use num_traits::PrimInt;
     ///
     /// let n = 0b0101000u16;
     ///
@@ -69,7 +69,7 @@ pub trait PrimInt
     /// # Examples
     ///
     /// ```
-    /// use num::traits::PrimInt;
+    /// use num_traits::PrimInt;
     ///
     /// let n = 0b0101000u16;
     ///
@@ -83,7 +83,7 @@ pub trait PrimInt
     /// # Examples
     ///
     /// ```
-    /// use num::traits::PrimInt;
+    /// use num_traits::PrimInt;
     ///
     /// let n = 0x0123456789ABCDEFu64;
     /// let m = 0x3456789ABCDEF012u64;
@@ -98,7 +98,7 @@ pub trait PrimInt
     /// # Examples
     ///
     /// ```
-    /// use num::traits::PrimInt;
+    /// use num_traits::PrimInt;
     ///
     /// let n = 0x0123456789ABCDEFu64;
     /// let m = 0xDEF0123456789ABCu64;
@@ -115,7 +115,7 @@ pub trait PrimInt
     /// # Examples
     ///
     /// ```
-    /// use num::traits::PrimInt;
+    /// use num_traits::PrimInt;
     ///
     /// let n = 0x0123456789ABCDEFu64;
     /// let m = 0x3456789ABCDEF000u64;
@@ -132,7 +132,7 @@ pub trait PrimInt
     /// # Examples
     ///
     /// ```
-    /// use num::traits::PrimInt;
+    /// use num_traits::PrimInt;
     ///
     /// let n = 0xFEDCBA9876543210u64;
     /// let m = 0xFFFFEDCBA9876543u64;
@@ -149,7 +149,7 @@ pub trait PrimInt
     /// # Examples
     ///
     /// ```
-    /// use num::traits::PrimInt;
+    /// use num_traits::PrimInt;
     ///
     /// let n = 0x0123456789ABCDEFi64;
     /// let m = 0x3456789ABCDEF000i64;
@@ -166,7 +166,7 @@ pub trait PrimInt
     /// # Examples
     ///
     /// ```
-    /// use num::traits::PrimInt;
+    /// use num_traits::PrimInt;
     ///
     /// let n = 0xFEDCBA9876543210i64;
     /// let m = 0x000FEDCBA9876543i64;
@@ -180,7 +180,7 @@ pub trait PrimInt
     /// # Examples
     ///
     /// ```
-    /// use num::traits::PrimInt;
+    /// use num_traits::PrimInt;
     ///
     /// let n = 0x0123456789ABCDEFu64;
     /// let m = 0xEFCDAB8967452301u64;
@@ -196,7 +196,7 @@ pub trait PrimInt
     /// # Examples
     ///
     /// ```
-    /// use num::traits::PrimInt;
+    /// use num_traits::PrimInt;
     ///
     /// let n = 0x0123456789ABCDEFu64;
     ///
@@ -215,7 +215,7 @@ pub trait PrimInt
     /// # Examples
     ///
     /// ```
-    /// use num::traits::PrimInt;
+    /// use num_traits::PrimInt;
     ///
     /// let n = 0x0123456789ABCDEFu64;
     ///
@@ -234,7 +234,7 @@ pub trait PrimInt
     /// # Examples
     ///
     /// ```
-    /// use num::traits::PrimInt;
+    /// use num_traits::PrimInt;
     ///
     /// let n = 0x0123456789ABCDEFu64;
     ///
@@ -253,7 +253,7 @@ pub trait PrimInt
     /// # Examples
     ///
     /// ```
-    /// use num::traits::PrimInt;
+    /// use num_traits::PrimInt;
     ///
     /// let n = 0x0123456789ABCDEFu64;
     ///
@@ -270,7 +270,7 @@ pub trait PrimInt
     /// # Examples
     ///
     /// ```
-    /// use num::traits::PrimInt;
+    /// use num_traits::PrimInt;
     ///
     /// assert_eq!(2i32.pow(4), 16);
     /// ```