mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-15 18:15:01 +00:00
std: Replace num::IntConvertible with {To,From}Primitive
This commit is contained in:
parent
17548378a7
commit
d9d1dfc195
@ -22,7 +22,8 @@ A `BigInt` is a combination of `BigUint` and `Sign`.
|
||||
use std::cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater};
|
||||
use std::int;
|
||||
use std::num;
|
||||
use std::num::{IntConvertible, Zero, One, ToStrRadix, FromStrRadix, Orderable};
|
||||
use std::num::{Zero, One, ToStrRadix, FromStrRadix, Orderable};
|
||||
use std::num::{ToPrimitive, FromPrimitive};
|
||||
use std::rand::Rng;
|
||||
use std::str;
|
||||
use std::uint;
|
||||
@ -500,15 +501,49 @@ impl Integer for BigUint {
|
||||
fn is_odd(&self) -> bool { !self.is_even() }
|
||||
}
|
||||
|
||||
impl IntConvertible for BigUint {
|
||||
impl ToPrimitive for BigUint {
|
||||
#[inline]
|
||||
fn to_int(&self) -> int {
|
||||
self.to_int_opt().expect("BigUint conversion would overflow int")
|
||||
fn to_int(&self) -> Option<int> {
|
||||
do self.to_uint().and_then |n| {
|
||||
// If top bit of uint is set, it's too large to convert to
|
||||
// int.
|
||||
if (n >> (2*BigDigit::bits - 1) != 0) {
|
||||
None
|
||||
} else {
|
||||
Some(n as int)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_int(n: int) -> BigUint {
|
||||
if (n < 0) { Zero::zero() } else { BigUint::from_uint(n as uint) }
|
||||
fn to_uint(&self) -> Option<uint> {
|
||||
match self.data.len() {
|
||||
0 => Some(0),
|
||||
1 => Some(self.data[0] as uint),
|
||||
2 => Some(BigDigit::to_uint(self.data[1], self.data[0])),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromPrimitive for BigUint {
|
||||
#[inline]
|
||||
fn from_int(n: int) -> Option<BigUint> {
|
||||
if (n < 0) {
|
||||
Some(Zero::zero())
|
||||
} else {
|
||||
FromPrimitive::from_uint(n as uint)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_uint(n: uint) -> Option<BigUint> {
|
||||
let n = match BigDigit::from_uint(n) {
|
||||
(0, 0) => Zero::zero(),
|
||||
(0, n0) => BigUint::new(~[n0]),
|
||||
(n1, n0) => BigUint::new(~[n0, n1])
|
||||
};
|
||||
Some(n)
|
||||
}
|
||||
}
|
||||
|
||||
@ -522,16 +557,16 @@ impl ToStrRadix for BigUint {
|
||||
return fill_concat(convert_base((*self).clone(), base), radix, max_len);
|
||||
|
||||
fn convert_base(n: BigUint, base: uint) -> ~[BigDigit] {
|
||||
let divider = BigUint::from_uint(base);
|
||||
let divider = FromPrimitive::from_uint(base).unwrap();
|
||||
let mut result = ~[];
|
||||
let mut m = n;
|
||||
while m > divider {
|
||||
let (d, m0) = m.div_mod_floor(÷r);
|
||||
result.push(m0.to_uint() as BigDigit);
|
||||
result.push(m0.to_uint().unwrap() as BigDigit);
|
||||
m = d;
|
||||
}
|
||||
if !m.is_zero() {
|
||||
result.push(m.to_uint() as BigDigit);
|
||||
result.push(m.to_uint().unwrap() as BigDigit);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -571,16 +606,6 @@ impl BigUint {
|
||||
return BigUint { data: v };
|
||||
}
|
||||
|
||||
/// Creates and initializes a `BigUint`.
|
||||
#[inline]
|
||||
pub fn from_uint(n: uint) -> BigUint {
|
||||
match BigDigit::from_uint(n) {
|
||||
(0, 0) => Zero::zero(),
|
||||
(0, n0) => BigUint::new(~[n0]),
|
||||
(n1, n0) => BigUint::new(~[n0, n1])
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates and initializes a `BigUint`.
|
||||
#[inline]
|
||||
pub fn from_slice(slice: &[BigDigit]) -> BigUint {
|
||||
@ -588,10 +613,12 @@ impl BigUint {
|
||||
}
|
||||
|
||||
/// Creates and initializes a `BigUint`.
|
||||
pub fn parse_bytes(buf: &[u8], radix: uint)
|
||||
-> Option<BigUint> {
|
||||
pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<BigUint> {
|
||||
let (base, unit_len) = get_radix_base(radix);
|
||||
let base_num: BigUint = BigUint::from_uint(base);
|
||||
let base_num = match FromPrimitive::from_uint(base) {
|
||||
Some(base_num) => base_num,
|
||||
None => { return None; }
|
||||
};
|
||||
|
||||
let mut end = buf.len();
|
||||
let mut n: BigUint = Zero::zero();
|
||||
@ -599,10 +626,19 @@ impl BigUint {
|
||||
loop {
|
||||
let start = num::max(end, unit_len) - unit_len;
|
||||
match uint::parse_bytes(buf.slice(start, end), radix) {
|
||||
// FIXME(#6102): Assignment operator for BigInt causes ICE
|
||||
// Some(d) => n += BigUint::from_uint(d) * power,
|
||||
Some(d) => n = n + BigUint::from_uint(d) * power,
|
||||
None => return None
|
||||
Some(d) => {
|
||||
let d: Option<BigUint> = FromPrimitive::from_uint(d);
|
||||
match d {
|
||||
Some(d) => {
|
||||
// FIXME(#6102): Assignment operator for BigInt
|
||||
// causes ICE:
|
||||
// n += d * power;
|
||||
n = n + d * power;
|
||||
}
|
||||
None => { return None; }
|
||||
}
|
||||
}
|
||||
None => { return None; }
|
||||
}
|
||||
if end <= unit_len {
|
||||
return Some(n);
|
||||
@ -614,39 +650,7 @@ impl BigUint {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Converts this `BigUint` into a `uint`, failing if the conversion
|
||||
/// would overflow.
|
||||
#[inline]
|
||||
pub fn to_uint(&self) -> uint {
|
||||
self.to_uint_opt().expect("BigUint conversion would overflow uint")
|
||||
}
|
||||
|
||||
/// Converts this `BigUint` into a `uint`, unless it would overflow.
|
||||
#[inline]
|
||||
pub fn to_uint_opt(&self) -> Option<uint> {
|
||||
match self.data.len() {
|
||||
0 => Some(0),
|
||||
1 => Some(self.data[0] as uint),
|
||||
2 => Some(BigDigit::to_uint(self.data[1], self.data[0])),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts this `BigUint` into an `int`, unless it would overflow.
|
||||
pub fn to_int_opt(&self) -> Option<int> {
|
||||
self.to_uint_opt().and_then(|n| {
|
||||
// If top bit of uint is set, it's too large to convert to
|
||||
// int.
|
||||
if (n >> (2*BigDigit::bits - 1) != 0) {
|
||||
None
|
||||
} else {
|
||||
Some(n as int)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Converts this `BigUint` into a `BigInt`.
|
||||
/// Converts this `BigUint` into a `BigInt.
|
||||
#[inline]
|
||||
pub fn to_bigint(&self) -> BigInt {
|
||||
BigInt::from_biguint(Plus, self.clone())
|
||||
@ -1077,23 +1081,62 @@ impl Integer for BigInt {
|
||||
fn is_odd(&self) -> bool { self.data.is_odd() }
|
||||
}
|
||||
|
||||
impl IntConvertible for BigInt {
|
||||
impl ToPrimitive for BigInt {
|
||||
#[inline]
|
||||
fn to_int(&self) -> int {
|
||||
self.to_int_opt().expect("BigInt conversion would overflow int")
|
||||
fn to_int(&self) -> Option<int> {
|
||||
match self.sign {
|
||||
Plus => self.data.to_int(),
|
||||
Zero => Some(0),
|
||||
Minus => {
|
||||
do self.data.to_uint().and_then |n| {
|
||||
let m: uint = 1 << (2*BigDigit::bits-1);
|
||||
if (n > m) {
|
||||
None
|
||||
} else if (n == m) {
|
||||
Some(int::min_value)
|
||||
} else {
|
||||
Some(-(n as int))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_int(n: int) -> BigInt {
|
||||
fn to_uint(&self) -> Option<uint> {
|
||||
match self.sign {
|
||||
Plus => self.data.to_uint(),
|
||||
Zero => Some(0),
|
||||
Minus => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromPrimitive for BigInt {
|
||||
#[inline]
|
||||
fn from_int(n: int) -> Option<BigInt> {
|
||||
if n > 0 {
|
||||
return BigInt::from_biguint(Plus, BigUint::from_uint(n as uint));
|
||||
do FromPrimitive::from_uint(n as uint).and_then |n| {
|
||||
Some(BigInt::from_biguint(Plus, n))
|
||||
}
|
||||
} else if n < 0 {
|
||||
do FromPrimitive::from_uint(uint::max_value - (n as uint) + 1).and_then |n| {
|
||||
Some(BigInt::from_biguint(Minus, n))
|
||||
}
|
||||
} else {
|
||||
Some(Zero::zero())
|
||||
}
|
||||
if n < 0 {
|
||||
return BigInt::from_biguint(
|
||||
Minus, BigUint::from_uint(uint::max_value - (n as uint) + 1)
|
||||
);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_uint(n: uint) -> Option<BigInt> {
|
||||
if n == 0 {
|
||||
Some(Zero::zero())
|
||||
} else {
|
||||
do FromPrimitive::from_uint(n).and_then |n| {
|
||||
Some(BigInt::from_biguint(Plus, n))
|
||||
}
|
||||
}
|
||||
return Zero::zero();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1196,7 +1239,7 @@ impl<R: Rng> RandBigInt for R {
|
||||
ubound: &BigInt)
|
||||
-> BigInt {
|
||||
assert!(*lbound < *ubound);
|
||||
let delta = (*ubound - *lbound).to_biguint();
|
||||
let delta = (*ubound - *lbound).to_biguint().unwrap();
|
||||
return *lbound + self.gen_biguint_below(&delta).to_bigint();
|
||||
}
|
||||
}
|
||||
@ -1217,13 +1260,6 @@ impl BigInt {
|
||||
return BigInt { sign: sign, data: data };
|
||||
}
|
||||
|
||||
/// Creates and initializes a `BigInt`.
|
||||
#[inline]
|
||||
pub fn from_uint(n: uint) -> BigInt {
|
||||
if n == 0 { return Zero::zero(); }
|
||||
return BigInt::from_biguint(Plus, BigUint::from_uint(n));
|
||||
}
|
||||
|
||||
/// Creates and initializes a `BigInt`.
|
||||
#[inline]
|
||||
pub fn from_slice(sign: Sign, slice: &[BigDigit]) -> BigInt {
|
||||
@ -1244,51 +1280,9 @@ impl BigInt {
|
||||
.map_move(|bu| BigInt::from_biguint(sign, bu));
|
||||
}
|
||||
|
||||
/// Converts this `BigInt` into a `uint`, failing if the conversion
|
||||
/// would overflow.
|
||||
#[inline]
|
||||
pub fn to_uint(&self) -> uint {
|
||||
self.to_uint_opt().expect("BigInt conversion would overflow uint")
|
||||
}
|
||||
|
||||
/// Converts this `BigInt` into a `uint`, unless it would overflow.
|
||||
#[inline]
|
||||
pub fn to_uint_opt(&self) -> Option<uint> {
|
||||
match self.sign {
|
||||
Plus => self.data.to_uint_opt(),
|
||||
Zero => Some(0),
|
||||
Minus => None
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts this `BigInt` into an `int`, unless it would overflow.
|
||||
pub fn to_int_opt(&self) -> Option<int> {
|
||||
match self.sign {
|
||||
Plus => self.data.to_int_opt(),
|
||||
Zero => Some(0),
|
||||
Minus => self.data.to_uint_opt().and_then(|n| {
|
||||
let m: uint = 1 << (2*BigDigit::bits-1);
|
||||
if (n > m) {
|
||||
None
|
||||
} else if (n == m) {
|
||||
Some(int::min_value)
|
||||
} else {
|
||||
Some(-(n as int))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts this `BigInt` into a `BigUint`, failing if BigInt is
|
||||
/// negative.
|
||||
#[inline]
|
||||
pub fn to_biguint(&self) -> BigUint {
|
||||
self.to_biguint_opt().expect("negative BigInt cannot convert to BigUint")
|
||||
}
|
||||
|
||||
/// Converts this `BigInt` into a `BigUint`, if it's not negative.
|
||||
#[inline]
|
||||
pub fn to_biguint_opt(&self) -> Option<BigUint> {
|
||||
pub fn to_biguint(&self) -> Option<BigUint> {
|
||||
match self.sign {
|
||||
Plus => Some(self.data.clone()),
|
||||
Zero => Some(Zero::zero()),
|
||||
@ -1304,7 +1298,8 @@ mod biguint_tests {
|
||||
|
||||
use std::cmp::{Less, Equal, Greater};
|
||||
use std::int;
|
||||
use std::num::{IntConvertible, Zero, One, FromStrRadix};
|
||||
use std::num::{Zero, One, FromStrRadix};
|
||||
use std::num::{ToPrimitive, FromPrimitive};
|
||||
use std::rand::{task_rng};
|
||||
use std::str;
|
||||
use std::uint;
|
||||
@ -1482,9 +1477,10 @@ mod biguint_tests {
|
||||
#[test]
|
||||
fn test_convert_int() {
|
||||
fn check(v: ~[BigDigit], i: int) {
|
||||
let b = BigUint::new(v);
|
||||
assert!(b == IntConvertible::from_int(i));
|
||||
assert!(b.to_int() == i);
|
||||
let b1 = BigUint::new(v);
|
||||
let b2: BigUint = FromPrimitive::from_int(i).unwrap();
|
||||
assert!(b1 == b2);
|
||||
assert!(b1.to_int().unwrap() == i);
|
||||
}
|
||||
|
||||
check(~[], 0);
|
||||
@ -1493,17 +1489,18 @@ mod biguint_tests {
|
||||
check(~[ 0, 1], ((uint::max_value >> BigDigit::bits) + 1) as int);
|
||||
check(~[-1, -1 >> 1], int::max_value);
|
||||
|
||||
assert_eq!(BigUint::new(~[0, -1]).to_int_opt(), None);
|
||||
assert_eq!(BigUint::new(~[0, 0, 1]).to_int_opt(), None);
|
||||
assert_eq!(BigUint::new(~[0, 0, -1]).to_int_opt(), None);
|
||||
assert_eq!(BigUint::new(~[0, -1]).to_int(), None);
|
||||
assert_eq!(BigUint::new(~[0, 0, 1]).to_int(), None);
|
||||
assert_eq!(BigUint::new(~[0, 0, -1]).to_int(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_convert_uint() {
|
||||
fn check(v: ~[BigDigit], u: uint) {
|
||||
let b = BigUint::new(v);
|
||||
assert!(b == BigUint::from_uint(u));
|
||||
assert!(b.to_uint() == u);
|
||||
let b1 = BigUint::new(v);
|
||||
let b2: BigUint = FromPrimitive::from_uint(u).unwrap();
|
||||
assert!(b1 == b2);
|
||||
assert!(b1.to_uint().unwrap() == u);
|
||||
}
|
||||
|
||||
check(~[], 0);
|
||||
@ -1513,15 +1510,15 @@ mod biguint_tests {
|
||||
check(~[ 0, -1], uint::max_value << BigDigit::bits);
|
||||
check(~[-1, -1], uint::max_value);
|
||||
|
||||
assert_eq!(BigUint::new(~[0, 0, 1]).to_uint_opt(), None);
|
||||
assert_eq!(BigUint::new(~[0, 0, -1]).to_uint_opt(), None);
|
||||
assert_eq!(BigUint::new(~[0, 0, 1]).to_uint(), None);
|
||||
assert_eq!(BigUint::new(~[0, 0, -1]).to_uint(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_convert_to_bigint() {
|
||||
fn check(n: BigUint, ans: BigInt) {
|
||||
assert_eq!(n.to_bigint(), ans);
|
||||
assert_eq!(n.to_bigint().to_biguint(), n);
|
||||
assert_eq!(n.to_bigint().to_biguint().unwrap(), n);
|
||||
}
|
||||
check(Zero::zero(), Zero::zero());
|
||||
check(BigUint::new(~[1,2,3]),
|
||||
@ -1660,9 +1657,9 @@ mod biguint_tests {
|
||||
#[test]
|
||||
fn test_gcd() {
|
||||
fn check(a: uint, b: uint, c: uint) {
|
||||
let big_a = BigUint::from_uint(a);
|
||||
let big_b = BigUint::from_uint(b);
|
||||
let big_c = BigUint::from_uint(c);
|
||||
let big_a: BigUint = FromPrimitive::from_uint(a).unwrap();
|
||||
let big_b: BigUint = FromPrimitive::from_uint(b).unwrap();
|
||||
let big_c: BigUint = FromPrimitive::from_uint(c).unwrap();
|
||||
|
||||
assert_eq!(big_a.gcd(&big_b), big_c);
|
||||
}
|
||||
@ -1677,9 +1674,9 @@ mod biguint_tests {
|
||||
#[test]
|
||||
fn test_lcm() {
|
||||
fn check(a: uint, b: uint, c: uint) {
|
||||
let big_a = BigUint::from_uint(a);
|
||||
let big_b = BigUint::from_uint(b);
|
||||
let big_c = BigUint::from_uint(c);
|
||||
let big_a: BigUint = FromPrimitive::from_uint(a).unwrap();
|
||||
let big_b: BigUint = FromPrimitive::from_uint(b).unwrap();
|
||||
let big_c: BigUint = FromPrimitive::from_uint(c).unwrap();
|
||||
|
||||
assert_eq!(big_a.lcm(&big_b), big_c);
|
||||
}
|
||||
@ -1694,20 +1691,18 @@ mod biguint_tests {
|
||||
|
||||
#[test]
|
||||
fn test_is_even() {
|
||||
let one: Option<BigUint> = FromStr::from_str("1");
|
||||
let two: Option<BigUint> = FromStr::from_str("2");
|
||||
let thousand: Option<BigUint> = FromStr::from_str("1000");
|
||||
let big: Option<BigUint> =
|
||||
FromStr::from_str("1000000000000000000000");
|
||||
let bigger: Option<BigUint> =
|
||||
FromStr::from_str("1000000000000000000001");
|
||||
assert!(one.unwrap().is_odd());
|
||||
assert!(two.unwrap().is_even());
|
||||
assert!(thousand.unwrap().is_even());
|
||||
assert!(big.unwrap().is_even());
|
||||
assert!(bigger.unwrap().is_odd());
|
||||
assert!((BigUint::from_uint(1) << 64).is_even());
|
||||
assert!(((BigUint::from_uint(1) << 64) + BigUint::from_uint(1)).is_odd());
|
||||
let one: BigUint = FromStr::from_str("1").unwrap();
|
||||
let two: BigUint = FromStr::from_str("2").unwrap();
|
||||
let thousand: BigUint = FromStr::from_str("1000").unwrap();
|
||||
let big: BigUint = FromStr::from_str("1000000000000000000000").unwrap();
|
||||
let bigger: BigUint = FromStr::from_str("1000000000000000000001").unwrap();
|
||||
assert!(one.is_odd());
|
||||
assert!(two.is_even());
|
||||
assert!(thousand.is_even());
|
||||
assert!(big.is_even());
|
||||
assert!(bigger.is_odd());
|
||||
assert!((one << 64).is_even());
|
||||
assert!(((one << 64) + one).is_odd());
|
||||
}
|
||||
|
||||
fn to_str_pairs() -> ~[ (BigUint, ~[(uint, ~str)]) ] {
|
||||
@ -1805,8 +1800,8 @@ mod biguint_tests {
|
||||
let mut f: BigUint = One::one();
|
||||
for i in range(2, n + 1) {
|
||||
// FIXME(#6102): Assignment operator for BigInt causes ICE
|
||||
// f *= BigUint::from_uint(i);
|
||||
f = f * BigUint::from_uint(i);
|
||||
// f *= FromPrimitive::from_uint(i);
|
||||
f = f * FromPrimitive::from_uint(i).unwrap();
|
||||
}
|
||||
return f;
|
||||
}
|
||||
@ -1828,9 +1823,12 @@ mod biguint_tests {
|
||||
#[test]
|
||||
fn test_bits() {
|
||||
assert_eq!(BigUint::new(~[0,0,0,0]).bits(), 0);
|
||||
assert_eq!(BigUint::from_uint(0).bits(), 0);
|
||||
assert_eq!(BigUint::from_uint(1).bits(), 1);
|
||||
assert_eq!(BigUint::from_uint(3).bits(), 2);
|
||||
let n: BigUint = FromPrimitive::from_uint(0).unwrap();
|
||||
assert_eq!(n.bits(), 0);
|
||||
let n: BigUint = FromPrimitive::from_uint(1).unwrap();
|
||||
assert_eq!(n.bits(), 1);
|
||||
let n: BigUint = FromPrimitive::from_uint(3).unwrap();
|
||||
assert_eq!(n.bits(), 2);
|
||||
let n: BigUint = FromStrRadix::from_str_radix("4000000000", 16).unwrap();
|
||||
assert_eq!(n.bits(), 39);
|
||||
let one: BigUint = One::one();
|
||||
@ -1849,13 +1847,13 @@ mod biguint_tests {
|
||||
let mut rng = task_rng();
|
||||
|
||||
do 10.times {
|
||||
assert_eq!(rng.gen_bigint_range(&BigInt::from_uint(236),
|
||||
&BigInt::from_uint(237)),
|
||||
BigInt::from_uint(236));
|
||||
assert_eq!(rng.gen_bigint_range(&FromPrimitive::from_uint(236).unwrap(),
|
||||
&FromPrimitive::from_uint(237).unwrap()),
|
||||
FromPrimitive::from_uint(236).unwrap());
|
||||
}
|
||||
|
||||
let l = BigUint::from_uint(403469000 + 2352);
|
||||
let u = BigUint::from_uint(403469000 + 3513);
|
||||
let l = FromPrimitive::from_uint(403469000 + 2352).unwrap();
|
||||
let u = FromPrimitive::from_uint(403469000 + 3513).unwrap();
|
||||
do 1000.times {
|
||||
let n: BigUint = rng.gen_biguint_below(&u);
|
||||
assert!(n < u);
|
||||
@ -1869,16 +1867,16 @@ mod biguint_tests {
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn test_zero_rand_range() {
|
||||
task_rng().gen_biguint_range(&BigUint::from_uint(54),
|
||||
&BigUint::from_uint(54));
|
||||
task_rng().gen_biguint_range(&FromPrimitive::from_uint(54).unwrap(),
|
||||
&FromPrimitive::from_uint(54).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn test_negative_rand_range() {
|
||||
let mut rng = task_rng();
|
||||
let l = BigUint::from_uint(2352);
|
||||
let u = BigUint::from_uint(3513);
|
||||
let l = FromPrimitive::from_uint(2352).unwrap();
|
||||
let u = FromPrimitive::from_uint(3513).unwrap();
|
||||
// Switching u and l should fail:
|
||||
let _n: BigUint = rng.gen_biguint_range(&u, &l);
|
||||
}
|
||||
@ -1890,15 +1888,16 @@ mod bigint_tests {
|
||||
|
||||
use std::cmp::{Less, Equal, Greater};
|
||||
use std::int;
|
||||
use std::num::{IntConvertible, Zero, One, FromStrRadix};
|
||||
use std::num::{Zero, One, FromStrRadix};
|
||||
use std::num::{ToPrimitive, FromPrimitive};
|
||||
use std::rand::{task_rng};
|
||||
use std::uint;
|
||||
|
||||
#[test]
|
||||
fn test_from_biguint() {
|
||||
fn check(inp_s: Sign, inp_n: uint, ans_s: Sign, ans_n: uint) {
|
||||
let inp = BigInt::from_biguint(inp_s, BigUint::from_uint(inp_n));
|
||||
let ans = BigInt { sign: ans_s, data: BigUint::from_uint(ans_n)};
|
||||
let inp = BigInt::from_biguint(inp_s, FromPrimitive::from_uint(inp_n).unwrap());
|
||||
let ans = BigInt { sign: ans_s, data: FromPrimitive::from_uint(ans_n).unwrap()};
|
||||
assert_eq!(inp, ans);
|
||||
}
|
||||
check(Plus, 1, Plus, 1);
|
||||
@ -1952,61 +1951,62 @@ mod bigint_tests {
|
||||
|
||||
#[test]
|
||||
fn test_convert_int() {
|
||||
fn check(b: BigInt, i: int) {
|
||||
assert!(b == IntConvertible::from_int(i));
|
||||
assert!(b.to_int() == i);
|
||||
fn check(b1: BigInt, i: int) {
|
||||
let b2: BigInt = FromPrimitive::from_int(i).unwrap();
|
||||
assert!(b1 == b2);
|
||||
assert!(b1.to_int().unwrap() == i);
|
||||
}
|
||||
|
||||
check(Zero::zero(), 0);
|
||||
check(One::one(), 1);
|
||||
check(BigInt::from_biguint(
|
||||
Plus, BigUint::from_uint(int::max_value as uint)
|
||||
Plus, FromPrimitive::from_uint(int::max_value as uint).unwrap()
|
||||
), int::max_value);
|
||||
|
||||
assert_eq!(BigInt::from_biguint(
|
||||
Plus, BigUint::from_uint(int::max_value as uint + 1)
|
||||
).to_int_opt(), None);
|
||||
Plus, FromPrimitive::from_uint(int::max_value as uint + 1).unwrap()
|
||||
).to_int(), None);
|
||||
assert_eq!(BigInt::from_biguint(
|
||||
Plus, BigUint::new(~[1, 2, 3])
|
||||
).to_int_opt(), None);
|
||||
).to_int(), None);
|
||||
|
||||
check(BigInt::from_biguint(
|
||||
Minus, BigUint::new(~[0, 1<<(BigDigit::bits-1)])
|
||||
), int::min_value);
|
||||
assert_eq!(BigInt::from_biguint(
|
||||
Minus, BigUint::new(~[1, 1<<(BigDigit::bits-1)])
|
||||
).to_int_opt(), None);
|
||||
).to_int(), None);
|
||||
assert_eq!(BigInt::from_biguint(
|
||||
Minus, BigUint::new(~[1, 2, 3])).to_int_opt(), None);
|
||||
Minus, BigUint::new(~[1, 2, 3])).to_int(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_convert_uint() {
|
||||
fn check(b: BigInt, u: uint) {
|
||||
assert!(b == BigInt::from_uint(u));
|
||||
assert!(b.to_uint() == u);
|
||||
fn check(b1: BigInt, u: uint) {
|
||||
let b2: BigInt = FromPrimitive::from_uint(u).unwrap();
|
||||
assert!(b1 == b2);
|
||||
assert!(b1.to_uint().unwrap() == u);
|
||||
}
|
||||
|
||||
check(Zero::zero(), 0);
|
||||
check(One::one(), 1);
|
||||
|
||||
check(
|
||||
BigInt::from_biguint(Plus, BigUint::from_uint(uint::max_value)),
|
||||
BigInt::from_biguint(Plus, FromPrimitive::from_uint(uint::max_value).unwrap()),
|
||||
uint::max_value);
|
||||
assert_eq!(BigInt::from_biguint(
|
||||
Plus, BigUint::new(~[1, 2, 3])).to_uint_opt(), None);
|
||||
Plus, BigUint::new(~[1, 2, 3])).to_uint(), None);
|
||||
|
||||
assert_eq!(BigInt::from_biguint(
|
||||
Minus, BigUint::from_uint(uint::max_value)).to_uint_opt(), None);
|
||||
assert_eq!(BigInt::from_biguint(
|
||||
Minus, BigUint::new(~[1, 2, 3])).to_uint_opt(), None);
|
||||
let max_value: BigUint = FromPrimitive::from_uint(uint::max_value).unwrap();
|
||||
assert_eq!(BigInt::from_biguint(Minus, max_value).to_uint(), None);
|
||||
assert_eq!(BigInt::from_biguint(Minus, BigUint::new(~[1, 2, 3])).to_uint(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_convert_to_biguint() {
|
||||
fn check(n: BigInt, ans_1: BigUint) {
|
||||
assert_eq!(n.to_biguint(), ans_1);
|
||||
assert_eq!(n.to_biguint().to_bigint(), n);
|
||||
assert_eq!(n.to_biguint().unwrap(), ans_1);
|
||||
assert_eq!(n.to_biguint().unwrap().to_bigint(), n);
|
||||
}
|
||||
let zero: BigInt = Zero::zero();
|
||||
let unsigned_zero: BigUint = Zero::zero();
|
||||
@ -2017,7 +2017,7 @@ mod bigint_tests {
|
||||
check(zero, unsigned_zero);
|
||||
check(positive, BigUint::new(~[1,2,3]));
|
||||
|
||||
assert_eq!(negative.to_biguint_opt(), None);
|
||||
assert_eq!(negative.to_biguint(), None);
|
||||
}
|
||||
|
||||
static sum_triples: &'static [(&'static [BigDigit],
|
||||
@ -2233,9 +2233,9 @@ mod bigint_tests {
|
||||
#[test]
|
||||
fn test_gcd() {
|
||||
fn check(a: int, b: int, c: int) {
|
||||
let big_a: BigInt = IntConvertible::from_int(a);
|
||||
let big_b: BigInt = IntConvertible::from_int(b);
|
||||
let big_c: BigInt = IntConvertible::from_int(c);
|
||||
let big_a: BigInt = FromPrimitive::from_int(a).unwrap();
|
||||
let big_b: BigInt = FromPrimitive::from_int(b).unwrap();
|
||||
let big_c: BigInt = FromPrimitive::from_int(c).unwrap();
|
||||
|
||||
assert_eq!(big_a.gcd(&big_b), big_c);
|
||||
}
|
||||
@ -2253,9 +2253,9 @@ mod bigint_tests {
|
||||
#[test]
|
||||
fn test_lcm() {
|
||||
fn check(a: int, b: int, c: int) {
|
||||
let big_a: BigInt = IntConvertible::from_int(a);
|
||||
let big_b: BigInt = IntConvertible::from_int(b);
|
||||
let big_c: BigInt = IntConvertible::from_int(c);
|
||||
let big_a: BigInt = FromPrimitive::from_int(a).unwrap();
|
||||
let big_b: BigInt = FromPrimitive::from_int(b).unwrap();
|
||||
let big_c: BigInt = FromPrimitive::from_int(c).unwrap();
|
||||
|
||||
assert_eq!(big_a.lcm(&big_b), big_c);
|
||||
}
|
||||
@ -2282,13 +2282,14 @@ mod bigint_tests {
|
||||
let zero: BigInt = Zero::zero();
|
||||
assert_eq!(one.abs_sub(&zero), one);
|
||||
let one: BigInt = One::one();
|
||||
assert_eq!(one.abs_sub(&-one), IntConvertible::from_int(2));
|
||||
let two: BigInt = FromPrimitive::from_int(2).unwrap();
|
||||
assert_eq!(one.abs_sub(&-one), two);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_str_radix() {
|
||||
fn check(n: int, ans: &str) {
|
||||
let n: BigInt = IntConvertible::from_int(n);
|
||||
let n: BigInt = FromPrimitive::from_int(n).unwrap();
|
||||
assert!(ans == n.to_str_radix(10));
|
||||
}
|
||||
check(10, "10");
|
||||
@ -2303,7 +2304,7 @@ mod bigint_tests {
|
||||
fn test_from_str_radix() {
|
||||
fn check(s: &str, ans: Option<int>) {
|
||||
let ans = ans.map_move(|n| {
|
||||
let x: BigInt = IntConvertible::from_int(n);
|
||||
let x: BigInt = FromPrimitive::from_int(n).unwrap();
|
||||
x
|
||||
});
|
||||
assert_eq!(FromStrRadix::from_str_radix(s, 10), ans);
|
||||
@ -2339,9 +2340,9 @@ mod bigint_tests {
|
||||
let mut rng = task_rng();
|
||||
|
||||
do 10.times {
|
||||
assert_eq!(rng.gen_bigint_range(&BigInt::from_uint(236),
|
||||
&BigInt::from_uint(237)),
|
||||
BigInt::from_uint(236));
|
||||
assert_eq!(rng.gen_bigint_range(&FromPrimitive::from_uint(236).unwrap(),
|
||||
&FromPrimitive::from_uint(237).unwrap()),
|
||||
FromPrimitive::from_uint(236).unwrap());
|
||||
}
|
||||
|
||||
fn check(l: BigInt, u: BigInt) {
|
||||
@ -2352,8 +2353,8 @@ mod bigint_tests {
|
||||
assert!(n < u);
|
||||
}
|
||||
}
|
||||
let l = BigInt::from_uint(403469000 + 2352);
|
||||
let u = BigInt::from_uint(403469000 + 3513);
|
||||
let l: BigInt = FromPrimitive::from_uint(403469000 + 2352).unwrap();
|
||||
let u: BigInt = FromPrimitive::from_uint(403469000 + 3513).unwrap();
|
||||
check( l.clone(), u.clone());
|
||||
check(-l.clone(), u.clone());
|
||||
check(-u.clone(), -l.clone());
|
||||
@ -2362,16 +2363,16 @@ mod bigint_tests {
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn test_zero_rand_range() {
|
||||
task_rng().gen_bigint_range(&IntConvertible::from_int(54),
|
||||
&IntConvertible::from_int(54));
|
||||
task_rng().gen_bigint_range(&FromPrimitive::from_int(54).unwrap(),
|
||||
&FromPrimitive::from_int(54).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_fail]
|
||||
fn test_negative_rand_range() {
|
||||
let mut rng = task_rng();
|
||||
let l = BigInt::from_uint(2352);
|
||||
let u = BigInt::from_uint(3513);
|
||||
let l = FromPrimitive::from_uint(2352).unwrap();
|
||||
let u = FromPrimitive::from_uint(3513).unwrap();
|
||||
// Switching u and l should fail:
|
||||
let _n: BigInt = rng.gen_bigint_range(&u, &l);
|
||||
}
|
||||
@ -2381,13 +2382,13 @@ mod bigint_tests {
|
||||
mod bench {
|
||||
use super::*;
|
||||
use std::{iter, util};
|
||||
use std::num::{Zero, One};
|
||||
use std::num::{FromPrimitive, Zero, One};
|
||||
use extra::test::BenchHarness;
|
||||
|
||||
fn factorial(n: uint) -> BigUint {
|
||||
let mut f: BigUint = One::one();
|
||||
for i in iter::range_inclusive(1, n) {
|
||||
f = f * BigUint::from_uint(i);
|
||||
f = f * FromPrimitive::from_uint(i).unwrap();
|
||||
}
|
||||
f
|
||||
}
|
||||
|
@ -306,7 +306,7 @@ impl<T: FromStrRadix + Clone + Integer + Ord>
|
||||
mod test {
|
||||
|
||||
use super::*;
|
||||
use std::num::{Zero,One,FromStrRadix,IntConvertible};
|
||||
use std::num::{Zero,One,FromStrRadix,FromPrimitive};
|
||||
use std::from_str::FromStr;
|
||||
|
||||
pub static _0 : Rational = Ratio { numer: 0, denom: 1};
|
||||
@ -318,8 +318,8 @@ mod test {
|
||||
|
||||
pub fn to_big(n: Rational) -> BigRational {
|
||||
Ratio::new(
|
||||
IntConvertible::from_int(n.numer),
|
||||
IntConvertible::from_int(n.denom)
|
||||
FromPrimitive::from_int(n.numer).unwrap(),
|
||||
FromPrimitive::from_int(n.denom).unwrap()
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -107,7 +107,7 @@ use std::hashmap::HashMap;
|
||||
use std::libc::{c_uint, c_ulonglong, c_longlong};
|
||||
use std::ptr;
|
||||
use std::vec;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::codemap::{Span, Pos};
|
||||
use syntax::{ast, codemap, ast_util, ast_map, opt_vec, visit};
|
||||
use syntax::parse::token;
|
||||
use syntax::parse::token::special_idents;
|
||||
|
@ -26,7 +26,7 @@ use middle::ty;
|
||||
use middle::typeck;
|
||||
use syntax::abi::AbiSet;
|
||||
use syntax::ast_map;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::codemap::{Span, Pos};
|
||||
use syntax::parse::token;
|
||||
use syntax::print::pprust;
|
||||
use syntax::{ast, ast_util};
|
||||
|
@ -32,11 +32,6 @@ pub trait Num: Eq + Zero + One
|
||||
+ Div<Self,Self>
|
||||
+ Rem<Self,Self> {}
|
||||
|
||||
pub trait IntConvertible {
|
||||
fn to_int(&self) -> int;
|
||||
fn from_int(n: int) -> Self;
|
||||
}
|
||||
|
||||
pub trait Orderable: Ord {
|
||||
// These should be methods on `Ord`, with overridable default implementations. We don't want
|
||||
// to encumber all implementors of Ord by requiring them to implement these functions, but at
|
||||
@ -353,6 +348,298 @@ pub trait Float: Real
|
||||
#[inline(always)] pub fn ln_1p<T: Float>(value: T) -> T { value.ln_1p() }
|
||||
#[inline(always)] pub fn mul_add<T: Float>(a: T, b: T, c: T) -> T { a.mul_add(b, c) }
|
||||
|
||||
/// A generic trait for converting a value to a number.
|
||||
pub trait ToPrimitive {
|
||||
/// Converts the value of `self` to an `int`.
|
||||
fn to_int(&self) -> Option<int>;
|
||||
|
||||
/// Converts the value of `self` to an `i8`.
|
||||
#[inline]
|
||||
fn to_i8(&self) -> Option<i8> {
|
||||
// XXX: Check for range.
|
||||
self.to_int().and_then(|x| Some(x as i8))
|
||||
}
|
||||
|
||||
/// Converts the value of `self` to an `i16`.
|
||||
#[inline]
|
||||
fn to_i16(&self) -> Option<i16> {
|
||||
// XXX: Check for range.
|
||||
self.to_int().and_then(|x| Some(x as i16))
|
||||
}
|
||||
|
||||
/// Converts the value of `self` to an `i32`.
|
||||
#[inline]
|
||||
fn to_i32(&self) -> Option<i32> {
|
||||
// XXX: Check for range.
|
||||
self.to_int().and_then(|x| Some(x as i32))
|
||||
}
|
||||
|
||||
/// Converts the value of `self` to an `i64`.
|
||||
#[inline]
|
||||
fn to_i64(&self) -> Option<i64> {
|
||||
// XXX: Check for range.
|
||||
self.to_int().and_then(|x| Some(x as i64))
|
||||
}
|
||||
|
||||
/// Converts the value of `self` to an `uint`.
|
||||
fn to_uint(&self) -> Option<uint>;
|
||||
|
||||
/// Converts the value of `self` to an `u8`.
|
||||
#[inline]
|
||||
fn to_u8(&self) -> Option<u8> {
|
||||
// XXX: Check for range.
|
||||
self.to_uint().and_then(|x| Some(x as u8))
|
||||
}
|
||||
|
||||
/// Converts the value of `self` to an `u16`.
|
||||
#[inline]
|
||||
fn to_u16(&self) -> Option<u16> {
|
||||
// XXX: Check for range.
|
||||
self.to_uint().and_then(|x| Some(x as u16))
|
||||
}
|
||||
|
||||
/// Converts the value of `self` to an `u32`.
|
||||
#[inline]
|
||||
fn to_u32(&self) -> Option<u32> {
|
||||
// XXX: Check for range.
|
||||
self.to_uint().and_then(|x| Some(x as u32))
|
||||
}
|
||||
|
||||
/// Converts the value of `self` to an `u64`.
|
||||
#[inline]
|
||||
fn to_u64(&self) -> Option<u64> {
|
||||
// XXX: Check for range.
|
||||
self.to_uint().and_then(|x| Some(x as u64))
|
||||
}
|
||||
|
||||
/// Converts the value of `self` to an `f32`.
|
||||
#[inline]
|
||||
fn to_f32(&self) -> Option<f32> {
|
||||
// XXX: Check for range.
|
||||
self.to_float().and_then(|x| Some(x as f32))
|
||||
}
|
||||
|
||||
/// Converts the value of `self` to an `f64`.
|
||||
#[inline]
|
||||
fn to_f64(&self) -> Option<f64> {
|
||||
// XXX: Check for range.
|
||||
self.to_float().and_then(|x| Some(x as f64))
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_to_primitive(
|
||||
($T:ty) => (
|
||||
impl ToPrimitive for $T {
|
||||
#[inline] fn to_int(&self) -> Option<int> { Some(*self as int) }
|
||||
#[inline] fn to_i8(&self) -> Option<i8> { Some(*self as i8) }
|
||||
#[inline] fn to_i16(&self) -> Option<i16> { Some(*self as i16) }
|
||||
#[inline] fn to_i32(&self) -> Option<i32> { Some(*self as i32) }
|
||||
#[inline] fn to_i64(&self) -> Option<i64> { Some(*self as i64) }
|
||||
|
||||
#[inline] fn to_uint(&self) -> Option<uint> { Some(*self as uint) }
|
||||
#[inline] fn to_u8(&self) -> Option<u8> { Some(*self as u8) }
|
||||
#[inline] fn to_u16(&self) -> Option<u16> { Some(*self as u16) }
|
||||
#[inline] fn to_u32(&self) -> Option<u32> { Some(*self as u32) }
|
||||
#[inline] fn to_u64(&self) -> Option<u64> { Some(*self as u64) }
|
||||
|
||||
#[inline] fn to_float(&self) -> Option<float> { Some(*self as float) }
|
||||
#[inline] fn to_f32(&self) -> Option<f32> { Some(*self as f32) }
|
||||
#[inline] fn to_f64(&self) -> Option<f64> { Some(*self as f64) }
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
impl_to_primitive!(u8)
|
||||
impl_to_primitive!(u16)
|
||||
impl_to_primitive!(u32)
|
||||
impl_to_primitive!(u64)
|
||||
impl_to_primitive!(uint)
|
||||
impl_to_primitive!(i8)
|
||||
impl_to_primitive!(i16)
|
||||
impl_to_primitive!(i32)
|
||||
impl_to_primitive!(i64)
|
||||
impl_to_primitive!(int)
|
||||
impl_to_primitive!(f32)
|
||||
impl_to_primitive!(f64)
|
||||
impl_to_primitive!(float)
|
||||
|
||||
/// A generic trait for converting a number to a value.
|
||||
pub trait FromPrimitive {
|
||||
/// Convert an `int` to return an optional value of this type. If the
|
||||
/// value cannot be represented by this value, the `None` is returned.
|
||||
fn from_int(n: int) -> Option<Self>;
|
||||
|
||||
/// Convert an `i8` to return an optional value of this type. If the
|
||||
/// type cannot be represented by this value, the `None` is returned.
|
||||
#[inline]
|
||||
fn from_i8(n: i8) -> Option<Self> {
|
||||
FromPrimitive::from_int(n as int)
|
||||
}
|
||||
|
||||
/// Convert an `i16` to return an optional value of this type. If the
|
||||
/// type cannot be represented by this value, the `None` is returned.
|
||||
#[inline]
|
||||
fn from_i16(n: i16) -> Option<Self> {
|
||||
FromPrimitive::from_int(n as int)
|
||||
}
|
||||
|
||||
/// Convert an `i32` to return an optional value of this type. If the
|
||||
/// type cannot be represented by this value, the `None` is returned.
|
||||
#[inline]
|
||||
fn from_i32(n: i32) -> Option<Self> {
|
||||
FromPrimitive::from_int(n as int)
|
||||
}
|
||||
|
||||
/// Convert an `i64` to return an optional value of this type. If the
|
||||
/// type cannot be represented by this value, the `None` is returned.
|
||||
#[inline]
|
||||
fn from_i64(n: i64) -> Option<Self> {
|
||||
FromPrimitive::from_int(n as int)
|
||||
}
|
||||
|
||||
/// Convert an `uint` to return an optional value of this type. If the
|
||||
/// type cannot be represented by this value, the `None` is returned.
|
||||
fn from_uint(n: uint) -> Option<Self>;
|
||||
|
||||
/// Convert an `u8` to return an optional value of this type. If the
|
||||
/// type cannot be represented by this value, the `None` is returned.
|
||||
#[inline]
|
||||
fn from_u8(n: u8) -> Option<Self> {
|
||||
FromPrimitive::from_uint(n as uint)
|
||||
}
|
||||
|
||||
/// Convert an `u16` to return an optional value of this type. If the
|
||||
/// type cannot be represented by this value, the `None` is returned.
|
||||
#[inline]
|
||||
fn from_u16(n: u16) -> Option<Self> {
|
||||
FromPrimitive::from_uint(n as uint)
|
||||
}
|
||||
|
||||
/// Convert an `u32` to return an optional value of this type. If the
|
||||
/// type cannot be represented by this value, the `None` is returned.
|
||||
#[inline]
|
||||
fn from_u32(n: u32) -> Option<Self> {
|
||||
FromPrimitive::from_uint(n as uint)
|
||||
}
|
||||
|
||||
/// Convert an `u64` to return an optional value of this type. If the
|
||||
/// type cannot be represented by this value, the `None` is returned.
|
||||
#[inline]
|
||||
fn from_u64(n: u64) -> Option<Self> {
|
||||
FromPrimitive::from_uint(n as uint)
|
||||
}
|
||||
|
||||
/// Convert a `f32` to return an optional value of this type. If the
|
||||
/// type cannot be represented by this value, the `None` is returned.
|
||||
#[inline]
|
||||
fn from_f32(n: f32) -> Option<Self> {
|
||||
FromPrimitive::from_float(n as float)
|
||||
}
|
||||
|
||||
/// Convert a `f64` to return an optional value of this type. If the
|
||||
/// type cannot be represented by this value, the `None` is returned.
|
||||
#[inline]
|
||||
fn from_f64(n: f64) -> Option<Self> {
|
||||
FromPrimitive::from_float(n as float)
|
||||
}
|
||||
}
|
||||
|
||||
/// A utility function that just calls `FromPrimitive::from_int`.
|
||||
pub fn from_int<A: FromPrimitive>(n: int) -> Option<A> {
|
||||
FromPrimitive::from_int(n)
|
||||
}
|
||||
|
||||
/// A utility function that just calls `FromPrimitive::from_i8`.
|
||||
pub fn from_i8<A: FromPrimitive>(n: i8) -> Option<A> {
|
||||
FromPrimitive::from_i8(n)
|
||||
}
|
||||
|
||||
/// A utility function that just calls `FromPrimitive::from_i16`.
|
||||
pub fn from_i16<A: FromPrimitive>(n: i16) -> Option<A> {
|
||||
FromPrimitive::from_i16(n)
|
||||
}
|
||||
|
||||
/// A utility function that just calls `FromPrimitive::from_i32`.
|
||||
pub fn from_i32<A: FromPrimitive>(n: i32) -> Option<A> {
|
||||
FromPrimitive::from_i32(n)
|
||||
}
|
||||
|
||||
/// A utility function that just calls `FromPrimitive::from_i64`.
|
||||
pub fn from_i64<A: FromPrimitive>(n: i64) -> Option<A> {
|
||||
FromPrimitive::from_i64(n)
|
||||
}
|
||||
|
||||
/// A utility function that just calls `FromPrimitive::from_uint`.
|
||||
pub fn from_uint<A: FromPrimitive>(n: uint) -> Option<A> {
|
||||
FromPrimitive::from_uint(n)
|
||||
}
|
||||
|
||||
/// A utility function that just calls `FromPrimitive::from_u8`.
|
||||
pub fn from_u8<A: FromPrimitive>(n: u8) -> Option<A> {
|
||||
FromPrimitive::from_u8(n)
|
||||
}
|
||||
|
||||
/// A utility function that just calls `FromPrimitive::from_u16`.
|
||||
pub fn from_u16<A: FromPrimitive>(n: u16) -> Option<A> {
|
||||
FromPrimitive::from_u16(n)
|
||||
}
|
||||
|
||||
/// A utility function that just calls `FromPrimitive::from_u32`.
|
||||
pub fn from_u32<A: FromPrimitive>(n: u32) -> Option<A> {
|
||||
FromPrimitive::from_u32(n)
|
||||
}
|
||||
|
||||
/// A utility function that just calls `FromPrimitive::from_u64`.
|
||||
pub fn from_u64<A: FromPrimitive>(n: u64) -> Option<A> {
|
||||
FromPrimitive::from_u64(n)
|
||||
}
|
||||
|
||||
/// A utility function that just calls `FromPrimitive::from_f32`.
|
||||
pub fn from_f32<A: FromPrimitive>(n: f32) -> Option<A> {
|
||||
FromPrimitive::from_f32(n)
|
||||
}
|
||||
|
||||
/// A utility function that just calls `FromPrimitive::from_f64`.
|
||||
pub fn from_f64<A: FromPrimitive>(n: f64) -> Option<A> {
|
||||
FromPrimitive::from_f64(n)
|
||||
}
|
||||
|
||||
macro_rules! impl_from_primitive(
|
||||
($T:ty) => (
|
||||
impl FromPrimitive for $T {
|
||||
#[inline] fn from_int(n: int) -> Option<$T> { Some(n as $T) }
|
||||
#[inline] fn from_i8(n: i8) -> Option<$T> { Some(n as $T) }
|
||||
#[inline] fn from_i16(n: i16) -> Option<$T> { Some(n as $T) }
|
||||
#[inline] fn from_i32(n: i32) -> Option<$T> { Some(n as $T) }
|
||||
#[inline] fn from_i64(n: i64) -> Option<$T> { Some(n as $T) }
|
||||
|
||||
#[inline] fn from_uint(n: uint) -> Option<$T> { Some(n as $T) }
|
||||
#[inline] fn from_u8(n: u8) -> Option<$T> { Some(n as $T) }
|
||||
#[inline] fn from_u16(n: u16) -> Option<$T> { Some(n as $T) }
|
||||
#[inline] fn from_u32(n: u32) -> Option<$T> { Some(n as $T) }
|
||||
#[inline] fn from_u64(n: u64) -> Option<$T> { Some(n as $T) }
|
||||
|
||||
#[inline] fn from_float(n: float) -> Option<$T> { Some(n as $T) }
|
||||
#[inline] fn from_f32(n: f32) -> Option<$T> { Some(n as $T) }
|
||||
#[inline] fn from_f64(n: f64) -> Option<$T> { Some(n as $T) }
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
impl_from_primitive!(u8)
|
||||
impl_from_primitive!(u16)
|
||||
impl_from_primitive!(u32)
|
||||
impl_from_primitive!(u64)
|
||||
impl_from_primitive!(uint)
|
||||
impl_from_primitive!(i8)
|
||||
impl_from_primitive!(i16)
|
||||
impl_from_primitive!(i32)
|
||||
impl_from_primitive!(i64)
|
||||
impl_from_primitive!(int)
|
||||
impl_from_primitive!(f32)
|
||||
impl_from_primitive!(f64)
|
||||
impl_from_primitive!(float)
|
||||
|
||||
/// Cast from one machine scalar to another
|
||||
///
|
||||
/// # Example
|
||||
@ -363,54 +650,24 @@ pub trait Float: Real
|
||||
/// ```
|
||||
///
|
||||
#[inline]
|
||||
pub fn cast<T:NumCast,U:NumCast>(n: T) -> U {
|
||||
pub fn cast<T: NumCast,U: NumCast>(n: T) -> Option<U> {
|
||||
NumCast::from(n)
|
||||
}
|
||||
|
||||
/// An interface for casting between machine scalars
|
||||
pub trait NumCast {
|
||||
fn from<T:NumCast>(n: T) -> Self;
|
||||
|
||||
fn to_u8(&self) -> u8;
|
||||
fn to_u16(&self) -> u16;
|
||||
fn to_u32(&self) -> u32;
|
||||
fn to_u64(&self) -> u64;
|
||||
fn to_uint(&self) -> uint;
|
||||
|
||||
fn to_i8(&self) -> i8;
|
||||
fn to_i16(&self) -> i16;
|
||||
fn to_i32(&self) -> i32;
|
||||
fn to_i64(&self) -> i64;
|
||||
fn to_int(&self) -> int;
|
||||
|
||||
fn to_f32(&self) -> f32;
|
||||
fn to_f64(&self) -> f64;
|
||||
pub trait NumCast: ToPrimitive {
|
||||
fn from<T: ToPrimitive>(n: T) -> Option<Self>;
|
||||
}
|
||||
|
||||
macro_rules! impl_num_cast(
|
||||
($T:ty, $conv:ident) => (
|
||||
impl NumCast for $T {
|
||||
#[inline]
|
||||
fn from<N:NumCast>(n: N) -> $T {
|
||||
fn from<N: ToPrimitive>(n: N) -> Option<$T> {
|
||||
// `$conv` could be generated using `concat_idents!`, but that
|
||||
// macro seems to be broken at the moment
|
||||
n.$conv()
|
||||
}
|
||||
|
||||
#[inline] fn to_u8(&self) -> u8 { *self as u8 }
|
||||
#[inline] fn to_u16(&self) -> u16 { *self as u16 }
|
||||
#[inline] fn to_u32(&self) -> u32 { *self as u32 }
|
||||
#[inline] fn to_u64(&self) -> u64 { *self as u64 }
|
||||
#[inline] fn to_uint(&self) -> uint { *self as uint }
|
||||
|
||||
#[inline] fn to_i8(&self) -> i8 { *self as i8 }
|
||||
#[inline] fn to_i16(&self) -> i16 { *self as i16 }
|
||||
#[inline] fn to_i32(&self) -> i32 { *self as i32 }
|
||||
#[inline] fn to_i64(&self) -> i64 { *self as i64 }
|
||||
#[inline] fn to_int(&self) -> int { *self as int }
|
||||
|
||||
#[inline] fn to_f32(&self) -> f32 { *self as f32 }
|
||||
#[inline] fn to_f64(&self) -> f64 { *self as f64 }
|
||||
}
|
||||
)
|
||||
)
|
||||
@ -461,7 +718,7 @@ pub fn pow_with_uint<T:NumCast+One+Zero+Div<T,T>+Mul<T,T>>(radix: uint, pow: uin
|
||||
if radix == 0u { return _0; }
|
||||
let mut my_pow = pow;
|
||||
let mut total = _1;
|
||||
let mut multiplier = cast(radix);
|
||||
let mut multiplier = cast(radix).unwrap();
|
||||
while (my_pow > 0u) {
|
||||
if my_pow % 2u == 1u {
|
||||
total = total * multiplier;
|
||||
@ -543,11 +800,11 @@ pub trait CheckedDiv: Div<Self, Self> {
|
||||
/// Helper function for testing numeric operations
|
||||
#[cfg(test)]
|
||||
pub fn test_num<T:Num + NumCast>(ten: T, two: T) {
|
||||
assert_eq!(ten.add(&two), cast(12));
|
||||
assert_eq!(ten.sub(&two), cast(8));
|
||||
assert_eq!(ten.mul(&two), cast(20));
|
||||
assert_eq!(ten.div(&two), cast(5));
|
||||
assert_eq!(ten.rem(&two), cast(0));
|
||||
assert_eq!(ten.add(&two), cast(12).unwrap());
|
||||
assert_eq!(ten.sub(&two), cast(8).unwrap());
|
||||
assert_eq!(ten.mul(&two), cast(20).unwrap());
|
||||
assert_eq!(ten.div(&two), cast(5).unwrap());
|
||||
assert_eq!(ten.rem(&two), cast(0).unwrap());
|
||||
|
||||
assert_eq!(ten.add(&two), ten + two);
|
||||
assert_eq!(ten.sub(&two), ten - two);
|
||||
@ -566,44 +823,45 @@ mod tests {
|
||||
($_20:expr) => ({
|
||||
let _20 = $_20;
|
||||
|
||||
assert_eq!(20u, _20.to_uint());
|
||||
assert_eq!(20u8, _20.to_u8());
|
||||
assert_eq!(20u16, _20.to_u16());
|
||||
assert_eq!(20u32, _20.to_u32());
|
||||
assert_eq!(20u64, _20.to_u64());
|
||||
assert_eq!(20i, _20.to_int());
|
||||
assert_eq!(20i8, _20.to_i8());
|
||||
assert_eq!(20i16, _20.to_i16());
|
||||
assert_eq!(20i32, _20.to_i32());
|
||||
assert_eq!(20i64, _20.to_i64());
|
||||
assert_eq!(20f32, _20.to_f32());
|
||||
assert_eq!(20f64, _20.to_f64());
|
||||
assert_eq!(20u, _20.to_uint().unwrap());
|
||||
assert_eq!(20u8, _20.to_u8().unwrap());
|
||||
assert_eq!(20u16, _20.to_u16().unwrap());
|
||||
assert_eq!(20u32, _20.to_u32().unwrap());
|
||||
assert_eq!(20u64, _20.to_u64().unwrap());
|
||||
assert_eq!(20i, _20.to_int().unwrap());
|
||||
assert_eq!(20i8, _20.to_i8().unwrap());
|
||||
assert_eq!(20i16, _20.to_i16().unwrap());
|
||||
assert_eq!(20i32, _20.to_i32().unwrap());
|
||||
assert_eq!(20i64, _20.to_i64().unwrap());
|
||||
assert_eq!(20f, _20.to_float().unwrap());
|
||||
assert_eq!(20f32, _20.to_f32().unwrap());
|
||||
assert_eq!(20f64, _20.to_f64().unwrap());
|
||||
|
||||
assert_eq!(_20, NumCast::from(20u));
|
||||
assert_eq!(_20, NumCast::from(20u8));
|
||||
assert_eq!(_20, NumCast::from(20u16));
|
||||
assert_eq!(_20, NumCast::from(20u32));
|
||||
assert_eq!(_20, NumCast::from(20u64));
|
||||
assert_eq!(_20, NumCast::from(20i));
|
||||
assert_eq!(_20, NumCast::from(20i8));
|
||||
assert_eq!(_20, NumCast::from(20i16));
|
||||
assert_eq!(_20, NumCast::from(20i32));
|
||||
assert_eq!(_20, NumCast::from(20i64));
|
||||
assert_eq!(_20, NumCast::from(20f32));
|
||||
assert_eq!(_20, NumCast::from(20f64));
|
||||
assert_eq!(_20, NumCast::from(20u).unwrap());
|
||||
assert_eq!(_20, NumCast::from(20u8).unwrap());
|
||||
assert_eq!(_20, NumCast::from(20u16).unwrap());
|
||||
assert_eq!(_20, NumCast::from(20u32).unwrap());
|
||||
assert_eq!(_20, NumCast::from(20u64).unwrap());
|
||||
assert_eq!(_20, NumCast::from(20i).unwrap());
|
||||
assert_eq!(_20, NumCast::from(20i8).unwrap());
|
||||
assert_eq!(_20, NumCast::from(20i16).unwrap());
|
||||
assert_eq!(_20, NumCast::from(20i32).unwrap());
|
||||
assert_eq!(_20, NumCast::from(20i64).unwrap());
|
||||
assert_eq!(_20, NumCast::from(20f32).unwrap());
|
||||
assert_eq!(_20, NumCast::from(20f64).unwrap());
|
||||
|
||||
assert_eq!(_20, cast(20u));
|
||||
assert_eq!(_20, cast(20u8));
|
||||
assert_eq!(_20, cast(20u16));
|
||||
assert_eq!(_20, cast(20u32));
|
||||
assert_eq!(_20, cast(20u64));
|
||||
assert_eq!(_20, cast(20i));
|
||||
assert_eq!(_20, cast(20i8));
|
||||
assert_eq!(_20, cast(20i16));
|
||||
assert_eq!(_20, cast(20i32));
|
||||
assert_eq!(_20, cast(20i64));
|
||||
assert_eq!(_20, cast(20f32));
|
||||
assert_eq!(_20, cast(20f64));
|
||||
assert_eq!(_20, cast(20u).unwrap());
|
||||
assert_eq!(_20, cast(20u8).unwrap());
|
||||
assert_eq!(_20, cast(20u16).unwrap());
|
||||
assert_eq!(_20, cast(20u32).unwrap());
|
||||
assert_eq!(_20, cast(20u64).unwrap());
|
||||
assert_eq!(_20, cast(20i).unwrap());
|
||||
assert_eq!(_20, cast(20i8).unwrap());
|
||||
assert_eq!(_20, cast(20i16).unwrap());
|
||||
assert_eq!(_20, cast(20i32).unwrap());
|
||||
assert_eq!(_20, cast(20i64).unwrap());
|
||||
assert_eq!(_20, cast(20f32).unwrap());
|
||||
assert_eq!(_20, cast(20f64).unwrap());
|
||||
})
|
||||
)
|
||||
|
||||
|
@ -140,7 +140,7 @@ pub fn int_to_str_bytes_common<T:NumCast+Zero+Eq+Ord+Integer+
|
||||
let _0: T = Zero::zero();
|
||||
|
||||
let neg = num < _0;
|
||||
let radix_gen: T = cast(radix);
|
||||
let radix_gen: T = cast(radix).unwrap();
|
||||
|
||||
let mut deccum = num;
|
||||
// This is just for integral types, the largest of which is a u64. The
|
||||
@ -163,7 +163,7 @@ pub fn int_to_str_bytes_common<T:NumCast+Zero+Eq+Ord+Integer+
|
||||
} else {
|
||||
current_digit_signed
|
||||
};
|
||||
buf[cur] = match current_digit.to_u8() {
|
||||
buf[cur] = match current_digit.to_u8().unwrap() {
|
||||
i @ 0..9 => '0' as u8 + i,
|
||||
i => 'a' as u8 + (i - 10),
|
||||
};
|
||||
@ -247,7 +247,7 @@ pub fn float_to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Float+Round+
|
||||
|
||||
let neg = num < _0 || (negative_zero && _1 / num == Float::neg_infinity());
|
||||
let mut buf: ~[u8] = ~[];
|
||||
let radix_gen: T = cast(radix as int);
|
||||
let radix_gen: T = cast(radix as int).unwrap();
|
||||
|
||||
// First emit the non-fractional part, looping at least once to make
|
||||
// sure at least a `0` gets emitted.
|
||||
@ -265,7 +265,7 @@ pub fn float_to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Float+Round+
|
||||
deccum = deccum / radix_gen;
|
||||
deccum = deccum.trunc();
|
||||
|
||||
buf.push(char::from_digit(current_digit.to_int() as uint, radix)
|
||||
buf.push(char::from_digit(current_digit.to_int().unwrap() as uint, radix)
|
||||
.unwrap() as u8);
|
||||
|
||||
// No more digits to calculate for the non-fractional part -> break
|
||||
@ -322,7 +322,7 @@ pub fn float_to_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Float+Round+
|
||||
let current_digit = deccum.trunc().abs();
|
||||
|
||||
buf.push(char::from_digit(
|
||||
current_digit.to_int() as uint, radix).unwrap() as u8);
|
||||
current_digit.to_int().unwrap() as uint, radix).unwrap() as u8);
|
||||
|
||||
// Decrease the deccumulator one fractional digit at a time
|
||||
deccum = deccum.fract();
|
||||
@ -492,7 +492,7 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Div<T,T>+
|
||||
|
||||
let _0: T = Zero::zero();
|
||||
let _1: T = One::one();
|
||||
let radix_gen: T = cast(radix as int);
|
||||
let radix_gen: T = cast(radix as int).unwrap();
|
||||
|
||||
let len = buf.len();
|
||||
|
||||
@ -543,9 +543,9 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Div<T,T>+
|
||||
|
||||
// add/subtract current digit depending on sign
|
||||
if accum_positive {
|
||||
accum = accum + cast(digit as int);
|
||||
accum = accum + cast(digit as int).unwrap();
|
||||
} else {
|
||||
accum = accum - cast(digit as int);
|
||||
accum = accum - cast(digit as int).unwrap();
|
||||
}
|
||||
|
||||
// Detect overflow by comparing to last value, except
|
||||
@ -556,11 +556,11 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Div<T,T>+
|
||||
|
||||
// Detect overflow by reversing the shift-and-add proccess
|
||||
if accum_positive &&
|
||||
(last_accum != ((accum - cast(digit as int))/radix_gen.clone())) {
|
||||
(last_accum != ((accum - cast(digit as int).unwrap())/radix_gen.clone())) {
|
||||
return NumStrConv::inf();
|
||||
}
|
||||
if !accum_positive &&
|
||||
(last_accum != ((accum + cast(digit as int))/radix_gen.clone())) {
|
||||
(last_accum != ((accum + cast(digit as int).unwrap())/radix_gen.clone())) {
|
||||
return NumStrConv::neg_inf();
|
||||
}
|
||||
}
|
||||
@ -596,7 +596,7 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Div<T,T>+
|
||||
// Decrease power one order of magnitude
|
||||
power = power / radix_gen;
|
||||
|
||||
let digit_t: T = cast(digit);
|
||||
let digit_t: T = cast(digit).unwrap();
|
||||
|
||||
// add/subtract current digit depending on sign
|
||||
if accum_positive {
|
||||
@ -654,9 +654,9 @@ pub fn from_str_bytes_common<T:NumCast+Zero+One+Eq+Ord+Div<T,T>+
|
||||
match exp {
|
||||
Some(exp_pow) => {
|
||||
multiplier = if exp_pow < 0 {
|
||||
_1 / pow_with_uint::<T>(base, (-exp_pow.to_int()) as uint)
|
||||
_1 / pow_with_uint::<T>(base, (-exp_pow.to_int().unwrap()) as uint)
|
||||
} else {
|
||||
pow_with_uint::<T>(base, exp_pow.to_int() as uint)
|
||||
pow_with_uint::<T>(base, exp_pow.to_int().unwrap() as uint)
|
||||
}
|
||||
}
|
||||
None => return None // invalid exponent -> invalid number
|
||||
|
@ -59,7 +59,7 @@ pub use num::{Orderable, Signed, Unsigned, Round};
|
||||
pub use num::{Algebraic, Trigonometric, Exponential, Hyperbolic};
|
||||
pub use num::{Integer, Fractional, Real, RealExt};
|
||||
pub use num::{Bitwise, BitCount, Bounded};
|
||||
pub use num::{Primitive, Int, Float, ToStrRadix};
|
||||
pub use num::{Primitive, Int, Float, ToStrRadix, ToPrimitive, FromPrimitive};
|
||||
pub use path::GenericPath;
|
||||
pub use path::Path;
|
||||
pub use path::PosixPath;
|
||||
|
@ -314,12 +314,12 @@ pub trait Rng {
|
||||
/// ```
|
||||
fn gen_integer_range<T: Rand + Int>(&mut self, low: T, high: T) -> T {
|
||||
assert!(low < high, "RNG.gen_integer_range called with low >= high");
|
||||
let range = (high - low).to_u64();
|
||||
let range = (high - low).to_u64().unwrap();
|
||||
let accept_zone = u64::max_value - u64::max_value % range;
|
||||
loop {
|
||||
let rand = self.gen::<u64>();
|
||||
if rand < accept_zone {
|
||||
return low + NumCast::from(rand % range);
|
||||
return low + NumCast::from(rand % range).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,6 @@ pub fn main() {
|
||||
|
||||
// floats
|
||||
// num
|
||||
assert_eq!(10f32.to_int(), 10);
|
||||
assert_eq!(10f64.to_int(), 10);
|
||||
assert_eq!(10f32.to_int().unwrap(), 10);
|
||||
assert_eq!(10f64.to_int().unwrap(), 10);
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ pub trait NumExt: Num + NumCast + Eq + Ord {}
|
||||
|
||||
pub trait FloatExt: NumExt + ApproxEq<Self> {}
|
||||
|
||||
fn greater_than_one<T:NumExt>(n: &T) -> bool { *n > NumCast::from(1) }
|
||||
fn greater_than_one_float<T:FloatExt>(n: &T) -> bool { *n > NumCast::from(1) }
|
||||
fn greater_than_one<T:NumExt>(n: &T) -> bool { *n > NumCast::from(1).unwrap() }
|
||||
fn greater_than_one_float<T:FloatExt>(n: &T) -> bool { *n > NumCast::from(1).unwrap() }
|
||||
|
||||
pub fn main() {}
|
||||
|
@ -22,7 +22,7 @@ trait Num {
|
||||
pub trait NumExt: Num + NumCast { }
|
||||
|
||||
fn greater_than_one<T:NumExt>(n: &T) -> bool {
|
||||
n.gt(&NumCast::from(1))
|
||||
n.gt(&NumCast::from(1).unwrap())
|
||||
}
|
||||
|
||||
pub fn main() {}
|
||||
|
@ -14,7 +14,7 @@ use std::num::NumCast;
|
||||
pub trait NumExt: Num + NumCast + Ord { }
|
||||
|
||||
fn greater_than_one<T:NumExt>(n: &T) -> bool {
|
||||
*n > NumCast::from(1)
|
||||
*n > NumCast::from(1).unwrap()
|
||||
}
|
||||
|
||||
pub fn main() {}
|
||||
|
@ -16,7 +16,7 @@ pub trait NumExt: Eq + Ord + Num + NumCast {}
|
||||
impl NumExt for f32 {}
|
||||
|
||||
fn num_eq_one<T:NumExt>(n: T) {
|
||||
println!("{}", n == NumCast::from(1))
|
||||
println!("{}", n == NumCast::from(1).unwrap())
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
|
@ -17,7 +17,7 @@ impl NumExt for f32 {}
|
||||
impl NumExt for int {}
|
||||
|
||||
fn num_eq_one<T:NumExt>() -> T {
|
||||
NumCast::from(1)
|
||||
NumCast::from(1).unwrap()
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
|
Loading…
Reference in New Issue
Block a user