std: Swap {To,From}Primitive to use the 64bit as the unimplemented version
One downside with this current implementation is that since BigInt's default is now 64 bit, we can convert larger BigInt's to a primitive, however the current implementation on 32 bit architectures does not take advantage of this fact.
This commit is contained in:
parent
5a64e1a35a
commit
9de7ad2d8c
@ -20,13 +20,13 @@ A `BigInt` is a combination of `BigUint` and `Sign`.
|
||||
#[allow(non_uppercase_statics)];
|
||||
|
||||
use std::cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater};
|
||||
use std::int;
|
||||
use std::num;
|
||||
use std::num::{Zero, One, ToStrRadix, FromStrRadix, Orderable};
|
||||
use std::num::{ToPrimitive, FromPrimitive};
|
||||
use std::rand::Rng;
|
||||
use std::str;
|
||||
use std::uint;
|
||||
use std::{i64, u64};
|
||||
use std::vec;
|
||||
|
||||
/**
|
||||
@ -503,24 +503,24 @@ impl Integer for BigUint {
|
||||
|
||||
impl ToPrimitive for BigUint {
|
||||
#[inline]
|
||||
fn to_int(&self) -> Option<int> {
|
||||
fn to_i64(&self) -> Option<i64> {
|
||||
do self.to_uint().and_then |n| {
|
||||
// If top bit of uint is set, it's too large to convert to
|
||||
// If top bit of u64 is set, it's too large to convert to
|
||||
// int.
|
||||
if (n >> (2*BigDigit::bits - 1) != 0) {
|
||||
None
|
||||
} else {
|
||||
Some(n as int)
|
||||
Some(n as i64)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn to_uint(&self) -> Option<uint> {
|
||||
fn to_u64(&self) -> Option<u64> {
|
||||
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])),
|
||||
1 => Some(self.data[0] as u64),
|
||||
2 => Some(BigDigit::to_uint(self.data[1], self.data[0]) as u64),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
@ -528,17 +528,17 @@ impl ToPrimitive for BigUint {
|
||||
|
||||
impl FromPrimitive for BigUint {
|
||||
#[inline]
|
||||
fn from_int(n: int) -> Option<BigUint> {
|
||||
fn from_i64(n: i64) -> Option<BigUint> {
|
||||
if (n < 0) {
|
||||
Some(Zero::zero())
|
||||
} else {
|
||||
FromPrimitive::from_uint(n as uint)
|
||||
FromPrimitive::from_u64(n as u64)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_uint(n: uint) -> Option<BigUint> {
|
||||
let n = match BigDigit::from_uint(n) {
|
||||
fn from_u64(n: u64) -> Option<BigUint> {
|
||||
let n = match BigDigit::from_uint(n as uint) {
|
||||
(0, 0) => Zero::zero(),
|
||||
(0, n0) => BigUint::new(~[n0]),
|
||||
(n1, n0) => BigUint::new(~[n0, n1])
|
||||
@ -1083,19 +1083,19 @@ impl Integer for BigInt {
|
||||
|
||||
impl ToPrimitive for BigInt {
|
||||
#[inline]
|
||||
fn to_int(&self) -> Option<int> {
|
||||
fn to_i64(&self) -> Option<i64> {
|
||||
match self.sign {
|
||||
Plus => self.data.to_int(),
|
||||
Plus => self.data.to_i64(),
|
||||
Zero => Some(0),
|
||||
Minus => {
|
||||
do self.data.to_uint().and_then |n| {
|
||||
let m: uint = 1 << (2*BigDigit::bits-1);
|
||||
do self.data.to_u64().and_then |n| {
|
||||
let m: u64 = 1 << (2*BigDigit::bits-1);
|
||||
if (n > m) {
|
||||
None
|
||||
} else if (n == m) {
|
||||
Some(int::min_value)
|
||||
Some(i64::min_value)
|
||||
} else {
|
||||
Some(-(n as int))
|
||||
Some(-(n as i64))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1103,9 +1103,9 @@ impl ToPrimitive for BigInt {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn to_uint(&self) -> Option<uint> {
|
||||
fn to_u64(&self) -> Option<u64> {
|
||||
match self.sign {
|
||||
Plus => self.data.to_uint(),
|
||||
Plus => self.data.to_u64(),
|
||||
Zero => Some(0),
|
||||
Minus => None
|
||||
}
|
||||
@ -1114,13 +1114,13 @@ impl ToPrimitive for BigInt {
|
||||
|
||||
impl FromPrimitive for BigInt {
|
||||
#[inline]
|
||||
fn from_int(n: int) -> Option<BigInt> {
|
||||
fn from_i64(n: i64) -> Option<BigInt> {
|
||||
if n > 0 {
|
||||
do FromPrimitive::from_uint(n as uint).and_then |n| {
|
||||
do FromPrimitive::from_u64(n as u64).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| {
|
||||
do FromPrimitive::from_u64(u64::max_value - (n as u64) + 1).and_then |n| {
|
||||
Some(BigInt::from_biguint(Minus, n))
|
||||
}
|
||||
} else {
|
||||
@ -1129,11 +1129,11 @@ impl FromPrimitive for BigInt {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn from_uint(n: uint) -> Option<BigInt> {
|
||||
fn from_u64(n: u64) -> Option<BigInt> {
|
||||
if n == 0 {
|
||||
Some(Zero::zero())
|
||||
} else {
|
||||
do FromPrimitive::from_uint(n).and_then |n| {
|
||||
do FromPrimitive::from_u64(n).and_then |n| {
|
||||
Some(BigInt::from_biguint(Plus, n))
|
||||
}
|
||||
}
|
||||
|
@ -351,65 +351,69 @@ pub trait Float: Real
|
||||
/// 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>;
|
||||
#[inline]
|
||||
fn to_int(&self) -> Option<int> {
|
||||
// XXX: Check for range.
|
||||
self.to_i64().and_then(|x| Some(x as 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))
|
||||
self.to_i64().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))
|
||||
self.to_i64().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))
|
||||
self.to_i64().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))
|
||||
}
|
||||
fn to_i64(&self) -> Option<i64>;
|
||||
|
||||
/// Converts the value of `self` to an `uint`.
|
||||
fn to_uint(&self) -> Option<uint>;
|
||||
#[inline]
|
||||
fn to_uint(&self) -> Option<uint> {
|
||||
// XXX: Check for range.
|
||||
self.to_u64().and_then(|x| Some(x as 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))
|
||||
self.to_u64().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))
|
||||
self.to_u64().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))
|
||||
self.to_u64().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))
|
||||
self.to_u64().and_then(|x| Some(x as u64))
|
||||
}
|
||||
|
||||
/// Converts the value of `self` to an `f32`.
|
||||
@ -423,7 +427,7 @@ pub trait ToPrimitive {
|
||||
#[inline]
|
||||
fn to_f64(&self) -> Option<f64> {
|
||||
// XXX: Check for range.
|
||||
self.to_float().and_then(|x| Some(x as f64))
|
||||
self.to_i64().and_then(|x| Some(x as f64))
|
||||
}
|
||||
}
|
||||
|
||||
@ -467,80 +471,80 @@ impl_to_primitive!(float)
|
||||
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>;
|
||||
#[inline]
|
||||
fn from_int(n: int) -> Option<Self> {
|
||||
FromPrimitive::from_i64(n as i64)
|
||||
}
|
||||
|
||||
/// 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)
|
||||
FromPrimitive::from_i64(n as i64)
|
||||
}
|
||||
|
||||
/// 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)
|
||||
FromPrimitive::from_i64(n as i64)
|
||||
}
|
||||
|
||||
/// 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)
|
||||
FromPrimitive::from_i64(n as i64)
|
||||
}
|
||||
|
||||
/// 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)
|
||||
}
|
||||
fn from_i64(n: i64) -> Option<Self>;
|
||||
|
||||
/// 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>;
|
||||
#[inline]
|
||||
fn from_uint(n: uint) -> Option<Self> {
|
||||
FromPrimitive::from_u64(n as u64)
|
||||
}
|
||||
|
||||
/// 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)
|
||||
FromPrimitive::from_u64(n as u64)
|
||||
}
|
||||
|
||||
/// 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)
|
||||
FromPrimitive::from_u64(n as u64)
|
||||
}
|
||||
|
||||
/// 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)
|
||||
FromPrimitive::from_u64(n as u64)
|
||||
}
|
||||
|
||||
/// 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)
|
||||
}
|
||||
fn from_u64(n: u64) -> Option<Self>;
|
||||
|
||||
/// 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)
|
||||
FromPrimitive::from_f64(n as f64)
|
||||
}
|
||||
|
||||
/// 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)
|
||||
FromPrimitive::from_i64(n as i64)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,32 +25,32 @@ pub fn expand_deriving_from_primitive(cx: @ExtCtxt,
|
||||
generics: LifetimeBounds::empty(),
|
||||
methods: ~[
|
||||
MethodDef {
|
||||
name: "from_int",
|
||||
name: "from_i64",
|
||||
generics: LifetimeBounds::empty(),
|
||||
explicit_self: None,
|
||||
args: ~[
|
||||
Literal(Path::new(~["int"])),
|
||||
Literal(Path::new(~["i64"])),
|
||||
],
|
||||
ret_ty: Literal(Path::new_(~["std", "option", "Option"],
|
||||
None,
|
||||
~[~Self],
|
||||
true)),
|
||||
const_nonmatching: false,
|
||||
combine_substructure: |c, s, sub| cs_from("int", c, s, sub),
|
||||
combine_substructure: |c, s, sub| cs_from("i64", c, s, sub),
|
||||
},
|
||||
MethodDef {
|
||||
name: "from_uint",
|
||||
name: "from_u64",
|
||||
generics: LifetimeBounds::empty(),
|
||||
explicit_self: None,
|
||||
args: ~[
|
||||
Literal(Path::new(~["uint"])),
|
||||
Literal(Path::new(~["u64"])),
|
||||
],
|
||||
ret_ty: Literal(Path::new_(~["std", "option", "Option"],
|
||||
None,
|
||||
~[~Self],
|
||||
true)),
|
||||
const_nonmatching: false,
|
||||
combine_substructure: |c, s, sub| cs_from("uint", c, s, sub),
|
||||
combine_substructure: |c, s, sub| cs_from("u64", c, s, sub),
|
||||
},
|
||||
]
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user