1
Fork 0

auto merge of #18827 : bjz/rust/rfc369-numerics, r=alexcrichton

This implements a considerable portion of rust-lang/rfcs#369 (tracked in #18640). Some interpretations had to be made in order to get this to work. The breaking changes are listed below:

[breaking-change]

- `core::num::{Num, Unsigned, Primitive}` have been deprecated and their re-exports removed from the `{std, core}::prelude`.
- `core::num::{Zero, One, Bounded}` have been deprecated. Use the static methods on `core::num::{Float, Int}` instead. There is no equivalent to `Zero::is_zero`. Use `(==)` with `{Float, Int}::zero` instead.
- `Signed::abs_sub` has been moved to `std::num::FloatMath`, and is no longer implemented for signed integers.
- `core::num::Signed` has been removed, and its methods have been moved to `core::num::Float` and a new trait, `core::num::SignedInt`. The methods now take the `self` parameter by value.
- `core::num::{Saturating, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv}` have been removed, and their methods moved to `core::num::Int`. Their parameters are now taken by value. This means that
- `std::time::Duration` no longer implements `core::num::{Zero, CheckedAdd, CheckedSub}` instead defining the required methods non-polymorphically.
- `core::num::{zero, one, abs, signum}` have been deprecated. Use their respective methods instead.
- The `core::num::{next_power_of_two, is_power_of_two, checked_next_power_of_two}` functions have been deprecated in favor of methods defined a new trait, `core::num::UnsignedInt`
- `core::iter::{AdditiveIterator, MultiplicativeIterator}` are now only implemented for the built-in numeric types.
- `core::iter::{range, range_inclusive, range_step, range_step_inclusive}` now require `core::num::Int` to be implemented for the type they a re parametrized over.
This commit is contained in:
bors 2014-11-14 05:37:17 +00:00
commit 6f7081fad5
77 changed files with 1136 additions and 1035 deletions

View file

@ -51,6 +51,7 @@ expensive. So we'd like to define a function that takes the points just as
a reference. a reference.
~~~ ~~~
# use std::num::Float;
# struct Point {x: f64, y: f64} # struct Point {x: f64, y: f64}
# fn sqrt(f: f64) -> f64 { 0.0 } # fn sqrt(f: f64) -> f64 { 0.0 }
fn compute_distance(p1: &Point, p2: &Point) -> f64 { fn compute_distance(p1: &Point, p2: &Point) -> f64 {

View file

@ -225,6 +225,7 @@ Here is another example showing how futures allow you to background
computations. The workload will be distributed on the available cores. computations. The workload will be distributed on the available cores.
```{rust} ```{rust}
# use std::num::Float;
# use std::sync::Future; # use std::sync::Future;
fn partial_sum(start: uint) -> f64 { fn partial_sum(start: uint) -> f64 {
let mut local_sum = 0f64; let mut local_sum = 0f64;
@ -262,6 +263,7 @@ several computations on a single large vector of floats. Each task needs the
full vector to perform its duty. full vector to perform its duty.
```{rust} ```{rust}
use std::num::Float;
use std::rand; use std::rand;
use std::sync::Arc; use std::sync::Arc;

View file

@ -97,8 +97,7 @@ syn keyword rustTrait FromIterator IntoIterator Extend ExactSize
syn keyword rustTrait Iterator DoubleEndedIterator syn keyword rustTrait Iterator DoubleEndedIterator
syn keyword rustTrait RandomAccessIterator CloneableIterator syn keyword rustTrait RandomAccessIterator CloneableIterator
syn keyword rustTrait OrdIterator MutableDoubleEndedIterator syn keyword rustTrait OrdIterator MutableDoubleEndedIterator
syn keyword rustTrait Num NumCast CheckedAdd CheckedSub CheckedMul CheckedDiv syn keyword rustTrait NumCast Int SignedInt UnsignedInt Float
syn keyword rustTrait Signed Unsigned Primitive Int Float
syn keyword rustTrait FloatMath ToPrimitive FromPrimitive syn keyword rustTrait FloatMath ToPrimitive FromPrimitive
syn keyword rustTrait Box syn keyword rustTrait Box
syn keyword rustTrait GenericPath Path PosixPath WindowsPath syn keyword rustTrait GenericPath Path PosixPath WindowsPath

View file

@ -38,7 +38,7 @@ use std::cmp;
use std::intrinsics::{TyDesc, get_tydesc}; use std::intrinsics::{TyDesc, get_tydesc};
use std::intrinsics; use std::intrinsics;
use std::mem; use std::mem;
use std::num; use std::num::{Int, UnsignedInt};
use std::ptr; use std::ptr;
use std::rc::Rc; use std::rc::Rc;
use std::rt::heap::{allocate, deallocate}; use std::rt::heap::{allocate, deallocate};
@ -132,7 +132,7 @@ impl Drop for Arena {
#[inline] #[inline]
fn round_up(base: uint, align: uint) -> uint { fn round_up(base: uint, align: uint) -> uint {
(base.checked_add(&(align - 1))).unwrap() & !(align - 1) (base.checked_add(align - 1)).unwrap() & !(align - 1)
} }
// Walk down a chunk, running the destructors for any objects stored // Walk down a chunk, running the destructors for any objects stored
@ -187,7 +187,7 @@ impl Arena {
self.chunks.borrow_mut().push(self.copy_head.borrow().clone()); self.chunks.borrow_mut().push(self.copy_head.borrow().clone());
*self.copy_head.borrow_mut() = *self.copy_head.borrow_mut() =
chunk(num::next_power_of_two(new_min_chunk_size + 1u), true); chunk((new_min_chunk_size + 1u).next_power_of_two(), true);
return self.alloc_copy_inner(n_bytes, align); return self.alloc_copy_inner(n_bytes, align);
} }
@ -228,7 +228,7 @@ impl Arena {
self.chunks.borrow_mut().push(self.head.borrow().clone()); self.chunks.borrow_mut().push(self.head.borrow().clone());
*self.head.borrow_mut() = *self.head.borrow_mut() =
chunk(num::next_power_of_two(new_min_chunk_size + 1u), false); chunk((new_min_chunk_size + 1u).next_power_of_two(), false);
return self.alloc_noncopy_inner(n_bytes, align); return self.alloc_noncopy_inner(n_bytes, align);
} }
@ -376,8 +376,8 @@ fn calculate_size<T>(capacity: uint) -> uint {
let mut size = mem::size_of::<TypedArenaChunk<T>>(); let mut size = mem::size_of::<TypedArenaChunk<T>>();
size = round_up(size, mem::min_align_of::<T>()); size = round_up(size, mem::min_align_of::<T>());
let elem_size = mem::size_of::<T>(); let elem_size = mem::size_of::<T>();
let elems_size = elem_size.checked_mul(&capacity).unwrap(); let elems_size = elem_size.checked_mul(capacity).unwrap();
size = size.checked_add(&elems_size).unwrap(); size = size.checked_add(elems_size).unwrap();
size size
} }
@ -432,7 +432,7 @@ impl<T> TypedArenaChunk<T> {
#[inline] #[inline]
fn end(&self) -> *const u8 { fn end(&self) -> *const u8 {
unsafe { unsafe {
let size = mem::size_of::<T>().checked_mul(&self.capacity).unwrap(); let size = mem::size_of::<T>().checked_mul(self.capacity).unwrap();
self.start().offset(size as int) self.start().offset(size as int)
} }
} }
@ -481,7 +481,7 @@ impl<T> TypedArena<T> {
fn grow(&self) { fn grow(&self) {
unsafe { unsafe {
let chunk = *self.first.borrow_mut(); let chunk = *self.first.borrow_mut();
let new_capacity = (*chunk).capacity.checked_mul(&2).unwrap(); let new_capacity = (*chunk).capacity.checked_mul(2).unwrap();
let chunk = TypedArenaChunk::<T>::new(chunk, new_capacity); let chunk = TypedArenaChunk::<T>::new(chunk, new_capacity);
self.ptr.set((*chunk).start() as *const T); self.ptr.set((*chunk).start() as *const T);
self.end.set((*chunk).end() as *const T); self.end.set((*chunk).end() as *const T);

View file

@ -22,6 +22,7 @@
//! //!
//! ``` //! ```
//! use std::collections::{BitvSet, Bitv}; //! use std::collections::{BitvSet, Bitv};
//! use std::num::Float;
//! use std::iter; //! use std::iter;
//! //!
//! let max_prime = 10000; //! let max_prime = 10000;
@ -69,6 +70,7 @@ use core::default::Default;
use core::fmt; use core::fmt;
use core::iter::{Chain, Enumerate, Repeat, Skip, Take}; use core::iter::{Chain, Enumerate, Repeat, Skip, Take};
use core::iter; use core::iter;
use core::num::Int;
use core::slice; use core::slice;
use core::u32; use core::u32;
use std::hash; use std::hash;

View file

@ -15,6 +15,7 @@
use core::prelude::*; use core::prelude::*;
use core::fmt; use core::fmt;
use core::num::Int;
// FIXME(contentions): implement union family of methods? (general design may be wrong here) // FIXME(contentions): implement union family of methods? (general design may be wrong here)

View file

@ -69,6 +69,7 @@ use alloc::boxed::Box;
use alloc::rc::Rc; use alloc::rc::Rc;
use core::intrinsics::TypeId; use core::intrinsics::TypeId;
use core::mem; use core::mem;
use core::num::Int;
use vec::Vec; use vec::Vec;

View file

@ -21,7 +21,7 @@ use core::default::Default;
use core::fmt; use core::fmt;
use core::kinds::marker::{ContravariantLifetime, InvariantType}; use core::kinds::marker::{ContravariantLifetime, InvariantType};
use core::mem; use core::mem;
use core::num; use core::num::{Int, UnsignedInt};
use core::ops; use core::ops;
use core::ptr; use core::ptr;
use core::raw::Slice as RawSlice; use core::raw::Slice as RawSlice;
@ -161,7 +161,7 @@ impl<T> Vec<T> {
} else if capacity == 0 { } else if capacity == 0 {
Vec::new() Vec::new()
} else { } else {
let size = capacity.checked_mul(&mem::size_of::<T>()) let size = capacity.checked_mul(mem::size_of::<T>())
.expect("capacity overflow"); .expect("capacity overflow");
let ptr = unsafe { allocate(size, mem::min_align_of::<T>()) }; let ptr = unsafe { allocate(size, mem::min_align_of::<T>()) };
Vec { ptr: ptr as *mut T, len: 0, cap: capacity } Vec { ptr: ptr as *mut T, len: 0, cap: capacity }
@ -587,11 +587,11 @@ impl<T> Vec<T> {
#[unstable = "matches collection reform specification, waiting for dust to settle"] #[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn reserve(&mut self, additional: uint) { pub fn reserve(&mut self, additional: uint) {
if self.cap - self.len < additional { if self.cap - self.len < additional {
match self.len.checked_add(&additional) { match self.len.checked_add(additional) {
None => panic!("Vec::reserve: `uint` overflow"), None => panic!("Vec::reserve: `uint` overflow"),
// if the checked_add // if the checked_add
Some(new_cap) => { Some(new_cap) => {
let amort_cap = num::next_power_of_two(new_cap); let amort_cap = new_cap.next_power_of_two();
// next_power_of_two will overflow to exactly 0 for really big capacities // next_power_of_two will overflow to exactly 0 for really big capacities
if amort_cap == 0 { if amort_cap == 0 {
self.grow_capacity(new_cap); self.grow_capacity(new_cap);
@ -624,7 +624,7 @@ impl<T> Vec<T> {
#[unstable = "matches collection reform specification, waiting for dust to settle"] #[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn reserve_exact(&mut self, additional: uint) { pub fn reserve_exact(&mut self, additional: uint) {
if self.cap - self.len < additional { if self.cap - self.len < additional {
match self.len.checked_add(&additional) { match self.len.checked_add(additional) {
None => panic!("Vec::reserve: `uint` overflow"), None => panic!("Vec::reserve: `uint` overflow"),
Some(new_cap) => self.grow_capacity(new_cap) Some(new_cap) => self.grow_capacity(new_cap)
} }
@ -957,7 +957,7 @@ impl<T> Vec<T> {
pub fn push(&mut self, value: T) { pub fn push(&mut self, value: T) {
if mem::size_of::<T>() == 0 { if mem::size_of::<T>() == 0 {
// zero-size types consume no memory, so we can't rely on the address space running out // zero-size types consume no memory, so we can't rely on the address space running out
self.len = self.len.checked_add(&1).expect("length overflow"); self.len = self.len.checked_add(1).expect("length overflow");
unsafe { mem::forget(value); } unsafe { mem::forget(value); }
return return
} }
@ -1050,7 +1050,7 @@ impl<T> Vec<T> {
if mem::size_of::<T>() == 0 { return } if mem::size_of::<T>() == 0 { return }
if capacity > self.cap { if capacity > self.cap {
let size = capacity.checked_mul(&mem::size_of::<T>()) let size = capacity.checked_mul(mem::size_of::<T>())
.expect("capacity overflow"); .expect("capacity overflow");
unsafe { unsafe {
self.ptr = alloc_or_realloc(self.ptr, self.cap * mem::size_of::<T>(), size); self.ptr = alloc_or_realloc(self.ptr, self.cap * mem::size_of::<T>(), size);

View file

@ -19,6 +19,8 @@
//! operators, you could do the following: //! operators, you could do the following:
//! //!
//! ```rust //! ```rust
//! use core::num::SignedInt;
//!
//! // Our type. //! // Our type.
//! struct SketchyNum { //! struct SketchyNum {
//! num : int //! num : int

View file

@ -13,8 +13,8 @@
use char; use char;
use fmt; use fmt;
use iter::{range, DoubleEndedIterator}; use iter::{range, DoubleEndedIterator};
use num::{Float, FPNaN, FPInfinite, ToPrimitive, Primitive}; use num::{Float, FPNaN, FPInfinite, ToPrimitive};
use num::{Zero, One, cast}; use num::cast;
use result::Ok; use result::Ok;
use slice::{mod, SlicePrelude}; use slice::{mod, SlicePrelude};
use str::StrPrelude; use str::StrPrelude;
@ -79,7 +79,7 @@ static DIGIT_E_RADIX: uint = ('e' as uint) - ('a' as uint) + 11u;
* - Fails if `radix` > 25 and `exp_format` is `ExpBin` due to conflict * - Fails if `radix` > 25 and `exp_format` is `ExpBin` due to conflict
* between digit and exponent sign `'p'`. * between digit and exponent sign `'p'`.
*/ */
pub fn float_to_str_bytes_common<T: Primitive + Float, U>( pub fn float_to_str_bytes_common<T: Float, U>(
num: T, num: T,
radix: uint, radix: uint,
negative_zero: bool, negative_zero: bool,
@ -97,8 +97,8 @@ pub fn float_to_str_bytes_common<T: Primitive + Float, U>(
_ => () _ => ()
} }
let _0: T = Zero::zero(); let _0: T = Float::zero();
let _1: T = One::one(); let _1: T = Float::one();
match num.classify() { match num.classify() {
FPNaN => return f("NaN".as_bytes()), FPNaN => return f("NaN".as_bytes()),

View file

@ -620,7 +620,7 @@ impl<'a, T> Pointer for &'a mut T {
macro_rules! floating(($ty:ident) => { macro_rules! floating(($ty:ident) => {
impl Float for $ty { impl Float for $ty {
fn fmt(&self, fmt: &mut Formatter) -> Result { fn fmt(&self, fmt: &mut Formatter) -> Result {
use num::{Float, Signed}; use num::Float;
let digits = match fmt.precision { let digits = match fmt.precision {
Some(i) => float::DigExact(i), Some(i) => float::DigExact(i),
@ -641,7 +641,7 @@ macro_rules! floating(($ty:ident) => {
impl LowerExp for $ty { impl LowerExp for $ty {
fn fmt(&self, fmt: &mut Formatter) -> Result { fn fmt(&self, fmt: &mut Formatter) -> Result {
use num::{Float, Signed}; use num::Float;
let digits = match fmt.precision { let digits = match fmt.precision {
Some(i) => float::DigExact(i), Some(i) => float::DigExact(i),
@ -662,7 +662,7 @@ macro_rules! floating(($ty:ident) => {
impl UpperExp for $ty { impl UpperExp for $ty {
fn fmt(&self, fmt: &mut Formatter) -> Result { fn fmt(&self, fmt: &mut Formatter) -> Result {
use num::{Float, Signed}; use num::Float;
let digits = match fmt.precision { let digits = match fmt.precision {
Some(i) => float::DigExact(i), Some(i) => float::DigExact(i),

View file

@ -16,7 +16,7 @@
use fmt; use fmt;
use iter::DoubleEndedIterator; use iter::DoubleEndedIterator;
use num::{Int, cast, zero}; use num::{Int, cast};
use slice::SlicePrelude; use slice::SlicePrelude;
/// A type that represents a specific radix /// A type that represents a specific radix
@ -35,10 +35,11 @@ trait GenericRadix {
fn fmt_int<T: Int>(&self, mut x: T, f: &mut fmt::Formatter) -> fmt::Result { fn fmt_int<T: Int>(&self, mut x: T, f: &mut fmt::Formatter) -> fmt::Result {
// The radix can be as low as 2, so we need a buffer of at least 64 // The radix can be as low as 2, so we need a buffer of at least 64
// characters for a base 2 number. // characters for a base 2 number.
let zero = Int::zero();
let is_positive = x >= zero;
let mut buf = [0u8, ..64]; let mut buf = [0u8, ..64];
let base = cast(self.base()).unwrap();
let mut curr = buf.len(); let mut curr = buf.len();
let is_positive = x >= zero(); let base = cast(self.base()).unwrap();
if is_positive { if is_positive {
// Accumulate each digit of the number from the least significant // Accumulate each digit of the number from the least significant
// to the most significant figure. // to the most significant figure.
@ -47,16 +48,16 @@ trait GenericRadix {
x = x / base; // Deaccumulate the number. x = x / base; // Deaccumulate the number.
*byte = self.digit(cast(n).unwrap()); // Store the digit in the buffer. *byte = self.digit(cast(n).unwrap()); // Store the digit in the buffer.
curr -= 1; curr -= 1;
if x == zero() { break; } // No more digits left to accumulate. if x == zero { break }; // No more digits left to accumulate.
} }
} else { } else {
// Do the same as above, but accounting for two's complement. // Do the same as above, but accounting for two's complement.
for byte in buf.iter_mut().rev() { for byte in buf.iter_mut().rev() {
let n = -(x % base); // Get the current place value. let n = zero - (x % base); // Get the current place value.
x = x / base; // Deaccumulate the number. x = x / base; // Deaccumulate the number.
*byte = self.digit(cast(n).unwrap()); // Store the digit in the buffer. *byte = self.digit(cast(n).unwrap()); // Store the digit in the buffer.
curr -= 1; curr -= 1;
if x == zero() { break; } // No more digits left to accumulate. if x == zero { break }; // No more digits left to accumulate.
} }
} }
f.pad_integral(is_positive, self.prefix(), buf[curr..]) f.pad_integral(is_positive, self.prefix(), buf[curr..])

View file

@ -60,10 +60,10 @@ This `for` loop syntax can be applied to any iterator over any type.
use clone::Clone; use clone::Clone;
use cmp; use cmp;
use cmp::{PartialEq, PartialOrd, Ord}; use cmp::Ord;
use mem; use mem;
use num::{Zero, One, CheckedAdd, CheckedSub, Saturating, ToPrimitive, Int}; use num::{ToPrimitive, Int};
use ops::{Add, Mul, Sub}; use ops::Add;
use option::{Option, Some, None}; use option::{Option, Some, None};
use uint; use uint;
#[deprecated = "renamed to Extend"] pub use self::Extend as Extendable; #[deprecated = "renamed to Extend"] pub use self::Extend as Extendable;
@ -573,6 +573,8 @@ pub trait Iterator<A> {
/// # Example /// # Example
/// ///
/// ```rust /// ```rust
/// use core::num::SignedInt;
///
/// let xs = [-3i, 0, 1, 5, -10]; /// let xs = [-3i, 0, 1, 5, -10];
/// assert_eq!(*xs.iter().max_by(|x| x.abs()).unwrap(), -10); /// assert_eq!(*xs.iter().max_by(|x| x.abs()).unwrap(), -10);
/// ``` /// ```
@ -597,6 +599,8 @@ pub trait Iterator<A> {
/// # Example /// # Example
/// ///
/// ```rust /// ```rust
/// use core::num::SignedInt;
///
/// let xs = [-3i, 0, 1, 5, -10]; /// let xs = [-3i, 0, 1, 5, -10];
/// assert_eq!(*xs.iter().min_by(|x| x.abs()).unwrap(), 0); /// assert_eq!(*xs.iter().min_by(|x| x.abs()).unwrap(), 0);
/// ``` /// ```
@ -785,13 +789,28 @@ pub trait AdditiveIterator<A> {
fn sum(&mut self) -> A; fn sum(&mut self) -> A;
} }
impl<A: Add<A, A> + Zero, T: Iterator<A>> AdditiveIterator<A> for T { macro_rules! impl_additive {
#[inline] ($A:ty, $init:expr) => {
fn sum(&mut self) -> A { impl<T: Iterator<$A>> AdditiveIterator<$A> for T {
let zero: A = Zero::zero(); #[inline]
self.fold(zero, |s, x| s + x) fn sum(&mut self) -> $A {
} self.fold($init, |acc, x| acc + x)
}
}
};
} }
impl_additive!(i8, 0)
impl_additive!(i16, 0)
impl_additive!(i32, 0)
impl_additive!(i64, 0)
impl_additive!(int, 0)
impl_additive!(u8, 0)
impl_additive!(u16, 0)
impl_additive!(u32, 0)
impl_additive!(u64, 0)
impl_additive!(uint, 0)
impl_additive!(f32, 0.0)
impl_additive!(f64, 0.0)
/// A trait for iterators over elements which can be multiplied together. /// A trait for iterators over elements which can be multiplied together.
pub trait MultiplicativeIterator<A> { pub trait MultiplicativeIterator<A> {
@ -812,13 +831,28 @@ pub trait MultiplicativeIterator<A> {
fn product(&mut self) -> A; fn product(&mut self) -> A;
} }
impl<A: Mul<A, A> + One, T: Iterator<A>> MultiplicativeIterator<A> for T { macro_rules! impl_multiplicative {
#[inline] ($A:ty, $init:expr) => {
fn product(&mut self) -> A { impl<T: Iterator<$A>> MultiplicativeIterator<$A> for T {
let one: A = One::one(); #[inline]
self.fold(one, |p, x| p * x) fn product(&mut self) -> $A {
} self.fold($init, |acc, x| acc * x)
}
}
};
} }
impl_multiplicative!(i8, 1)
impl_multiplicative!(i16, 1)
impl_multiplicative!(i32, 1)
impl_multiplicative!(i64, 1)
impl_multiplicative!(int, 1)
impl_multiplicative!(u8, 1)
impl_multiplicative!(u16, 1)
impl_multiplicative!(u32, 1)
impl_multiplicative!(u64, 1)
impl_multiplicative!(uint, 1)
impl_multiplicative!(f32, 1.0)
impl_multiplicative!(f64, 1.0)
/// A trait for iterators over elements which can be compared to one another. /// A trait for iterators over elements which can be compared to one another.
pub trait OrdIterator<A> { pub trait OrdIterator<A> {
@ -1093,7 +1127,7 @@ impl<A, T: Iterator<A>, U: Iterator<A>> Iterator<A> for Chain<T, U> {
let lower = a_lower.saturating_add(b_lower); let lower = a_lower.saturating_add(b_lower);
let upper = match (a_upper, b_upper) { let upper = match (a_upper, b_upper) {
(Some(x), Some(y)) => x.checked_add(&y), (Some(x), Some(y)) => x.checked_add(y),
_ => None _ => None
}; };
@ -1415,7 +1449,7 @@ impl<A, T: Iterator<A>> Iterator<A> for Peekable<A, T> {
if self.peeked.is_some() { if self.peeked.is_some() {
let lo = lo.saturating_add(1); let lo = lo.saturating_add(1);
let hi = match hi { let hi = match hi {
Some(x) => x.checked_add(&1), Some(x) => x.checked_add(1),
None => None None => None
}; };
(lo, hi) (lo, hi)
@ -1680,7 +1714,7 @@ impl<'a, A, T: Iterator<A>, B, U: Iterator<B>> Iterator<B> for FlatMap<'a, A, T,
let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), |it| it.size_hint()); let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), |it| it.size_hint());
let lo = flo.saturating_add(blo); let lo = flo.saturating_add(blo);
match (self.iter.size_hint(), fhi, bhi) { match (self.iter.size_hint(), fhi, bhi) {
((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(&b)), ((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(b)),
_ => (lo, None) _ => (lo, None)
} }
} }
@ -1905,7 +1939,7 @@ impl<A: Add<A, A> + Clone> Iterator<A> for Counter<A> {
pub struct Range<A> { pub struct Range<A> {
state: A, state: A,
stop: A, stop: A,
one: A one: A,
} }
/// Returns an iterator over the given range [start, stop) (that is, starting /// Returns an iterator over the given range [start, stop) (that is, starting
@ -1922,12 +1956,16 @@ pub struct Range<A> {
/// } /// }
/// ``` /// ```
#[inline] #[inline]
pub fn range<A: Add<A, A> + PartialOrd + Clone + One>(start: A, stop: A) -> Range<A> { pub fn range<A: Int>(start: A, stop: A) -> Range<A> {
Range{state: start, stop: stop, one: One::one()} Range {
state: start,
stop: stop,
one: Int::one(),
}
} }
// FIXME: #10414: Unfortunate type bound // FIXME: #10414: Unfortunate type bound
impl<A: Add<A, A> + PartialOrd + Clone + ToPrimitive> Iterator<A> for Range<A> { impl<A: Int + ToPrimitive> Iterator<A> for Range<A> {
#[inline] #[inline]
fn next(&mut self) -> Option<A> { fn next(&mut self) -> Option<A> {
if self.state < self.stop { if self.state < self.stop {
@ -1946,7 +1984,7 @@ impl<A: Add<A, A> + PartialOrd + Clone + ToPrimitive> Iterator<A> for Range<A> {
// the i64/u64 might lie within their range. // the i64/u64 might lie within their range.
let bound = match self.state.to_i64() { let bound = match self.state.to_i64() {
Some(a) => { Some(a) => {
let sz = self.stop.to_i64().map(|b| b.checked_sub(&a)); let sz = self.stop.to_i64().map(|b| b.checked_sub(a));
match sz { match sz {
Some(Some(bound)) => bound.to_uint(), Some(Some(bound)) => bound.to_uint(),
_ => None, _ => None,
@ -1954,7 +1992,7 @@ impl<A: Add<A, A> + PartialOrd + Clone + ToPrimitive> Iterator<A> for Range<A> {
}, },
None => match self.state.to_u64() { None => match self.state.to_u64() {
Some(a) => { Some(a) => {
let sz = self.stop.to_u64().map(|b| b.checked_sub(&a)); let sz = self.stop.to_u64().map(|b| b.checked_sub(a));
match sz { match sz {
Some(Some(bound)) => bound.to_uint(), Some(Some(bound)) => bound.to_uint(),
_ => None _ => None
@ -1974,7 +2012,7 @@ impl<A: Add<A, A> + PartialOrd + Clone + ToPrimitive> Iterator<A> for Range<A> {
/// `Int` is required to ensure the range will be the same regardless of /// `Int` is required to ensure the range will be the same regardless of
/// the direction it is consumed. /// the direction it is consumed.
impl<A: Int + PartialOrd + Clone + ToPrimitive> DoubleEndedIterator<A> for Range<A> { impl<A: Int + ToPrimitive> DoubleEndedIterator<A> for Range<A> {
#[inline] #[inline]
fn next_back(&mut self) -> Option<A> { fn next_back(&mut self) -> Option<A> {
if self.stop > self.state { if self.stop > self.state {
@ -1995,12 +2033,14 @@ pub struct RangeInclusive<A> {
/// Return an iterator over the range [start, stop] /// Return an iterator over the range [start, stop]
#[inline] #[inline]
pub fn range_inclusive<A: Add<A, A> + PartialOrd + Clone + One>(start: A, stop: A) pub fn range_inclusive<A: Int>(start: A, stop: A) -> RangeInclusive<A> {
-> RangeInclusive<A> { RangeInclusive {
RangeInclusive{range: range(start, stop), done: false} range: range(start, stop),
done: false,
}
} }
impl<A: Add<A, A> + PartialOrd + Clone + ToPrimitive> Iterator<A> for RangeInclusive<A> { impl<A: Int + ToPrimitive> Iterator<A> for RangeInclusive<A> {
#[inline] #[inline]
fn next(&mut self) -> Option<A> { fn next(&mut self) -> Option<A> {
match self.range.next() { match self.range.next() {
@ -2024,7 +2064,7 @@ impl<A: Add<A, A> + PartialOrd + Clone + ToPrimitive> Iterator<A> for RangeInclu
} else { } else {
let lo = lo.saturating_add(1); let lo = lo.saturating_add(1);
let hi = match hi { let hi = match hi {
Some(x) => x.checked_add(&1), Some(x) => x.checked_add(1),
None => None None => None
}; };
(lo, hi) (lo, hi)
@ -2032,8 +2072,7 @@ impl<A: Add<A, A> + PartialOrd + Clone + ToPrimitive> Iterator<A> for RangeInclu
} }
} }
impl<A: Sub<A, A> + Int + PartialOrd + Clone + ToPrimitive> DoubleEndedIterator<A> impl<A: Int + ToPrimitive> DoubleEndedIterator<A> for RangeInclusive<A> {
for RangeInclusive<A> {
#[inline] #[inline]
fn next_back(&mut self) -> Option<A> { fn next_back(&mut self) -> Option<A> {
if self.range.stop > self.range.state { if self.range.stop > self.range.state {
@ -2060,18 +2099,17 @@ pub struct RangeStep<A> {
/// Return an iterator over the range [start, stop) by `step`. It handles overflow by stopping. /// Return an iterator over the range [start, stop) by `step`. It handles overflow by stopping.
#[inline] #[inline]
pub fn range_step<A: CheckedAdd + PartialOrd + pub fn range_step<A: Int>(start: A, stop: A, step: A) -> RangeStep<A> {
Clone + Zero>(start: A, stop: A, step: A) -> RangeStep<A> { let rev = step < Int::zero();
let rev = step < Zero::zero();
RangeStep{state: start, stop: stop, step: step, rev: rev} RangeStep{state: start, stop: stop, step: step, rev: rev}
} }
impl<A: CheckedAdd + PartialOrd + Clone> Iterator<A> for RangeStep<A> { impl<A: Int> Iterator<A> for RangeStep<A> {
#[inline] #[inline]
fn next(&mut self) -> Option<A> { fn next(&mut self) -> Option<A> {
if (self.rev && self.state > self.stop) || (!self.rev && self.state < self.stop) { if (self.rev && self.state > self.stop) || (!self.rev && self.state < self.stop) {
let result = self.state.clone(); let result = self.state;
match self.state.checked_add(&self.step) { match self.state.checked_add(self.step) {
Some(x) => self.state = x, Some(x) => self.state = x,
None => self.state = self.stop.clone() None => self.state = self.stop.clone()
} }
@ -2094,19 +2132,24 @@ pub struct RangeStepInclusive<A> {
/// Return an iterator over the range [start, stop] by `step`. It handles overflow by stopping. /// Return an iterator over the range [start, stop] by `step`. It handles overflow by stopping.
#[inline] #[inline]
pub fn range_step_inclusive<A: CheckedAdd + PartialOrd + Clone + Zero>(start: A, stop: A, pub fn range_step_inclusive<A: Int>(start: A, stop: A, step: A) -> RangeStepInclusive<A> {
step: A) -> RangeStepInclusive<A> { let rev = step < Int::zero();
let rev = step < Zero::zero(); RangeStepInclusive {
RangeStepInclusive{state: start, stop: stop, step: step, rev: rev, done: false} state: start,
stop: stop,
step: step,
rev: rev,
done: false,
}
} }
impl<A: CheckedAdd + PartialOrd + Clone + PartialEq> Iterator<A> for RangeStepInclusive<A> { impl<A: Int> Iterator<A> for RangeStepInclusive<A> {
#[inline] #[inline]
fn next(&mut self) -> Option<A> { fn next(&mut self) -> Option<A> {
if !self.done && ((self.rev && self.state >= self.stop) || if !self.done && ((self.rev && self.state >= self.stop) ||
(!self.rev && self.state <= self.stop)) { (!self.rev && self.state <= self.stop)) {
let result = self.state.clone(); let result = self.state;
match self.state.checked_add(&self.step) { match self.state.checked_add(self.step) {
Some(x) => self.state = x, Some(x) => self.state = x,
None => self.done = true None => self.done = true
} }

View file

@ -114,9 +114,15 @@ impl Float for f32 {
#[inline] #[inline]
fn neg_infinity() -> f32 { NEG_INFINITY } fn neg_infinity() -> f32 { NEG_INFINITY }
#[inline]
fn zero() -> f32 { 0.0 }
#[inline] #[inline]
fn neg_zero() -> f32 { -0.0 } fn neg_zero() -> f32 { -0.0 }
#[inline]
fn one() -> f32 { 1.0 }
/// Returns `true` if the number is NaN. /// Returns `true` if the number is NaN.
#[inline] #[inline]
fn is_nan(self) -> bool { self != self } fn is_nan(self) -> bool { self != self }
@ -177,9 +183,15 @@ impl Float for f32 {
#[inline] #[inline]
fn max_10_exp(_: Option<f32>) -> int { MAX_10_EXP } fn max_10_exp(_: Option<f32>) -> int { MAX_10_EXP }
#[inline]
fn min_value() -> f32 { MIN_VALUE }
#[inline] #[inline]
fn min_pos_value(_: Option<f32>) -> f32 { MIN_POS_VALUE } fn min_pos_value(_: Option<f32>) -> f32 { MIN_POS_VALUE }
#[inline]
fn max_value() -> f32 { MAX_VALUE }
/// Returns the mantissa, exponent and sign as integers. /// Returns the mantissa, exponent and sign as integers.
fn integer_decode(self) -> (u64, i16, i8) { fn integer_decode(self) -> (u64, i16, i8) {
let bits: u32 = unsafe { mem::transmute(self) }; let bits: u32 = unsafe { mem::transmute(self) };
@ -222,12 +234,49 @@ impl Float for f32 {
/// The fractional part of the number, satisfying: /// The fractional part of the number, satisfying:
/// ///
/// ```rust /// ```rust
/// use core::num::Float;
///
/// let x = 1.65f32; /// let x = 1.65f32;
/// assert!(x == x.trunc() + x.fract()) /// assert!(x == x.trunc() + x.fract())
/// ``` /// ```
#[inline] #[inline]
fn fract(self) -> f32 { self - self.trunc() } fn fract(self) -> f32 { self - self.trunc() }
/// Computes the absolute value of `self`. Returns `Float::nan()` if the
/// number is `Float::nan()`.
#[inline]
fn abs(self) -> f32 {
unsafe { intrinsics::fabsf32(self) }
}
/// Returns a number that represents the sign of `self`.
///
/// - `1.0` if the number is positive, `+0.0` or `Float::infinity()`
/// - `-1.0` if the number is negative, `-0.0` or `Float::neg_infinity()`
/// - `Float::nan()` if the number is `Float::nan()`
#[inline]
fn signum(self) -> f32 {
if self.is_nan() {
Float::nan()
} else {
unsafe { intrinsics::copysignf32(1.0, self) }
}
}
/// Returns `true` if `self` is positive, including `+0.0` and
/// `Float::infinity()`.
#[inline]
fn is_positive(self) -> bool {
self > 0.0 || (1.0 / self) == Float::infinity()
}
/// Returns `true` if `self` is negative, including `-0.0` and
/// `Float::neg_infinity()`.
#[inline]
fn is_negative(self) -> bool {
self < 0.0 || (1.0 / self) == Float::neg_infinity()
}
/// Fused multiply-add. Computes `(self * a) + b` with only one rounding /// Fused multiply-add. Computes `(self * a) + b` with only one rounding
/// error. This produces a more accurate result with better performance than /// error. This produces a more accurate result with better performance than
/// a separate multiplication operation followed by an add. /// a separate multiplication operation followed by an add.
@ -240,6 +289,7 @@ impl Float for f32 {
#[inline] #[inline]
fn recip(self) -> f32 { 1.0 / self } fn recip(self) -> f32 { 1.0 / self }
#[inline]
fn powi(self, n: i32) -> f32 { fn powi(self, n: i32) -> f32 {
unsafe { intrinsics::powif32(self, n) } unsafe { intrinsics::powif32(self, n) }
} }

View file

@ -120,9 +120,15 @@ impl Float for f64 {
#[inline] #[inline]
fn neg_infinity() -> f64 { NEG_INFINITY } fn neg_infinity() -> f64 { NEG_INFINITY }
#[inline]
fn zero() -> f64 { 0.0 }
#[inline] #[inline]
fn neg_zero() -> f64 { -0.0 } fn neg_zero() -> f64 { -0.0 }
#[inline]
fn one() -> f64 { 1.0 }
/// Returns `true` if the number is NaN. /// Returns `true` if the number is NaN.
#[inline] #[inline]
fn is_nan(self) -> bool { self != self } fn is_nan(self) -> bool { self != self }
@ -183,9 +189,15 @@ impl Float for f64 {
#[inline] #[inline]
fn max_10_exp(_: Option<f64>) -> int { MAX_10_EXP } fn max_10_exp(_: Option<f64>) -> int { MAX_10_EXP }
#[inline]
fn min_value() -> f64 { MIN_VALUE }
#[inline] #[inline]
fn min_pos_value(_: Option<f64>) -> f64 { MIN_POS_VALUE } fn min_pos_value(_: Option<f64>) -> f64 { MIN_POS_VALUE }
#[inline]
fn max_value() -> f64 { MAX_VALUE }
/// Returns the mantissa, exponent and sign as integers. /// Returns the mantissa, exponent and sign as integers.
fn integer_decode(self) -> (u64, i16, i8) { fn integer_decode(self) -> (u64, i16, i8) {
let bits: u64 = unsafe { mem::transmute(self) }; let bits: u64 = unsafe { mem::transmute(self) };
@ -228,12 +240,49 @@ impl Float for f64 {
/// The fractional part of the number, satisfying: /// The fractional part of the number, satisfying:
/// ///
/// ```rust /// ```rust
/// use core::num::Float;
///
/// let x = 1.65f64; /// let x = 1.65f64;
/// assert!(x == x.trunc() + x.fract()) /// assert!(x == x.trunc() + x.fract())
/// ``` /// ```
#[inline] #[inline]
fn fract(self) -> f64 { self - self.trunc() } fn fract(self) -> f64 { self - self.trunc() }
/// Computes the absolute value of `self`. Returns `Float::nan()` if the
/// number is `Float::nan()`.
#[inline]
fn abs(self) -> f64 {
unsafe { intrinsics::fabsf64(self) }
}
/// Returns a number that represents the sign of `self`.
///
/// - `1.0` if the number is positive, `+0.0` or `Float::infinity()`
/// - `-1.0` if the number is negative, `-0.0` or `Float::neg_infinity()`
/// - `Float::nan()` if the number is `Float::nan()`
#[inline]
fn signum(self) -> f64 {
if self.is_nan() {
Float::nan()
} else {
unsafe { intrinsics::copysignf64(1.0, self) }
}
}
/// Returns `true` if `self` is positive, including `+0.0` and
/// `Float::infinity()`.
#[inline]
fn is_positive(self) -> bool {
self > 0.0 || (1.0 / self) == Float::infinity()
}
/// Returns `true` if `self` is negative, including `-0.0` and
/// `Float::neg_infinity()`.
#[inline]
fn is_negative(self) -> bool {
self < 0.0 || (1.0 / self) == Float::neg_infinity()
}
/// Fused multiply-add. Computes `(self * a) + b` with only one rounding /// Fused multiply-add. Computes `(self * a) + b` with only one rounding
/// error. This produces a more accurate result with better performance than /// error. This produces a more accurate result with better performance than
/// a separate multiplication operation followed by an add. /// a separate multiplication operation followed by an add.

View file

@ -13,6 +13,7 @@
macro_rules! assert_approx_eq( macro_rules! assert_approx_eq(
($a:expr, $b:expr) => ({ ($a:expr, $b:expr) => ({
use num::Float;
let (a, b) = (&$a, &$b); let (a, b) = (&$a, &$b);
assert!((*a - *b).abs() < 1.0e-6, assert!((*a - *b).abs() < 1.0e-6,
"{} is not approximately equal to {}", *a, *b); "{} is not approximately equal to {}", *a, *b);

File diff suppressed because it is too large Load diff

View file

@ -51,9 +51,7 @@ pub use cmp::{Ordering, Less, Equal, Greater, Equiv};
pub use iter::{FromIterator, Extend}; pub use iter::{FromIterator, Extend};
pub use iter::{Iterator, DoubleEndedIterator, RandomAccessIterator, CloneableIterator}; pub use iter::{Iterator, DoubleEndedIterator, RandomAccessIterator, CloneableIterator};
pub use iter::{OrdIterator, MutableDoubleEndedIterator, ExactSize}; pub use iter::{OrdIterator, MutableDoubleEndedIterator, ExactSize};
pub use num::{Num, NumCast, CheckedAdd, CheckedSub, CheckedMul}; pub use num::{ToPrimitive, FromPrimitive};
pub use num::{Signed, Unsigned, Float};
pub use num::{Primitive, Int, ToPrimitive, FromPrimitive};
pub use option::{Option, Some, None}; pub use option::{Option, Some, None};
pub use ptr::RawPtr; pub use ptr::RawPtr;
pub use result::{Result, Ok, Err}; pub use result::{Result, Ok, Err};

View file

@ -40,7 +40,7 @@ use cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering, Less, Equal, Greater, Equiv}
use cmp; use cmp;
use default::Default; use default::Default;
use iter::*; use iter::*;
use num::{CheckedAdd, Saturating, div_rem}; use num::{Int, div_rem};
use ops; use ops;
use option::{None, Option, Some}; use option::{None, Option, Some};
use ptr; use ptr;
@ -1346,7 +1346,7 @@ impl<'a, T> Iterator<&'a [T]> for Windows<'a, T> {
(0, Some(0)) (0, Some(0))
} else { } else {
let x = self.v.len() - self.size; let x = self.v.len() - self.size;
(x.saturating_add(1), x.checked_add(&1u)) (x.saturating_add(1), x.checked_add(1u))
} }
} }
} }

View file

@ -25,7 +25,7 @@ use iter::{Map, Iterator};
use iter::{DoubleEndedIterator, ExactSize}; use iter::{DoubleEndedIterator, ExactSize};
use iter::range; use iter::range;
use kinds::Sized; use kinds::Sized;
use num::{CheckedMul, Saturating}; use num::Int;
use option::{Option, None, Some}; use option::{Option, None, Some};
use raw::Repr; use raw::Repr;
use slice::{mod, SlicePrelude}; use slice::{mod, SlicePrelude};
@ -750,7 +750,7 @@ impl<'a> Iterator<u16> for Utf16CodeUnits<'a> {
// every char gets either one u16 or two u16, // every char gets either one u16 or two u16,
// so this iterator is between 1 or 2 times as // so this iterator is between 1 or 2 times as
// long as the underlying iterator. // long as the underlying iterator.
(low, high.and_then(|n| n.checked_mul(&2))) (low, high.and_then(|n| n.checked_mul(2)))
} }
} }

View file

@ -109,6 +109,8 @@ fn test_partial_max() {
#[test] #[test]
fn test_user_defined_eq() { fn test_user_defined_eq() {
use core::num::SignedInt;
// Our type. // Our type.
struct SketchyNum { struct SketchyNum {
num : int num : int

View file

@ -10,9 +10,9 @@
use core::iter::*; use core::iter::*;
use core::iter::order::*; use core::iter::order::*;
use core::num::SignedInt;
use core::uint; use core::uint;
use core::cmp; use core::cmp;
use core::num;
use core::ops::Slice; use core::ops::Slice;
use test::Bencher; use test::Bencher;
@ -689,50 +689,6 @@ fn test_double_ended_range() {
#[test] #[test]
fn test_range() { fn test_range() {
/// A mock type to check Range when ToPrimitive returns None
struct Foo;
impl ToPrimitive for Foo {
fn to_i64(&self) -> Option<i64> { None }
fn to_u64(&self) -> Option<u64> { None }
}
impl Add<Foo, Foo> for Foo {
fn add(&self, _: &Foo) -> Foo {
Foo
}
}
impl PartialEq for Foo {
fn eq(&self, _: &Foo) -> bool {
true
}
}
impl PartialOrd for Foo {
fn partial_cmp(&self, _: &Foo) -> Option<Ordering> {
None
}
}
impl Clone for Foo {
fn clone(&self) -> Foo {
Foo
}
}
impl Mul<Foo, Foo> for Foo {
fn mul(&self, _: &Foo) -> Foo {
Foo
}
}
impl num::One for Foo {
fn one() -> Foo {
Foo
}
}
assert!(range(0i, 5).collect::<Vec<int>>() == vec![0i, 1, 2, 3, 4]); assert!(range(0i, 5).collect::<Vec<int>>() == vec![0i, 1, 2, 3, 4]);
assert!(range(-10i, -1).collect::<Vec<int>>() == assert!(range(-10i, -1).collect::<Vec<int>>() ==
vec![-10, -9, -8, -7, -6, -5, -4, -3, -2]); vec![-10, -9, -8, -7, -6, -5, -4, -3, -2]);
@ -746,7 +702,6 @@ fn test_range() {
// this test is only meaningful when sizeof uint < sizeof u64 // this test is only meaningful when sizeof uint < sizeof u64
assert_eq!(range(uint::MAX - 1, uint::MAX).size_hint(), (1, Some(1))); assert_eq!(range(uint::MAX - 1, uint::MAX).size_hint(), (1, Some(1)));
assert_eq!(range(-10i, -1).size_hint(), (9, Some(9))); assert_eq!(range(-10i, -1).size_hint(), (9, Some(9)));
assert_eq!(range(Foo, Foo).size_hint(), (0, None));
} }
#[test] #[test]

View file

@ -15,8 +15,8 @@ macro_rules! int_module (($T:ty, $T_i:ident) => (
mod tests { mod tests {
use core::$T_i::*; use core::$T_i::*;
use core::int; use core::int;
use core::num::{Int, SignedInt};
use num; use num;
use core::num::CheckedDiv;
#[test] #[test]
fn test_overflows() { fn test_overflows() {
@ -37,14 +37,6 @@ mod tests {
assert!((-1 as $T).abs() == 1 as $T); assert!((-1 as $T).abs() == 1 as $T);
} }
#[test]
fn test_abs_sub() {
assert!((-1 as $T).abs_sub(&(1 as $T)) == 0 as $T);
assert!((1 as $T).abs_sub(&(1 as $T)) == 0 as $T);
assert!((1 as $T).abs_sub(&(0 as $T)) == 1 as $T);
assert!((1 as $T).abs_sub(&(-1 as $T)) == 2 as $T);
}
#[test] #[test]
fn test_signum() { fn test_signum() {
assert!((1 as $T).signum() == 1 as $T); assert!((1 as $T).signum() == 1 as $T);
@ -160,9 +152,9 @@ mod tests {
#[test] #[test]
fn test_signed_checked_div() { fn test_signed_checked_div() {
assert!(10i.checked_div(&2) == Some(5)); assert!(10i.checked_div(2) == Some(5));
assert!(5i.checked_div(&0) == None); assert!(5i.checked_div(0) == None);
assert!(int::MIN.checked_div(&-1) == None); assert!(int::MIN.checked_div(-1) == None);
} }
} }

View file

@ -8,7 +8,10 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use core::num::cast; use core::cmp::PartialEq;
use core::fmt::Show;
use core::num::{NumCast, cast};
use core::ops::{Add, Sub, Mul, Div, Rem};
mod int_macros; mod int_macros;
mod i8; mod i8;
@ -24,7 +27,12 @@ mod u64;
mod uint; mod uint;
/// Helper function for testing numeric operations /// Helper function for testing numeric operations
pub fn test_num<T:Num + NumCast + ::std::fmt::Show>(ten: T, two: T) { pub fn test_num<T>(ten: T, two: T) where
T: PartialEq + NumCast
+ Add<T, T> + Sub<T, T>
+ Mul<T, T> + Div<T, T>
+ Rem<T, T> + Show
{
assert_eq!(ten.add(&two), cast(12i).unwrap()); assert_eq!(ten.add(&two), cast(12i).unwrap());
assert_eq!(ten.sub(&two), cast(8i).unwrap()); assert_eq!(ten.sub(&two), cast(8i).unwrap());
assert_eq!(ten.mul(&two), cast(20i).unwrap()); assert_eq!(ten.mul(&two), cast(20i).unwrap());

View file

@ -14,8 +14,8 @@ macro_rules! uint_module (($T:ty, $T_i:ident) => (
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use core::$T_i::*; use core::$T_i::*;
use core::num::Int;
use num; use num;
use core::num::CheckedDiv;
#[test] #[test]
fn test_overflows() { fn test_overflows() {
@ -120,8 +120,8 @@ mod tests {
#[test] #[test]
fn test_unsigned_checked_div() { fn test_unsigned_checked_div() {
assert!(10u.checked_div(&2) == Some(5)); assert!(10u.checked_div(2) == Some(5));
assert!(5u.checked_div(&0) == None); assert!(5u.checked_div(0) == None);
} }
} }
)) ))

View file

@ -11,6 +11,7 @@
//! The ChaCha random number generator. //! The ChaCha random number generator.
use core::prelude::*; use core::prelude::*;
use core::num::Int;
use {Rng, SeedableRng, Rand}; use {Rng, SeedableRng, Rand};

View file

@ -23,7 +23,7 @@ that do not need to record state.
#![experimental] #![experimental]
use core::prelude::*; use core::prelude::*;
use core::num; use core::num::{Float, Int};
use {Rng, Rand}; use {Rng, Rand};
@ -127,7 +127,7 @@ impl<'a, T: Clone> WeightedChoice<'a, T> {
// weights so we can binary search. This *could* drop elements // weights so we can binary search. This *could* drop elements
// with weight == 0 as an optimisation. // with weight == 0 as an optimisation.
for item in items.iter_mut() { for item in items.iter_mut() {
running_total = match running_total.checked_add(&item.weight) { running_total = match running_total.checked_add(item.weight) {
Some(n) => n, Some(n) => n,
None => panic!("WeightedChoice::new called with a total weight \ None => panic!("WeightedChoice::new called with a total weight \
larger than a uint can contain") larger than a uint can contain")
@ -243,7 +243,7 @@ fn ziggurat<R:Rng>(
let u = if symmetric {2.0 * f - 1.0} else {f}; let u = if symmetric {2.0 * f - 1.0} else {f};
let x = u * x_tab[i]; let x = u * x_tab[i];
let test_x = if symmetric {num::abs(x)} else {x}; let test_x = if symmetric { x.abs() } else {x};
// algebraically equivalent to |u| < x_tab[i+1]/x_tab[i] (or u < x_tab[i+1]/x_tab[i]) // algebraically equivalent to |u| < x_tab[i+1]/x_tab[i] (or u < x_tab[i+1]/x_tab[i])
if test_x < x_tab[i + 1] { if test_x < x_tab[i + 1] {

View file

@ -13,7 +13,7 @@
// this is surprisingly complicated to be both generic & correct // this is surprisingly complicated to be both generic & correct
use core::prelude::*; use core::prelude::*;
use core::num::Bounded; use core::num::Int;
use Rng; use Rng;
use distributions::{Sample, IndependentSample}; use distributions::{Sample, IndependentSample};
@ -98,7 +98,7 @@ macro_rules! integer_impl {
fn construct_range(low: $ty, high: $ty) -> Range<$ty> { fn construct_range(low: $ty, high: $ty) -> Range<$ty> {
let range = high as $unsigned - low as $unsigned; let range = high as $unsigned - low as $unsigned;
let unsigned_max: $unsigned = Bounded::max_value(); let unsigned_max: $unsigned = Int::max_value();
// this is the largest number that fits into $unsigned // this is the largest number that fits into $unsigned
// that `range` divides evenly, so, if we've sampled // that `range` divides evenly, so, if we've sampled
@ -163,10 +163,10 @@ float_impl! { f64 }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::num::Int;
use std::prelude::*; use std::prelude::*;
use distributions::{Sample, IndependentSample}; use distributions::{Sample, IndependentSample};
use super::Range; use super::Range;
use std::num::Bounded;
#[should_fail] #[should_fail]
#[test] #[test]
@ -187,7 +187,7 @@ mod tests {
$( $(
let v: &[($ty, $ty)] = [(0, 10), let v: &[($ty, $ty)] = [(0, 10),
(10, 127), (10, 127),
(Bounded::min_value(), Bounded::max_value())]; (Int::min_value(), Int::max_value())];
for &(low, high) in v.iter() { for &(low, high) in v.iter() {
let mut sampler: Range<$ty> = Range::new(low, high); let mut sampler: Range<$ty> = Range::new(low, high);
for _ in range(0u, 1000) { for _ in range(0u, 1000) {

View file

@ -114,10 +114,11 @@ pub enum Error {
pub mod reader { pub mod reader {
use std::char; use std::char;
use std::mem::transmute;
use std::int; use std::int;
use std::option::{None, Option, Some};
use std::io::extensions::u64_from_be_bytes; use std::io::extensions::u64_from_be_bytes;
use std::mem::transmute;
use std::num::Int;
use std::option::{None, Option, Some};
use serialize; use serialize;

View file

@ -23,6 +23,7 @@ use flate;
use std::iter; use std::iter;
use std::mem; use std::mem;
use std::num::Int;
pub fn run(sess: &session::Session, llmod: ModuleRef, pub fn run(sess: &session::Session, llmod: ModuleRef,
tm: TargetMachineRef, reachable: &[String]) { tm: TargetMachineRef, reachable: &[String]) {

View file

@ -37,6 +37,7 @@ use lint::{Context, LintPass, LintArray};
use std::cmp; use std::cmp;
use std::collections::hash_map::{Occupied, Vacant}; use std::collections::hash_map::{Occupied, Vacant};
use std::num::SignedInt;
use std::slice; use std::slice;
use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64}; use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};
use syntax::abi; use syntax::abi;

View file

@ -21,6 +21,7 @@ use middle::ty;
use std::fmt; use std::fmt;
use std::iter::AdditiveIterator; use std::iter::AdditiveIterator;
use std::iter::range_inclusive; use std::iter::range_inclusive;
use std::num::Float;
use std::slice; use std::slice;
use syntax::ast::*; use syntax::ast::*;
use syntax::ast_util::walk_pat; use syntax::ast_util::walk_pat;

View file

@ -21,18 +21,17 @@ use util::ppaux::Repr;
use middle::trans::type_::Type; use middle::trans::type_::Type;
use std::num::Int;
use syntax::abi; use syntax::abi;
use syntax::ast; use syntax::ast;
use std::num::CheckedMul;
// LLVM doesn't like objects that are too big. Issue #17913 // LLVM doesn't like objects that are too big. Issue #17913
fn ensure_array_fits_in_address_space(ccx: &CrateContext, fn ensure_array_fits_in_address_space(ccx: &CrateContext,
llet: Type, llet: Type,
size: machine::llsize, size: machine::llsize,
scapegoat: ty::t) { scapegoat: ty::t) {
let esz = machine::llsize_of_alloc(ccx, llet); let esz = machine::llsize_of_alloc(ccx, llet);
match esz.checked_mul(&size) { match esz.checked_mul(size) {
Some(n) if n < ccx.max_obj_size() => {} Some(n) if n < ccx.max_obj_size() => {}
_ => { ccx.report_overbig_object(scapegoat) } _ => { ccx.report_overbig_object(scapegoat) }
} }

View file

@ -15,7 +15,7 @@
#![allow(deprecated)] // to_be32 #![allow(deprecated)] // to_be32
use std::iter::range_step; use std::iter::range_step;
use std::num::Zero; use std::num::Int;
use std::slice::bytes::{MutableByteVector, copy_memory}; use std::slice::bytes::{MutableByteVector, copy_memory};
use serialize::hex::ToHex; use serialize::hex::ToHex;
@ -61,14 +61,14 @@ impl ToBits for u64 {
/// Adds the specified number of bytes to the bit count. panic!() if this would cause numeric /// Adds the specified number of bytes to the bit count. panic!() if this would cause numeric
/// overflow. /// overflow.
fn add_bytes_to_bits<T: Int + CheckedAdd + ToBits>(bits: T, bytes: T) -> T { fn add_bytes_to_bits<T: Int + ToBits>(bits: T, bytes: T) -> T {
let (new_high_bits, new_low_bits) = bytes.to_bits(); let (new_high_bits, new_low_bits) = bytes.to_bits();
if new_high_bits > Zero::zero() { if new_high_bits > Int::zero() {
panic!("numeric overflow occurred.") panic!("numeric overflow occurred.")
} }
match bits.checked_add(&new_low_bits) { match bits.checked_add(new_low_bits) {
Some(x) => return x, Some(x) => return x,
None => panic!("numeric overflow occurred.") None => panic!("numeric overflow occurred.")
} }
@ -528,10 +528,10 @@ mod tests {
extern crate rand; extern crate rand;
use super::{Digest, Sha256, FixedBuffer}; use super::{Digest, Sha256, FixedBuffer};
use std::num::Bounded;
use self::rand::isaac::IsaacRng; use self::rand::isaac::IsaacRng;
use self::rand::Rng; use self::rand::Rng;
use serialize::hex::FromHex; use serialize::hex::FromHex;
use std::num::Int;
// A normal addition - no overflow occurs // A normal addition - no overflow occurs
#[test] #[test]
@ -543,7 +543,7 @@ mod tests {
#[test] #[test]
#[should_fail] #[should_fail]
fn test_add_bytes_to_bits_overflow() { fn test_add_bytes_to_bits_overflow() {
super::add_bytes_to_bits::<u64>(Bounded::max_value(), 1); super::add_bytes_to_bits::<u64>(Int::max_value(), 1);
} }
struct Test { struct Test {

View file

@ -15,7 +15,6 @@
use std::ops::Add; use std::ops::Add;
use std::num::Zero; use std::num::Zero;
use std::iter::AdditiveIterator;
use syntax::attr::{Deprecated, Experimental, Unstable, Stable, Frozen, Locked}; use syntax::attr::{Deprecated, Experimental, Unstable, Stable, Frozen, Locked};
use syntax::ast::Public; use syntax::ast::Public;
@ -55,6 +54,18 @@ impl Add<Counts, Counts> for Counts {
} }
impl Counts { impl Counts {
fn zero() -> Counts {
Counts {
deprecated: 0,
experimental: 0,
unstable: 0,
stable: 0,
frozen: 0,
locked: 0,
unmarked: 0,
}
}
pub fn total(&self) -> uint { pub fn total(&self) -> uint {
self.deprecated + self.experimental + self.unstable + self.stable + self.deprecated + self.experimental + self.unstable + self.stable +
self.frozen + self.locked + self.unmarked self.frozen + self.locked + self.unmarked
@ -92,14 +103,14 @@ fn visible(item: &Item) -> bool {
fn count_stability(stab: Option<&Stability>) -> Counts { fn count_stability(stab: Option<&Stability>) -> Counts {
match stab { match stab {
None => Counts { unmarked: 1, .. Zero::zero() }, None => Counts { unmarked: 1, .. Counts::zero() },
Some(ref stab) => match stab.level { Some(ref stab) => match stab.level {
Deprecated => Counts { deprecated: 1, .. Zero::zero() }, Deprecated => Counts { deprecated: 1, .. Counts::zero() },
Experimental => Counts { experimental: 1, .. Zero::zero() }, Experimental => Counts { experimental: 1, .. Counts::zero() },
Unstable => Counts { unstable: 1, .. Zero::zero() }, Unstable => Counts { unstable: 1, .. Counts::zero() },
Stable => Counts { stable: 1, .. Zero::zero() }, Stable => Counts { stable: 1, .. Counts::zero() },
Frozen => Counts { frozen: 1, .. Zero::zero() }, Frozen => Counts { frozen: 1, .. Counts::zero() },
Locked => Counts { locked: 1, .. Zero::zero() }, Locked => Counts { locked: 1, .. Counts::zero() },
} }
} }
} }
@ -108,15 +119,19 @@ fn summarize_methods(item: &Item) -> Counts {
match cache_key.get().unwrap().impls.get(&item.def_id) { match cache_key.get().unwrap().impls.get(&item.def_id) {
Some(v) => { Some(v) => {
v.iter().map(|i| { v.iter().map(|i| {
let mut count = count_stability(i.stability.as_ref()); let count = count_stability(i.stability.as_ref());
if i.impl_.trait_.is_none() { if i.impl_.trait_.is_none() {
count = count + count + i.impl_.items.iter()
i.impl_.items.iter().map(|ti| summarize_item(ti).0).sum(); .map(|ti| summarize_item(ti).0)
.fold(Counts::zero(), |acc, c| acc + c)
} else {
count
} }
count }).fold(Counts::zero(), |acc, c| acc + c)
}).sum() },
} None => {
None => Zero::zero() Counts::zero()
},
} }
} }
@ -136,14 +151,14 @@ fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
let subcounts = subitems.iter().filter(|i| visible(*i)) let subcounts = subitems.iter().filter(|i| visible(*i))
.map(summarize_item) .map(summarize_item)
.map(|s| s.val0()) .map(|s| s.val0())
.sum(); .fold(Counts::zero(), |acc, x| acc + x);
(item_counts + subcounts, None) (item_counts + subcounts, None)
} }
// `pub` automatically // `pub` automatically
EnumItem(Enum { variants: ref subitems, .. }) => { EnumItem(Enum { variants: ref subitems, .. }) => {
let subcounts = subitems.iter().map(summarize_item) let subcounts = subitems.iter().map(summarize_item)
.map(|s| s.val0()) .map(|s| s.val0())
.sum(); .fold(Counts::zero(), |acc, x| acc + x);
(item_counts + subcounts, None) (item_counts + subcounts, None)
} }
TraitItem(Trait { TraitItem(Trait {
@ -161,7 +176,7 @@ fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
.map(extract_item) .map(extract_item)
.map(summarize_item) .map(summarize_item)
.map(|s| s.val0()) .map(|s| s.val0())
.sum(); .fold(Counts::zero(), |acc, x| acc + x);
(item_counts + subcounts, None) (item_counts + subcounts, None)
} }
ModuleItem(Module { ref items, .. }) => { ModuleItem(Module { ref items, .. }) => {
@ -182,7 +197,7 @@ fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
})) }))
} }
// no stability information for the following items: // no stability information for the following items:
ViewItemItem(_) | PrimitiveItem(_) => (Zero::zero(), None), ViewItemItem(_) | PrimitiveItem(_) => (Counts::zero(), None),
_ => (item_counts, None) _ => (item_counts, None)
} }
} }
@ -192,7 +207,7 @@ pub fn build(krate: &Crate) -> ModuleSummary {
match krate.module { match krate.module {
None => ModuleSummary { None => ModuleSummary {
name: krate.name.clone(), name: krate.name.clone(),
counts: Zero::zero(), counts: Counts::zero(),
submodules: Vec::new(), submodules: Vec::new(),
}, },
Some(ref item) => ModuleSummary { Some(ref item) => ModuleSummary {

View file

@ -199,7 +199,7 @@ use std::collections::{HashMap, TreeMap};
use std::{char, f64, fmt, io, num, str}; use std::{char, f64, fmt, io, num, str};
use std::io::MemWriter; use std::io::MemWriter;
use std::mem::{swap, transmute}; use std::mem::{swap, transmute};
use std::num::{FPNaN, FPInfinite}; use std::num::{Float, FPNaN, FPInfinite, Int};
use std::str::ScalarValue; use std::str::ScalarValue;
use std::string; use std::string;
use std::vec::Vec; use std::vec::Vec;
@ -609,7 +609,7 @@ impl<'a> PrettyEncoder<'a> {
/// This is safe to set during encoding. /// This is safe to set during encoding.
pub fn set_indent<'a>(&mut self, indent: uint) { pub fn set_indent<'a>(&mut self, indent: uint) {
// self.indent very well could be 0 so we need to use checked division. // self.indent very well could be 0 so we need to use checked division.
let level = self.curr_indent.checked_div(&self.indent).unwrap_or(0); let level = self.curr_indent.checked_div(self.indent).unwrap_or(0);
self.indent = indent; self.indent = indent;
self.curr_indent = level * self.indent; self.curr_indent = level * self.indent;
} }
@ -1484,7 +1484,7 @@ impl<T: Iterator<char>> Parser<T> {
} }
} }
let exp = num::pow(10_f64, exp); let exp = 10_f64.powi(exp as i32);
if neg_exp { if neg_exp {
res /= exp; res /= exp;
} else { } else {
@ -2417,6 +2417,7 @@ mod tests {
TrailingCharacters, TrailingComma}; TrailingCharacters, TrailingComma};
use std::{i64, u64, f32, f64, io}; use std::{i64, u64, f32, f64, io};
use std::collections::TreeMap; use std::collections::TreeMap;
use std::num::Float;
use std::string; use std::string;
#[deriving(Decodable, Eq, PartialEq, Show)] #[deriving(Decodable, Eq, PartialEq, Show)]

View file

@ -18,7 +18,7 @@ use hash::{Hash, Hasher, RandomSipHasher};
use iter::{mod, Iterator, FromIterator, Extend}; use iter::{mod, Iterator, FromIterator, Extend};
use kinds::Sized; use kinds::Sized;
use mem::{mod, replace}; use mem::{mod, replace};
use num; use num::UnsignedInt;
use ops::{Deref, Index, IndexMut}; use ops::{Deref, Index, IndexMut};
use option::{Some, None, Option}; use option::{Some, None, Option};
use result::{Result, Ok, Err}; use result::{Result, Ok, Err};
@ -549,7 +549,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
/// ``` /// ```
#[inline] #[inline]
pub fn with_capacity_and_hasher(capacity: uint, hasher: H) -> HashMap<K, V, H> { pub fn with_capacity_and_hasher(capacity: uint, hasher: H) -> HashMap<K, V, H> {
let cap = num::next_power_of_two(max(INITIAL_CAPACITY, capacity)); let cap = max(INITIAL_CAPACITY, capacity).next_power_of_two();
HashMap { HashMap {
hasher: hasher, hasher: hasher,
resize_policy: DefaultResizePolicy::new(cap), resize_policy: DefaultResizePolicy::new(cap),
@ -572,8 +572,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
/// map.reserve(10); /// map.reserve(10);
/// ``` /// ```
pub fn reserve(&mut self, new_minimum_capacity: uint) { pub fn reserve(&mut self, new_minimum_capacity: uint) {
let cap = num::next_power_of_two( let cap = max(INITIAL_CAPACITY, new_minimum_capacity).next_power_of_two();
max(INITIAL_CAPACITY, new_minimum_capacity));
self.resize_policy.reserve(cap); self.resize_policy.reserve(cap);
@ -588,7 +587,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
/// 2) Ensure new_capacity is a power of two. /// 2) Ensure new_capacity is a power of two.
fn resize(&mut self, new_capacity: uint) { fn resize(&mut self, new_capacity: uint) {
assert!(self.table.size() <= new_capacity); assert!(self.table.size() <= new_capacity);
assert!(num::is_power_of_two(new_capacity)); assert!(new_capacity.is_power_of_two());
let mut old_table = replace(&mut self.table, RawTable::new(new_capacity)); let mut old_table = replace(&mut self.table, RawTable::new(new_capacity));
let old_size = old_table.size(); let old_size = old_table.size();

View file

@ -17,7 +17,7 @@ use iter::{Iterator, count};
use kinds::{Sized, marker}; use kinds::{Sized, marker};
use mem::{min_align_of, size_of}; use mem::{min_align_of, size_of};
use mem; use mem;
use num::{CheckedAdd, CheckedMul, is_power_of_two}; use num::{Int, UnsignedInt};
use ops::{Deref, DerefMut, Drop}; use ops::{Deref, DerefMut, Drop};
use option::{Some, None, Option}; use option::{Some, None, Option};
use ptr::{RawPtr, copy_nonoverlapping_memory, zero_memory}; use ptr::{RawPtr, copy_nonoverlapping_memory, zero_memory};
@ -493,7 +493,7 @@ impl<K, V, M: Deref<RawTable<K, V>>> GapThenFull<K, V, M> {
/// ///
/// Fails if `target_alignment` is not a power of two. /// Fails if `target_alignment` is not a power of two.
fn round_up_to_next(unrounded: uint, target_alignment: uint) -> uint { fn round_up_to_next(unrounded: uint, target_alignment: uint) -> uint {
assert!(is_power_of_two(target_alignment)); assert!(target_alignment.is_power_of_two());
(unrounded + target_alignment - 1) & !(target_alignment - 1) (unrounded + target_alignment - 1) & !(target_alignment - 1)
} }
@ -581,9 +581,9 @@ impl<K, V> RawTable<K, V> {
vals_size, min_align_of::< V >()); vals_size, min_align_of::< V >());
// One check for overflow that covers calculation and rounding of size. // One check for overflow that covers calculation and rounding of size.
let size_of_bucket = size_of::<u64>().checked_add(&size_of::<K>()).unwrap() let size_of_bucket = size_of::<u64>().checked_add(size_of::<K>()).unwrap()
.checked_add(&size_of::<V>()).unwrap(); .checked_add(size_of::<V>()).unwrap();
assert!(size >= capacity.checked_mul(&size_of_bucket) assert!(size >= capacity.checked_mul(size_of_bucket)
.expect("capacity overflow"), .expect("capacity overflow"),
"capacity overflow"); "capacity overflow");

View file

@ -190,6 +190,7 @@ like:
```rust ```rust
use std::fmt; use std::fmt;
use std::f64; use std::f64;
use std::num::Float;
struct Vector2D { struct Vector2D {
x: int, x: int,

View file

@ -20,6 +20,7 @@ use prelude::*;
use from_str::FromStr; use from_str::FromStr;
use intrinsics; use intrinsics;
use libc::c_int; use libc::c_int;
use num::{Float, FloatMath};
use num::strconv; use num::strconv;
use num; use num;
@ -108,6 +109,11 @@ impl FloatMath for f32 {
unsafe { cmath::fminf(self, other) } unsafe { cmath::fminf(self, other) }
} }
#[inline]
fn abs_sub(self, other: f32) -> f32 {
unsafe { cmath::fdimf(self, other) }
}
#[inline] #[inline]
fn cbrt(self) -> f32 { fn cbrt(self) -> f32 {
unsafe { cmath::cbrtf(self) } unsafe { cmath::cbrtf(self) }
@ -593,20 +599,20 @@ mod tests {
#[test] #[test]
fn test_abs_sub() { fn test_abs_sub() {
assert_eq!((-1f32).abs_sub(&1f32), 0f32); assert_eq!((-1f32).abs_sub(1f32), 0f32);
assert_eq!(1f32.abs_sub(&1f32), 0f32); assert_eq!(1f32.abs_sub(1f32), 0f32);
assert_eq!(1f32.abs_sub(&0f32), 1f32); assert_eq!(1f32.abs_sub(0f32), 1f32);
assert_eq!(1f32.abs_sub(&-1f32), 2f32); assert_eq!(1f32.abs_sub(-1f32), 2f32);
assert_eq!(NEG_INFINITY.abs_sub(&0f32), 0f32); assert_eq!(NEG_INFINITY.abs_sub(0f32), 0f32);
assert_eq!(INFINITY.abs_sub(&1f32), INFINITY); assert_eq!(INFINITY.abs_sub(1f32), INFINITY);
assert_eq!(0f32.abs_sub(&NEG_INFINITY), INFINITY); assert_eq!(0f32.abs_sub(NEG_INFINITY), INFINITY);
assert_eq!(0f32.abs_sub(&INFINITY), 0f32); assert_eq!(0f32.abs_sub(INFINITY), 0f32);
} }
#[test] #[test]
fn test_abs_sub_nowin() { fn test_abs_sub_nowin() {
assert!(NAN.abs_sub(&-1f32).is_nan()); assert!(NAN.abs_sub(-1f32).is_nan());
assert!(1f32.abs_sub(&NAN).is_nan()); assert!(1f32.abs_sub(NAN).is_nan());
} }
#[test] #[test]
@ -650,7 +656,7 @@ mod tests {
let nan: f32 = Float::nan(); let nan: f32 = Float::nan();
let inf: f32 = Float::infinity(); let inf: f32 = Float::infinity();
let neg_inf: f32 = Float::neg_infinity(); let neg_inf: f32 = Float::neg_infinity();
let zero: f32 = Zero::zero(); let zero: f32 = Float::zero();
let neg_zero: f32 = Float::neg_zero(); let neg_zero: f32 = Float::neg_zero();
assert!(!nan.is_normal()); assert!(!nan.is_normal());
assert!(!inf.is_normal()); assert!(!inf.is_normal());
@ -667,7 +673,7 @@ mod tests {
let nan: f32 = Float::nan(); let nan: f32 = Float::nan();
let inf: f32 = Float::infinity(); let inf: f32 = Float::infinity();
let neg_inf: f32 = Float::neg_infinity(); let neg_inf: f32 = Float::neg_infinity();
let zero: f32 = Zero::zero(); let zero: f32 = Float::zero();
let neg_zero: f32 = Float::neg_zero(); let neg_zero: f32 = Float::neg_zero();
assert_eq!(nan.classify(), FPNaN); assert_eq!(nan.classify(), FPNaN);
assert_eq!(inf.classify(), FPInfinite); assert_eq!(inf.classify(), FPInfinite);

View file

@ -19,6 +19,7 @@ use prelude::*;
use from_str::FromStr; use from_str::FromStr;
use intrinsics; use intrinsics;
use libc::c_int; use libc::c_int;
use num::{Float, FloatMath};
use num::strconv; use num::strconv;
use num; use num;
@ -116,6 +117,11 @@ impl FloatMath for f64 {
unsafe { cmath::fmin(self, other) } unsafe { cmath::fmin(self, other) }
} }
#[inline]
fn abs_sub(self, other: f64) -> f64 {
unsafe { cmath::fdim(self, other) }
}
#[inline] #[inline]
fn cbrt(self) -> f64 { fn cbrt(self) -> f64 {
unsafe { cmath::cbrt(self) } unsafe { cmath::cbrt(self) }
@ -591,20 +597,20 @@ mod tests {
#[test] #[test]
fn test_abs_sub() { fn test_abs_sub() {
assert_eq!((-1f64).abs_sub(&1f64), 0f64); assert_eq!((-1f64).abs_sub(1f64), 0f64);
assert_eq!(1f64.abs_sub(&1f64), 0f64); assert_eq!(1f64.abs_sub(1f64), 0f64);
assert_eq!(1f64.abs_sub(&0f64), 1f64); assert_eq!(1f64.abs_sub(0f64), 1f64);
assert_eq!(1f64.abs_sub(&-1f64), 2f64); assert_eq!(1f64.abs_sub(-1f64), 2f64);
assert_eq!(NEG_INFINITY.abs_sub(&0f64), 0f64); assert_eq!(NEG_INFINITY.abs_sub(0f64), 0f64);
assert_eq!(INFINITY.abs_sub(&1f64), INFINITY); assert_eq!(INFINITY.abs_sub(1f64), INFINITY);
assert_eq!(0f64.abs_sub(&NEG_INFINITY), INFINITY); assert_eq!(0f64.abs_sub(NEG_INFINITY), INFINITY);
assert_eq!(0f64.abs_sub(&INFINITY), 0f64); assert_eq!(0f64.abs_sub(INFINITY), 0f64);
} }
#[test] #[test]
fn test_abs_sub_nowin() { fn test_abs_sub_nowin() {
assert!(NAN.abs_sub(&-1f64).is_nan()); assert!(NAN.abs_sub(-1f64).is_nan());
assert!(1f64.abs_sub(&NAN).is_nan()); assert!(1f64.abs_sub(NAN).is_nan());
} }
#[test] #[test]
@ -648,7 +654,7 @@ mod tests {
let nan: f64 = Float::nan(); let nan: f64 = Float::nan();
let inf: f64 = Float::infinity(); let inf: f64 = Float::infinity();
let neg_inf: f64 = Float::neg_infinity(); let neg_inf: f64 = Float::neg_infinity();
let zero: f64 = Zero::zero(); let zero: f64 = Float::zero();
let neg_zero: f64 = Float::neg_zero(); let neg_zero: f64 = Float::neg_zero();
assert!(!nan.is_normal()); assert!(!nan.is_normal());
assert!(!inf.is_normal()); assert!(!inf.is_normal());
@ -665,7 +671,7 @@ mod tests {
let nan: f64 = Float::nan(); let nan: f64 = Float::nan();
let inf: f64 = Float::infinity(); let inf: f64 = Float::infinity();
let neg_inf: f64 = Float::neg_infinity(); let neg_inf: f64 = Float::neg_infinity();
let zero: f64 = Zero::zero(); let zero: f64 = Float::zero();
let neg_zero: f64 = Float::neg_zero(); let neg_zero: f64 = Float::neg_zero();
assert_eq!(nan.classify(), FPNaN); assert_eq!(nan.classify(), FPNaN);
assert_eq!(inf.classify(), FPInfinite); assert_eq!(inf.classify(), FPInfinite);

View file

@ -14,6 +14,7 @@
macro_rules! assert_approx_eq( macro_rules! assert_approx_eq(
($a:expr, $b:expr) => ({ ($a:expr, $b:expr) => ({
use num::Float;
let (a, b) = (&$a, &$b); let (a, b) = (&$a, &$b);
assert!((*a - *b).abs() < 1.0e-6, assert!((*a - *b).abs() < 1.0e-6,
"{} is not approximately equal to {}", *a, *b); "{} is not approximately equal to {}", *a, *b);

View file

@ -18,13 +18,13 @@
use option::Option; use option::Option;
#[cfg(test)] use cmp::PartialEq;
#[cfg(test)] use fmt::Show; #[cfg(test)] use fmt::Show;
#[cfg(test)] use ops::{Add, Sub, Mul, Div, Rem};
pub use core::num::{Num, div_rem, Zero, zero, One, one}; pub use core::num::{Num, div_rem, Zero, zero, One, one};
pub use core::num::{Signed, abs, abs_sub, signum};
pub use core::num::{Unsigned, pow, Bounded}; pub use core::num::{Unsigned, pow, Bounded};
pub use core::num::{Primitive, Int, Saturating}; pub use core::num::{Primitive, Int, SignedInt, UnsignedInt};
pub use core::num::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv};
pub use core::num::{cast, FromPrimitive, NumCast, ToPrimitive}; pub use core::num::{cast, FromPrimitive, NumCast, ToPrimitive};
pub use core::num::{next_power_of_two, is_power_of_two}; pub use core::num::{next_power_of_two, is_power_of_two};
pub use core::num::{checked_next_power_of_two}; pub use core::num::{checked_next_power_of_two};
@ -58,6 +58,11 @@ pub trait FloatMath: Float {
/// Returns the minimum of the two numbers. /// Returns the minimum of the two numbers.
fn min(self, other: Self) -> Self; fn min(self, other: Self) -> Self;
/// The positive difference of two numbers. Returns `0.0` if the number is
/// less than or equal to `other`, otherwise the difference between`self`
/// and `other` is returned.
fn abs_sub(self, other: Self) -> Self;
/// Take the cubic root of a number. /// Take the cubic root of a number.
fn cbrt(self) -> Self; fn cbrt(self) -> Self;
/// Calculate the length of the hypotenuse of a right-angle triangle given /// Calculate the length of the hypotenuse of a right-angle triangle given
@ -122,9 +127,21 @@ pub fn from_str_radix<T: FromStrRadix>(str: &str, radix: uint) -> Option<T> {
FromStrRadix::from_str_radix(str, radix) FromStrRadix::from_str_radix(str, radix)
} }
// DEPRECATED
#[deprecated = "Use `FloatMath::abs_sub`"]
pub fn abs_sub<T: FloatMath>(x: T, y: T) -> T {
x.abs_sub(y)
}
/// Helper function for testing numeric operations /// Helper function for testing numeric operations
#[cfg(test)] #[cfg(test)]
pub fn test_num<T:Num + NumCast + Show>(ten: T, two: T) { pub fn test_num<T>(ten: T, two: T) where
T: PartialEq + NumCast
+ Add<T, T> + Sub<T, T>
+ Mul<T, T> + Div<T, T>
+ Rem<T, T> + Show
{
assert_eq!(ten.add(&two), cast(12i).unwrap()); assert_eq!(ten.add(&two), cast(12i).unwrap());
assert_eq!(ten.sub(&two), cast(8i).unwrap()); assert_eq!(ten.sub(&two), cast(8i).unwrap());
assert_eq!(ten.mul(&two), cast(20i).unwrap()); assert_eq!(ten.mul(&two), cast(20i).unwrap());
@ -624,46 +641,46 @@ mod tests {
#[test] #[test]
fn test_checked_add() { fn test_checked_add() {
let five_less = uint::MAX - 5; let five_less = uint::MAX - 5;
assert_eq!(five_less.checked_add(&0), Some(uint::MAX - 5)); assert_eq!(five_less.checked_add(0), Some(uint::MAX - 5));
assert_eq!(five_less.checked_add(&1), Some(uint::MAX - 4)); assert_eq!(five_less.checked_add(1), Some(uint::MAX - 4));
assert_eq!(five_less.checked_add(&2), Some(uint::MAX - 3)); assert_eq!(five_less.checked_add(2), Some(uint::MAX - 3));
assert_eq!(five_less.checked_add(&3), Some(uint::MAX - 2)); assert_eq!(five_less.checked_add(3), Some(uint::MAX - 2));
assert_eq!(five_less.checked_add(&4), Some(uint::MAX - 1)); assert_eq!(five_less.checked_add(4), Some(uint::MAX - 1));
assert_eq!(five_less.checked_add(&5), Some(uint::MAX)); assert_eq!(five_less.checked_add(5), Some(uint::MAX));
assert_eq!(five_less.checked_add(&6), None); assert_eq!(five_less.checked_add(6), None);
assert_eq!(five_less.checked_add(&7), None); assert_eq!(five_less.checked_add(7), None);
} }
#[test] #[test]
fn test_checked_sub() { fn test_checked_sub() {
assert_eq!(5u.checked_sub(&0), Some(5)); assert_eq!(5u.checked_sub(0), Some(5));
assert_eq!(5u.checked_sub(&1), Some(4)); assert_eq!(5u.checked_sub(1), Some(4));
assert_eq!(5u.checked_sub(&2), Some(3)); assert_eq!(5u.checked_sub(2), Some(3));
assert_eq!(5u.checked_sub(&3), Some(2)); assert_eq!(5u.checked_sub(3), Some(2));
assert_eq!(5u.checked_sub(&4), Some(1)); assert_eq!(5u.checked_sub(4), Some(1));
assert_eq!(5u.checked_sub(&5), Some(0)); assert_eq!(5u.checked_sub(5), Some(0));
assert_eq!(5u.checked_sub(&6), None); assert_eq!(5u.checked_sub(6), None);
assert_eq!(5u.checked_sub(&7), None); assert_eq!(5u.checked_sub(7), None);
} }
#[test] #[test]
fn test_checked_mul() { fn test_checked_mul() {
let third = uint::MAX / 3; let third = uint::MAX / 3;
assert_eq!(third.checked_mul(&0), Some(0)); assert_eq!(third.checked_mul(0), Some(0));
assert_eq!(third.checked_mul(&1), Some(third)); assert_eq!(third.checked_mul(1), Some(third));
assert_eq!(third.checked_mul(&2), Some(third * 2)); assert_eq!(third.checked_mul(2), Some(third * 2));
assert_eq!(third.checked_mul(&3), Some(third * 3)); assert_eq!(third.checked_mul(3), Some(third * 3));
assert_eq!(third.checked_mul(&4), None); assert_eq!(third.checked_mul(4), None);
} }
macro_rules! test_next_power_of_two( macro_rules! test_next_power_of_two(
($test_name:ident, $T:ident) => ( ($test_name:ident, $T:ident) => (
fn $test_name() { fn $test_name() {
#![test] #![test]
assert_eq!(next_power_of_two::<$T>(0), 0); assert_eq!((0 as $T).next_power_of_two(), 0);
let mut next_power = 1; let mut next_power = 1;
for i in range::<$T>(1, 40) { for i in range::<$T>(1, 40) {
assert_eq!(next_power_of_two(i), next_power); assert_eq!(i.next_power_of_two(), next_power);
if i == next_power { next_power *= 2 } if i == next_power { next_power *= 2 }
} }
} }
@ -680,15 +697,15 @@ mod tests {
($test_name:ident, $T:ident) => ( ($test_name:ident, $T:ident) => (
fn $test_name() { fn $test_name() {
#![test] #![test]
assert_eq!(checked_next_power_of_two::<$T>(0), None); assert_eq!((0 as $T).checked_next_power_of_two(), None);
let mut next_power = 1; let mut next_power = 1;
for i in range::<$T>(1, 40) { for i in range::<$T>(1, 40) {
assert_eq!(checked_next_power_of_two(i), Some(next_power)); assert_eq!(i.checked_next_power_of_two(), Some(next_power));
if i == next_power { next_power *= 2 } if i == next_power { next_power *= 2 }
} }
assert!(checked_next_power_of_two::<$T>($T::MAX / 2).is_some()); assert!(($T::MAX / 2).checked_next_power_of_two().is_some());
assert_eq!(checked_next_power_of_two::<$T>($T::MAX - 1), None); assert_eq!(($T::MAX - 1).checked_next_power_of_two(), None);
assert_eq!(checked_next_power_of_two::<$T>($T::MAX), None); assert_eq!($T::MAX.checked_next_power_of_two(), None);
} }
) )
) )
@ -760,10 +777,7 @@ mod tests {
assert_pow!((3i, 0 ) => 1); assert_pow!((3i, 0 ) => 1);
assert_pow!((5i, 1 ) => 5); assert_pow!((5i, 1 ) => 5);
assert_pow!((-4i, 2 ) => 16); assert_pow!((-4i, 2 ) => 16);
assert_pow!((0.5f64, 5 ) => 0.03125);
assert_pow!((8i, 3 ) => 512); assert_pow!((8i, 3 ) => 512);
assert_pow!((8.0f64, 5 ) => 32768.0);
assert_pow!((8.5f64, 5 ) => 44370.53125);
assert_pow!((2u64, 50) => 1125899906842624); assert_pow!((2u64, 50) => 1125899906842624);
} }
} }

View file

@ -17,8 +17,7 @@ use char::Char;
use from_str::from_str; use from_str::from_str;
use iter::Iterator; use iter::Iterator;
use num; use num;
use num::{Int, Bounded}; use num::{Int, Float, FPNaN, FPInfinite, ToPrimitive};
use num::{Float, FPNaN, FPInfinite, ToPrimitive};
use option::{None, Option, Some}; use option::{None, Option, Some};
use slice::{SlicePrelude, CloneSliceAllocPrelude}; use slice::{SlicePrelude, CloneSliceAllocPrelude};
use str::StrPrelude; use str::StrPrelude;
@ -95,7 +94,7 @@ pub enum SignFormat {
fn int_to_str_bytes_common<T: Int>(num: T, radix: uint, sign: SignFormat, f: |u8|) { fn int_to_str_bytes_common<T: Int>(num: T, radix: uint, sign: SignFormat, f: |u8|) {
assert!(2 <= radix && radix <= 36); assert!(2 <= radix && radix <= 36);
let _0: T = num::zero(); let _0: T = Int::zero();
let neg = num < _0; let neg = num < _0;
let radix_gen: T = num::cast(radix).unwrap(); let radix_gen: T = num::cast(radix).unwrap();
@ -117,7 +116,7 @@ fn int_to_str_bytes_common<T: Int>(num: T, radix: uint, sign: SignFormat, f: |u8
// numbers [-35 .. 0] we always have [0 .. 35]. // numbers [-35 .. 0] we always have [0 .. 35].
let current_digit_signed = deccum % radix_gen; let current_digit_signed = deccum % radix_gen;
let current_digit = if current_digit_signed < _0 { let current_digit = if current_digit_signed < _0 {
-current_digit_signed _0 - current_digit_signed
} else { } else {
current_digit_signed current_digit_signed
}; };
@ -195,8 +194,8 @@ pub fn float_to_str_bytes_common<T: Float>(
_ => () _ => ()
} }
let _0: T = num::zero(); let _0: T = Float::zero();
let _1: T = num::one(); let _1: T = Float::one();
match num.classify() { match num.classify() {
FPNaN => { return (b"NaN".to_vec(), true); } FPNaN => { return (b"NaN".to_vec(), true); }
@ -431,8 +430,8 @@ pub fn from_str_radix_float<T: Float>(src: &str, radix: uint) -> Option<T> {
"from_str_radix_float: must lie in the range `[2, 36]` - found {}", "from_str_radix_float: must lie in the range `[2, 36]` - found {}",
radix); radix);
let _0: T = num::zero(); let _0: T = Float::zero();
let _1: T = num::one(); let _1: T = Float::one();
let radix_t: T = num::cast(radix as int).unwrap(); let radix_t: T = num::cast(radix as int).unwrap();
// Special values // Special values
@ -559,8 +558,8 @@ pub fn from_str_radix_float<T: Float>(src: &str, radix: uint) -> Option<T> {
}; };
match (is_positive, exp) { match (is_positive, exp) {
(true, Some(exp)) => num::pow(base, exp), (true, Some(exp)) => base.powi(exp as i32),
(false, Some(exp)) => _1 / num::pow(base, exp), (false, Some(exp)) => _1 / base.powi(exp as i32),
(_, None) => return None, (_, None) => return None,
} }
}, },
@ -579,9 +578,9 @@ pub fn from_str_radix_int<T: Int>(src: &str, radix: uint) -> Option<T> {
num::cast(x).unwrap() num::cast(x).unwrap()
} }
let _0: T = num::zero(); let _0: T = Int::zero();
let _1: T = num::one(); let _1: T = Int::one();
let is_signed = _0 > Bounded::min_value(); let is_signed = _0 > Int::min_value();
let (is_positive, src) = match src.slice_shift_char() { let (is_positive, src) = match src.slice_shift_char() {
(Some('-'), src) if is_signed => (false, src), (Some('-'), src) if is_signed => (false, src),
@ -601,11 +600,11 @@ pub fn from_str_radix_int<T: Int>(src: &str, radix: uint) -> Option<T> {
Some(x) => x, Some(x) => x,
None => return None, None => return None,
}; };
result = match result.checked_mul(&radix) { result = match result.checked_mul(radix) {
Some(result) => result, Some(result) => result,
None => return None, None => return None,
}; };
result = match result.checked_add(&x) { result = match result.checked_add(x) {
Some(result) => result, Some(result) => result,
None => return None, None => return None,
}; };
@ -616,11 +615,11 @@ pub fn from_str_radix_int<T: Int>(src: &str, radix: uint) -> Option<T> {
Some(x) => x, Some(x) => x,
None => return None, None => return None,
}; };
result = match result.checked_mul(&radix) { result = match result.checked_mul(radix) {
Some(result) => result, Some(result) => result,
None => return None, None => return None,
}; };
result = match result.checked_sub(&x) { result = match result.checked_sub(x) {
Some(result) => result, Some(result) => result,
None => return None, None => return None,
}; };

View file

@ -67,9 +67,7 @@
#[doc(no_inline)] pub use iter::{Iterator, DoubleEndedIterator}; #[doc(no_inline)] pub use iter::{Iterator, DoubleEndedIterator};
#[doc(no_inline)] pub use iter::{RandomAccessIterator, CloneableIterator}; #[doc(no_inline)] pub use iter::{RandomAccessIterator, CloneableIterator};
#[doc(no_inline)] pub use iter::{OrdIterator, MutableDoubleEndedIterator}; #[doc(no_inline)] pub use iter::{OrdIterator, MutableDoubleEndedIterator};
#[doc(no_inline)] pub use num::{Num, NumCast, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv}; #[doc(no_inline)] pub use num::{ToPrimitive, FromPrimitive};
#[doc(no_inline)] pub use num::{Signed, Unsigned, Primitive, Int, Float};
#[doc(no_inline)] pub use num::{FloatMath, ToPrimitive, FromPrimitive};
#[doc(no_inline)] pub use boxed::Box; #[doc(no_inline)] pub use boxed::Box;
#[doc(no_inline)] pub use option::{Option, Some, None}; #[doc(no_inline)] pub use option::{Option, Some, None};
#[doc(no_inline)] pub use path::{GenericPath, Path, PosixPath, WindowsPath}; #[doc(no_inline)] pub use path::{GenericPath, Path, PosixPath, WindowsPath};

View file

@ -78,6 +78,7 @@ mod test {
use super::ReaderRng; use super::ReaderRng;
use io::MemReader; use io::MemReader;
use num::Int;
use rand::Rng; use rand::Rng;
#[test] #[test]

View file

@ -13,9 +13,9 @@
use io::{mod, IoError, IoResult}; use io::{mod, IoError, IoResult};
use prelude::*; use prelude::*;
use num;
use sys::{last_error, retry, fs}; use sys::{last_error, retry, fs};
use c_str::CString; use c_str::CString;
use num::Int;
use path::BytesContainer; use path::BytesContainer;
use collections; use collections;
@ -57,8 +57,8 @@ pub fn unimpl() -> IoError {
} }
// unix has nonzero values as errors // unix has nonzero values as errors
pub fn mkerr_libc<Int: num::Zero>(ret: Int) -> IoResult<()> { pub fn mkerr_libc<T: Int>(ret: T) -> IoResult<()> {
if !ret.is_zero() { if ret != Int::zero() {
Err(last_error()) Err(last_error())
} else { } else {
Ok(()) Ok(())

View file

@ -11,6 +11,7 @@
use alloc::arc::Arc; use alloc::arc::Arc;
use libc::{mod, c_char, c_int}; use libc::{mod, c_char, c_int};
use mem; use mem;
use num::Int;
use ptr::{mod, null, null_mut}; use ptr::{mod, null, null_mut};
use rt::mutex; use rt::mutex;
use io::net::ip::{SocketAddr, IpAddr, Ipv4Addr, Ipv6Addr}; use io::net::ip::{SocketAddr, IpAddr, Ipv4Addr, Ipv6Addr};

View file

@ -18,6 +18,7 @@
extern crate libc; extern crate libc;
use num; use num;
use num::{Int, SignedInt};
use prelude::*; use prelude::*;
use io::{mod, IoResult, IoError}; use io::{mod, IoResult, IoError};
use sys_common::mkerr_libc; use sys_common::mkerr_libc;
@ -116,11 +117,11 @@ pub fn decode_error_detailed(errno: i32) -> IoError {
} }
#[inline] #[inline]
pub fn retry<I: PartialEq + num::One + Neg<I>> (f: || -> I) -> I { pub fn retry<T: SignedInt> (f: || -> T) -> T {
let minus_one = -num::one::<I>(); let one: T = Int::one();
loop { loop {
let n = f(); let n = f();
if n == minus_one && os::errno() == libc::EINTR as int { } if n == -one && os::errno() == libc::EINTR as int { }
else { return n } else { return n }
} }
} }

View file

@ -15,8 +15,7 @@
use {fmt, i64}; use {fmt, i64};
use ops::{Add, Sub, Mul, Div, Neg}; use ops::{Add, Sub, Mul, Div, Neg};
use option::{Option, Some, None}; use option::{Option, Some, None};
use num; use num::Int;
use num::{CheckedAdd, CheckedMul};
use result::{Result, Ok, Err}; use result::{Result, Ok, Err};
/// The number of nanoseconds in a microsecond. /// The number of nanoseconds in a microsecond.
@ -69,7 +68,7 @@ impl Duration {
/// Fails when the duration is out of bounds. /// Fails when the duration is out of bounds.
#[inline] #[inline]
pub fn weeks(weeks: i64) -> Duration { pub fn weeks(weeks: i64) -> Duration {
let secs = weeks.checked_mul(&SECS_PER_WEEK).expect("Duration::weeks out of bounds"); let secs = weeks.checked_mul(SECS_PER_WEEK).expect("Duration::weeks out of bounds");
Duration::seconds(secs) Duration::seconds(secs)
} }
@ -78,7 +77,7 @@ impl Duration {
/// Fails when the duration is out of bounds. /// Fails when the duration is out of bounds.
#[inline] #[inline]
pub fn days(days: i64) -> Duration { pub fn days(days: i64) -> Duration {
let secs = days.checked_mul(&SECS_PER_DAY).expect("Duration::days out of bounds"); let secs = days.checked_mul(SECS_PER_DAY).expect("Duration::days out of bounds");
Duration::seconds(secs) Duration::seconds(secs)
} }
@ -87,7 +86,7 @@ impl Duration {
/// Fails when the duration is out of bounds. /// Fails when the duration is out of bounds.
#[inline] #[inline]
pub fn hours(hours: i64) -> Duration { pub fn hours(hours: i64) -> Duration {
let secs = hours.checked_mul(&SECS_PER_HOUR).expect("Duration::hours ouf of bounds"); let secs = hours.checked_mul(SECS_PER_HOUR).expect("Duration::hours ouf of bounds");
Duration::seconds(secs) Duration::seconds(secs)
} }
@ -96,7 +95,7 @@ impl Duration {
/// Fails when the duration is out of bounds. /// Fails when the duration is out of bounds.
#[inline] #[inline]
pub fn minutes(minutes: i64) -> Duration { pub fn minutes(minutes: i64) -> Duration {
let secs = minutes.checked_mul(&SECS_PER_MINUTE).expect("Duration::minutes out of bounds"); let secs = minutes.checked_mul(SECS_PER_MINUTE).expect("Duration::minutes out of bounds");
Duration::seconds(secs) Duration::seconds(secs)
} }
@ -199,33 +198,64 @@ impl Duration {
/// Returns the total number of whole microseconds in the duration, /// Returns the total number of whole microseconds in the duration,
/// or `None` on overflow (exceeding 2^63 microseconds in either direction). /// or `None` on overflow (exceeding 2^63 microseconds in either direction).
pub fn num_microseconds(&self) -> Option<i64> { pub fn num_microseconds(&self) -> Option<i64> {
let secs_part = try_opt!(self.num_seconds().checked_mul(&MICROS_PER_SEC)); let secs_part = try_opt!(self.num_seconds().checked_mul(MICROS_PER_SEC));
let nanos_part = self.nanos_mod_sec() / NANOS_PER_MICRO; let nanos_part = self.nanos_mod_sec() / NANOS_PER_MICRO;
secs_part.checked_add(&(nanos_part as i64)) secs_part.checked_add(nanos_part as i64)
} }
/// Returns the total number of whole nanoseconds in the duration, /// Returns the total number of whole nanoseconds in the duration,
/// or `None` on overflow (exceeding 2^63 nanoseconds in either direction). /// or `None` on overflow (exceeding 2^63 nanoseconds in either direction).
pub fn num_nanoseconds(&self) -> Option<i64> { pub fn num_nanoseconds(&self) -> Option<i64> {
let secs_part = try_opt!(self.num_seconds().checked_mul(&(NANOS_PER_SEC as i64))); let secs_part = try_opt!(self.num_seconds().checked_mul(NANOS_PER_SEC as i64));
let nanos_part = self.nanos_mod_sec(); let nanos_part = self.nanos_mod_sec();
secs_part.checked_add(&(nanos_part as i64)) secs_part.checked_add(nanos_part as i64)
} }
}
impl num::Bounded for Duration { /// Add two durations, returning `None` if overflow occured.
#[inline] fn min_value() -> Duration { MIN } pub fn checked_add(&self, rhs: &Duration) -> Option<Duration> {
#[inline] fn max_value() -> Duration { MAX } let mut secs = try_opt!(self.secs.checked_add(rhs.secs));
} let mut nanos = self.nanos + rhs.nanos;
if nanos >= NANOS_PER_SEC {
nanos -= NANOS_PER_SEC;
secs = try_opt!(secs.checked_add(1));
}
let d = Duration { secs: secs, nanos: nanos };
// Even if d is within the bounds of i64 seconds,
// it might still overflow i64 milliseconds.
if d < MIN || d > MAX { None } else { Some(d) }
}
impl num::Zero for Duration { /// Subtract two durations, returning `None` if overflow occured.
pub fn checked_sub(&self, rhs: &Duration) -> Option<Duration> {
let mut secs = try_opt!(self.secs.checked_sub(rhs.secs));
let mut nanos = self.nanos - rhs.nanos;
if nanos < 0 {
nanos += NANOS_PER_SEC;
secs = try_opt!(secs.checked_sub(1));
}
let d = Duration { secs: secs, nanos: nanos };
// Even if d is within the bounds of i64 seconds,
// it might still overflow i64 milliseconds.
if d < MIN || d > MAX { None } else { Some(d) }
}
/// The minimum possible `Duration`: `i64::MIN` milliseconds.
#[inline] #[inline]
fn zero() -> Duration { pub fn min_value() -> Duration { MIN }
/// The maximum possible `Duration`: `i64::MAX` milliseconds.
#[inline]
pub fn max_value() -> Duration { MAX }
/// A duration where the stored seconds and nanoseconds are equal to zero.
#[inline]
pub fn zero() -> Duration {
Duration { secs: 0, nanos: 0 } Duration { secs: 0, nanos: 0 }
} }
/// Returns `true` if the duration equals `Duration::zero()`.
#[inline] #[inline]
fn is_zero(&self) -> bool { pub fn is_zero(&self) -> bool {
self.secs == 0 && self.nanos == 0 self.secs == 0 && self.nanos == 0
} }
} }
@ -253,21 +283,6 @@ impl Add<Duration,Duration> for Duration {
} }
} }
impl num::CheckedAdd for Duration {
fn checked_add(&self, rhs: &Duration) -> Option<Duration> {
let mut secs = try_opt!(self.secs.checked_add(&rhs.secs));
let mut nanos = self.nanos + rhs.nanos;
if nanos >= NANOS_PER_SEC {
nanos -= NANOS_PER_SEC;
secs = try_opt!(secs.checked_add(&1));
}
let d = Duration { secs: secs, nanos: nanos };
// Even if d is within the bounds of i64 seconds,
// it might still overflow i64 milliseconds.
if d < MIN || d > MAX { None } else { Some(d) }
}
}
impl Sub<Duration,Duration> for Duration { impl Sub<Duration,Duration> for Duration {
fn sub(&self, rhs: &Duration) -> Duration { fn sub(&self, rhs: &Duration) -> Duration {
let mut secs = self.secs - rhs.secs; let mut secs = self.secs - rhs.secs;
@ -280,21 +295,6 @@ impl Sub<Duration,Duration> for Duration {
} }
} }
impl num::CheckedSub for Duration {
fn checked_sub(&self, rhs: &Duration) -> Option<Duration> {
let mut secs = try_opt!(self.secs.checked_sub(&rhs.secs));
let mut nanos = self.nanos - rhs.nanos;
if nanos < 0 {
nanos += NANOS_PER_SEC;
secs = try_opt!(secs.checked_sub(&1));
}
let d = Duration { secs: secs, nanos: nanos };
// Even if d is within the bounds of i64 seconds,
// it might still overflow i64 milliseconds.
if d < MIN || d > MAX { None } else { Some(d) }
}
}
impl Mul<i32,Duration> for Duration { impl Mul<i32,Duration> for Duration {
fn mul(&self, rhs: &i32) -> Duration { fn mul(&self, rhs: &i32) -> Duration {
// Multiply nanoseconds as i64, because it cannot overflow that way. // Multiply nanoseconds as i64, because it cannot overflow that way.
@ -387,15 +387,12 @@ fn div_rem_64(this: i64, other: i64) -> (i64, i64) {
mod tests { mod tests {
use super::{Duration, MIN, MAX}; use super::{Duration, MIN, MAX};
use {i32, i64}; use {i32, i64};
use num::{Zero, CheckedAdd, CheckedSub};
use option::{Some, None}; use option::{Some, None};
use to_string::ToString; use to_string::ToString;
#[test] #[test]
fn test_duration() { fn test_duration() {
let d: Duration = Zero::zero(); assert!(Duration::seconds(1) != Duration::zero());
assert_eq!(d, Zero::zero());
assert!(Duration::seconds(1) != Zero::zero());
assert_eq!(Duration::seconds(1) + Duration::seconds(2), Duration::seconds(3)); assert_eq!(Duration::seconds(1) + Duration::seconds(2), Duration::seconds(3));
assert_eq!(Duration::seconds(86399) + Duration::seconds(4), assert_eq!(Duration::seconds(86399) + Duration::seconds(4),
Duration::days(1) + Duration::seconds(3)); Duration::days(1) + Duration::seconds(3));
@ -411,8 +408,7 @@ mod tests {
#[test] #[test]
fn test_duration_num_days() { fn test_duration_num_days() {
let d: Duration = Zero::zero(); assert_eq!(Duration::zero().num_days(), 0);
assert_eq!(d.num_days(), 0);
assert_eq!(Duration::days(1).num_days(), 1); assert_eq!(Duration::days(1).num_days(), 1);
assert_eq!(Duration::days(-1).num_days(), -1); assert_eq!(Duration::days(-1).num_days(), -1);
assert_eq!(Duration::seconds(86399).num_days(), 0); assert_eq!(Duration::seconds(86399).num_days(), 0);
@ -425,8 +421,7 @@ mod tests {
#[test] #[test]
fn test_duration_num_seconds() { fn test_duration_num_seconds() {
let d: Duration = Zero::zero(); assert_eq!(Duration::zero().num_seconds(), 0);
assert_eq!(d.num_seconds(), 0);
assert_eq!(Duration::seconds(1).num_seconds(), 1); assert_eq!(Duration::seconds(1).num_seconds(), 1);
assert_eq!(Duration::seconds(-1).num_seconds(), -1); assert_eq!(Duration::seconds(-1).num_seconds(), -1);
assert_eq!(Duration::milliseconds(999).num_seconds(), 0); assert_eq!(Duration::milliseconds(999).num_seconds(), 0);
@ -437,8 +432,7 @@ mod tests {
#[test] #[test]
fn test_duration_num_milliseconds() { fn test_duration_num_milliseconds() {
let d: Duration = Zero::zero(); assert_eq!(Duration::zero().num_milliseconds(), 0);
assert_eq!(d.num_milliseconds(), 0);
assert_eq!(Duration::milliseconds(1).num_milliseconds(), 1); assert_eq!(Duration::milliseconds(1).num_milliseconds(), 1);
assert_eq!(Duration::milliseconds(-1).num_milliseconds(), -1); assert_eq!(Duration::milliseconds(-1).num_milliseconds(), -1);
assert_eq!(Duration::microseconds(999).num_milliseconds(), 0); assert_eq!(Duration::microseconds(999).num_milliseconds(), 0);
@ -453,8 +447,7 @@ mod tests {
#[test] #[test]
fn test_duration_num_microseconds() { fn test_duration_num_microseconds() {
let d: Duration = Zero::zero(); assert_eq!(Duration::zero().num_microseconds(), Some(0));
assert_eq!(d.num_microseconds(), Some(0));
assert_eq!(Duration::microseconds(1).num_microseconds(), Some(1)); assert_eq!(Duration::microseconds(1).num_microseconds(), Some(1));
assert_eq!(Duration::microseconds(-1).num_microseconds(), Some(-1)); assert_eq!(Duration::microseconds(-1).num_microseconds(), Some(-1));
assert_eq!(Duration::nanoseconds(999).num_microseconds(), Some(0)); assert_eq!(Duration::nanoseconds(999).num_microseconds(), Some(0));
@ -478,8 +471,7 @@ mod tests {
#[test] #[test]
fn test_duration_num_nanoseconds() { fn test_duration_num_nanoseconds() {
let d: Duration = Zero::zero(); assert_eq!(Duration::zero().num_nanoseconds(), Some(0));
assert_eq!(d.num_nanoseconds(), Some(0));
assert_eq!(Duration::nanoseconds(1).num_nanoseconds(), Some(1)); assert_eq!(Duration::nanoseconds(1).num_nanoseconds(), Some(1));
assert_eq!(Duration::nanoseconds(-1).num_nanoseconds(), Some(-1)); assert_eq!(Duration::nanoseconds(-1).num_nanoseconds(), Some(-1));
assert_eq!(Duration::nanoseconds(i64::MAX).num_nanoseconds(), Some(i64::MAX)); assert_eq!(Duration::nanoseconds(i64::MAX).num_nanoseconds(), Some(i64::MAX));
@ -512,10 +504,9 @@ mod tests {
#[test] #[test]
fn test_duration_mul() { fn test_duration_mul() {
let d: Duration = Zero::zero(); assert_eq!(Duration::zero() * i32::MAX, Duration::zero());
assert_eq!(d * i32::MAX, d); assert_eq!(Duration::zero() * i32::MIN, Duration::zero());
assert_eq!(d * i32::MIN, d); assert_eq!(Duration::nanoseconds(1) * 0, Duration::zero());
assert_eq!(Duration::nanoseconds(1) * 0, Zero::zero());
assert_eq!(Duration::nanoseconds(1) * 1, Duration::nanoseconds(1)); assert_eq!(Duration::nanoseconds(1) * 1, Duration::nanoseconds(1));
assert_eq!(Duration::nanoseconds(1) * 1_000_000_000, Duration::seconds(1)); assert_eq!(Duration::nanoseconds(1) * 1_000_000_000, Duration::seconds(1));
assert_eq!(Duration::nanoseconds(1) * -1_000_000_000, -Duration::seconds(1)); assert_eq!(Duration::nanoseconds(1) * -1_000_000_000, -Duration::seconds(1));
@ -530,9 +521,8 @@ mod tests {
#[test] #[test]
fn test_duration_div() { fn test_duration_div() {
let d: Duration = Zero::zero(); assert_eq!(Duration::zero() / i32::MAX, Duration::zero());
assert_eq!(d / i32::MAX, d); assert_eq!(Duration::zero() / i32::MIN, Duration::zero());
assert_eq!(d / i32::MIN, d);
assert_eq!(Duration::nanoseconds(123_456_789) / 1, Duration::nanoseconds(123_456_789)); assert_eq!(Duration::nanoseconds(123_456_789) / 1, Duration::nanoseconds(123_456_789));
assert_eq!(Duration::nanoseconds(123_456_789) / -1, -Duration::nanoseconds(123_456_789)); assert_eq!(Duration::nanoseconds(123_456_789) / -1, -Duration::nanoseconds(123_456_789));
assert_eq!(-Duration::nanoseconds(123_456_789) / -1, Duration::nanoseconds(123_456_789)); assert_eq!(-Duration::nanoseconds(123_456_789) / -1, Duration::nanoseconds(123_456_789));
@ -548,8 +538,7 @@ mod tests {
#[test] #[test]
fn test_duration_fmt() { fn test_duration_fmt() {
let d: Duration = Zero::zero(); assert_eq!(Duration::zero().to_string(), "PT0S".to_string());
assert_eq!(d.to_string(), "PT0S".to_string());
assert_eq!(Duration::days(42).to_string(), "P42D".to_string()); assert_eq!(Duration::days(42).to_string(), "P42D".to_string());
assert_eq!(Duration::days(-42).to_string(), "-P42D".to_string()); assert_eq!(Duration::days(-42).to_string(), "-P42D".to_string());
assert_eq!(Duration::seconds(42).to_string(), "PT42S".to_string()); assert_eq!(Duration::seconds(42).to_string(), "PT42S".to_string());

View file

@ -34,7 +34,7 @@ use core::prelude::*;
use alloc::arc::Arc; use alloc::arc::Arc;
use collections::Vec; use collections::Vec;
use core::num::next_power_of_two; use core::num::UnsignedInt;
use core::cell::UnsafeCell; use core::cell::UnsafeCell;
use atomic::{AtomicUint,Relaxed,Release,Acquire}; use atomic::{AtomicUint,Relaxed,Release,Acquire};
@ -66,7 +66,7 @@ impl<T: Send> State<T> {
2u 2u
} else { } else {
// use next power of 2 as capacity // use next power of 2 as capacity
next_power_of_two(capacity) capacity.next_power_of_two()
} }
} else { } else {
capacity capacity

View file

@ -19,8 +19,8 @@ use parse::token;
use ptr::P; use ptr::P;
use std::fmt; use std::fmt;
use std::num::Zero;
use std::fmt::Show; use std::fmt::Show;
use std::num::Int;
use std::rc::Rc; use std::rc::Rc;
use serialize::{Encodable, Decodable, Encoder, Decoder}; use serialize::{Encodable, Decodable, Encoder, Decoder};
@ -857,9 +857,9 @@ pub enum Sign {
Plus Plus
} }
impl<T: PartialOrd+Zero> Sign { impl<T: Int> Sign {
pub fn new(n: T) -> Sign { pub fn new(n: T) -> Sign {
if n < Zero::zero() { if n < Int::zero() {
Minus Minus
} else { } else {
Plus Plus

View file

@ -20,6 +20,7 @@ use ptr::P;
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
use std::io::File; use std::io::File;
use std::rc::Rc; use std::rc::Rc;
use std::num::Int;
use std::str; use std::str;
use std::iter; use std::iter;
@ -63,7 +64,7 @@ impl ParseSess {
pub fn reserve_node_ids(&self, count: ast::NodeId) -> ast::NodeId { pub fn reserve_node_ids(&self, count: ast::NodeId) -> ast::NodeId {
let v = self.node_id.get(); let v = self.node_id.get();
match v.checked_add(&count) { match v.checked_add(count) {
Some(next) => { self.node_id.set(next); } Some(next) => { self.node_id.set(next); }
None => panic!("Input too large, ran out of node ids!") None => panic!("Input too large, ran out of node ids!")
} }

View file

@ -87,6 +87,7 @@ use std::collections::HashSet;
use std::io::fs::PathExtensions; use std::io::fs::PathExtensions;
use std::mem::replace; use std::mem::replace;
use std::mem; use std::mem;
use std::num::Float;
use std::rc::Rc; use std::rc::Rc;
use std::iter; use std::iter;

View file

@ -58,6 +58,7 @@ use std::io::fs::PathExtensions;
use std::io::stdio::StdWriter; use std::io::stdio::StdWriter;
use std::io::{File, ChanReader, ChanWriter}; use std::io::{File, ChanReader, ChanWriter};
use std::io; use std::io;
use std::num::{Float, FloatMath, Int};
use std::os; use std::os;
use std::string::String; use std::string::String;
use std::task::TaskBuilder; use std::task::TaskBuilder;
@ -105,7 +106,6 @@ enum NamePadding { PadNone, PadOnLeft, PadOnRight }
impl TestDesc { impl TestDesc {
fn padded_name(&self, column_count: uint, align: NamePadding) -> String { fn padded_name(&self, column_count: uint, align: NamePadding) -> String {
use std::num::Saturating;
let mut name = String::from_str(self.name.as_slice()); let mut name = String::from_str(self.name.as_slice());
let fill = column_count.saturating_sub(name.len()); let fill = column_count.saturating_sub(name.len());
let mut pad = " ".repeat(fill); let mut pad = " ".repeat(fill);

View file

@ -16,8 +16,7 @@ use std::fmt::Show;
use std::hash::Hash; use std::hash::Hash;
use std::io; use std::io;
use std::mem; use std::mem;
use std::num::Zero; use std::num::{Float, FloatMath};
use std::num;
fn local_cmp<T:Float>(x: T, y: T) -> Ordering { fn local_cmp<T:Float>(x: T, y: T) -> Ordering {
// arbitrarily decide that NaNs are larger than everything. // arbitrarily decide that NaNs are larger than everything.
@ -145,7 +144,6 @@ pub struct Summary<T> {
} }
impl<T: FloatMath + FromPrimitive> Summary<T> { impl<T: FloatMath + FromPrimitive> Summary<T> {
/// Construct a new summary of a sample set. /// Construct a new summary of a sample set.
pub fn new(samples: &[T]) -> Summary<T> { pub fn new(samples: &[T]) -> Summary<T> {
Summary { Summary {
@ -166,7 +164,6 @@ impl<T: FloatMath + FromPrimitive> Summary<T> {
} }
impl<'a, T: FloatMath + FromPrimitive> Stats<T> for &'a [T] { impl<'a, T: FloatMath + FromPrimitive> Stats<T> for &'a [T] {
// FIXME #11059 handle NaN, inf and overflow // FIXME #11059 handle NaN, inf and overflow
fn sum(self) -> T { fn sum(self) -> T {
let mut partials = vec![]; let mut partials = vec![];
@ -176,15 +173,15 @@ impl<'a, T: FloatMath + FromPrimitive> Stats<T> for &'a [T] {
// This inner loop applies `hi`/`lo` summation to each // This inner loop applies `hi`/`lo` summation to each
// partial so that the list of partial sums remains exact. // partial so that the list of partial sums remains exact.
for i in range(0, partials.len()) { for i in range(0, partials.len()) {
let mut y = partials[i]; let mut y: T = partials[i];
if num::abs(x) < num::abs(y) { if x.abs() < y.abs() {
mem::swap(&mut x, &mut y); mem::swap(&mut x, &mut y);
} }
// Rounded `x+y` is stored in `hi` with round-off stored in // Rounded `x+y` is stored in `hi` with round-off stored in
// `lo`. Together `hi+lo` are exactly equal to `x+y`. // `lo`. Together `hi+lo` are exactly equal to `x+y`.
let hi = x + y; let hi = x + y;
let lo = y - (hi - x); let lo = y - (hi - x);
if !lo.is_zero() { if lo != Float::zero() {
partials[j] = lo; partials[j] = lo;
j += 1; j += 1;
} }
@ -197,7 +194,7 @@ impl<'a, T: FloatMath + FromPrimitive> Stats<T> for &'a [T] {
partials.truncate(j+1); partials.truncate(j+1);
} }
} }
let zero: T = Zero::zero(); let zero: T = Float::zero();
partials.iter().fold(zero, |p, q| p + *q) partials.iter().fold(zero, |p, q| p + *q)
} }
@ -222,10 +219,10 @@ impl<'a, T: FloatMath + FromPrimitive> Stats<T> for &'a [T] {
fn var(self) -> T { fn var(self) -> T {
if self.len() < 2 { if self.len() < 2 {
Zero::zero() Float::zero()
} else { } else {
let mean = self.mean(); let mean = self.mean();
let mut v: T = Zero::zero(); let mut v: T = Float::zero();
for s in self.iter() { for s in self.iter() {
let x = *s - mean; let x = *s - mean;
v = v + x*x; v = v + x*x;
@ -249,7 +246,7 @@ impl<'a, T: FloatMath + FromPrimitive> Stats<T> for &'a [T] {
fn median_abs_dev(self) -> T { fn median_abs_dev(self) -> T {
let med = self.median(); let med = self.median();
let abs_devs: Vec<T> = self.iter().map(|&v| num::abs(med - v)).collect(); let abs_devs: Vec<T> = self.iter().map(|&v| (med - v).abs()).collect();
// This constant is derived by smarter statistics brains than me, but it is // This constant is derived by smarter statistics brains than me, but it is
// consistent with how R and other packages treat the MAD. // consistent with how R and other packages treat the MAD.
let number = FromPrimitive::from_f64(1.4826).unwrap(); let number = FromPrimitive::from_f64(1.4826).unwrap();
@ -294,7 +291,7 @@ fn percentile_of_sorted<T: Float + FromPrimitive>(sorted_samples: &[T],
if sorted_samples.len() == 1 { if sorted_samples.len() == 1 {
return sorted_samples[0]; return sorted_samples[0];
} }
let zero: T = Zero::zero(); let zero: T = Float::zero();
assert!(zero <= pct); assert!(zero <= pct);
let hundred = FromPrimitive::from_uint(100).unwrap(); let hundred = FromPrimitive::from_uint(100).unwrap();
assert!(pct <= hundred); assert!(pct <= hundred);
@ -370,14 +367,14 @@ pub fn write_boxplot<T: Float + Show + FromPrimitive>(
let himag = ten.powf(s.max.abs().log10().floor()); let himag = ten.powf(s.max.abs().log10().floor());
// need to consider when the limit is zero // need to consider when the limit is zero
let zero: T = Zero::zero(); let zero: T = Float::zero();
let lo = if lomag.is_zero() { let lo = if lomag == Float::zero() {
zero zero
} else { } else {
(s.min / lomag).floor() * lomag (s.min / lomag).floor() * lomag
}; };
let hi = if himag.is_zero() { let hi = if himag == Float::zero() {
zero zero
} else { } else {
(s.max / himag).ceil() * himag (s.max / himag).ceil() * himag
@ -464,6 +461,7 @@ mod tests {
macro_rules! assert_approx_eq( macro_rules! assert_approx_eq(
($a:expr, $b:expr) => ({ ($a:expr, $b:expr) => ({
use std::num::Float;
let (a, b) = (&$a, &$b); let (a, b) = (&$a, &$b);
assert!((*a - *b).abs() < 1.0e-6, assert!((*a - *b).abs() < 1.0e-6,
"{} is not approximately equal to {}", *a, *b); "{} is not approximately equal to {}", *a, *b);

View file

@ -31,7 +31,7 @@ extern crate libc;
use std::fmt::Show; use std::fmt::Show;
use std::fmt; use std::fmt;
use std::io::BufReader; use std::io::BufReader;
use std::num; use std::num::SignedInt;
use std::string::String; use std::string::String;
use std::time::Duration; use std::time::Duration;
@ -758,7 +758,7 @@ impl<'a> fmt::Show for TmFmt<'a> {
'Z' => if tm.tm_gmtoff == 0_i32 { "GMT"} else { "" }, // FIXME (#2350): support locale 'Z' => if tm.tm_gmtoff == 0_i32 { "GMT"} else { "" }, // FIXME (#2350): support locale
'z' => { 'z' => {
let sign = if tm.tm_gmtoff > 0_i32 { '+' } else { '-' }; let sign = if tm.tm_gmtoff > 0_i32 { '+' } else { '-' };
let mut m = num::abs(tm.tm_gmtoff) / 60_i32; let mut m = tm.tm_gmtoff.abs() / 60_i32;
let h = m / 60_i32; let h = m / 60_i32;
m -= h * 60_i32; m -= h * 60_i32;
return write!(fmt, "{}{:02d}{:02d}", sign, h, m); return write!(fmt, "{}{:02d}{:02d}", sign, h, m);
@ -800,7 +800,7 @@ impl<'a> fmt::Show for TmFmt<'a> {
format: FmtStr("%Y-%m-%dT%H:%M:%S"), format: FmtStr("%Y-%m-%dT%H:%M:%S"),
}; };
let sign = if self.tm.tm_gmtoff > 0_i32 { '+' } else { '-' }; let sign = if self.tm.tm_gmtoff > 0_i32 { '+' } else { '-' };
let mut m = num::abs(self.tm.tm_gmtoff) / 60_i32; let mut m = self.tm.tm_gmtoff.abs() / 60_i32;
let h = m / 60_i32; let h = m / 60_i32;
m -= h * 60_i32; m -= h * 60_i32;
write!(fmt, "{}{}{:02d}:{:02d}", s, sign, h as int, m as int) write!(fmt, "{}{}{:02d}:{:02d}", s, sign, h as int, m as int)

View file

@ -13,6 +13,7 @@
// ignore-lexer-test FIXME #15679 // ignore-lexer-test FIXME #15679
use std::f32::consts::PI; use std::f32::consts::PI;
use std::num::{Float, FloatMath};
use std::rand::{Rng, StdRng}; use std::rand::{Rng, StdRng};
struct Vec2 { struct Vec2 {

View file

@ -43,6 +43,7 @@
use std::io; use std::io;
use std::io::{BufferedWriter, File}; use std::io::{BufferedWriter, File};
use std::cmp::min; use std::cmp::min;
use std::num::Float;
use std::os; use std::os;
const LINE_LENGTH: uint = 60; const LINE_LENGTH: uint = 60;

View file

@ -19,6 +19,7 @@ extern crate collections;
use std::collections::HashMap; use std::collections::HashMap;
use std::mem::replace; use std::mem::replace;
use std::num::Float;
use std::option; use std::option;
use std::os; use std::os;
use std::string::String; use std::string::String;

View file

@ -38,6 +38,8 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE. // OF THE POSSIBILITY OF SUCH DAMAGE.
use std::num::Float;
const PI: f64 = 3.141592653589793; const PI: f64 = 3.141592653589793;
const SOLAR_MASS: f64 = 4.0 * PI * PI; const SOLAR_MASS: f64 = 4.0 * PI * PI;
const YEAR: f64 = 365.24; const YEAR: f64 = 365.24;

View file

@ -45,6 +45,7 @@
use std::iter::AdditiveIterator; use std::iter::AdditiveIterator;
use std::mem; use std::mem;
use std::num::Float;
use std::os; use std::os;
use std::raw::Repr; use std::raw::Repr;
use std::simd::f64x2; use std::simd::f64x2;

View file

@ -15,6 +15,7 @@
use std::io; use std::io;
use std::io::stdio::StdReader; use std::io::stdio::StdReader;
use std::io::BufferedReader; use std::io::BufferedReader;
use std::num::Int;
use std::os; use std::os;
// Computes a single solution to a given 9x9 sudoku // Computes a single solution to a given 9x9 sudoku

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use std::num::SignedInt;
fn main() { fn main() {
let _f = 10i.abs; //~ ERROR attempted to take value of method let _f = 10i.abs; //~ ERROR attempted to take value of method
} }

View file

@ -8,15 +8,15 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use std::num::Num; use std::num::Int;
trait BrokenAdd: Num { trait BrokenAdd: Int {
fn broken_add<T>(&self, rhs: T) -> Self { fn broken_add<T>(&self, rhs: T) -> Self {
*self + rhs //~ ERROR expected `Self`, found `T` *self + rhs //~ ERROR expected `Self`, found `T`
} }
} }
impl<T: Num> BrokenAdd for T {} impl<T: Int> BrokenAdd for T {}
pub fn main() { pub fn main() {
let foo: u8 = 0u8; let foo: u8 = 0u8;

View file

@ -12,6 +12,7 @@
macro_rules! assert_approx_eq( macro_rules! assert_approx_eq(
($a:expr, $b:expr) => ({ ($a:expr, $b:expr) => ({
use std::num::Float;
let (a, b) = (&$a, &$b); let (a, b) = (&$a, &$b);
assert!((*a - *b).abs() < 1.0e-6, assert!((*a - *b).abs() < 1.0e-6,
"{} is not approximately equal to {}", *a, *b); "{} is not approximately equal to {}", *a, *b);

View file

@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use std::num::Int;
extern "C" fn foo<T: Int>(a: T, b: T) -> T { a + b } extern "C" fn foo<T: Int>(a: T, b: T) -> T { a + b }
fn main() { fn main() {

View file

@ -13,6 +13,7 @@
macro_rules! assert_approx_eq( macro_rules! assert_approx_eq(
($a:expr, $b:expr) => ({ ($a:expr, $b:expr) => ({
use std::num::Float;
let (a, b) = (&$a, &$b); let (a, b) = (&$a, &$b);
assert!((*a - *b).abs() < 1.0e-6, assert!((*a - *b).abs() < 1.0e-6,
"{} is not approximately equal to {}", *a, *b); "{} is not approximately equal to {}", *a, *b);

View file

@ -11,6 +11,7 @@
extern crate collections; extern crate collections;
use std::collections::Bitv; use std::collections::Bitv;
use std::num::Float;
fn main() { fn main() {
// Generate sieve of Eratosthenes for n up to 1e6 // Generate sieve of Eratosthenes for n up to 1e6

View file

@ -12,11 +12,11 @@
use std::cmp::{PartialEq, PartialOrd}; use std::cmp::{PartialEq, PartialOrd};
use std::num::NumCast; use std::num::NumCast;
pub trait NumExt: Num + NumCast + PartialEq + PartialOrd {} pub trait NumExt: NumCast + PartialEq + PartialOrd {}
pub trait FloatExt: NumExt {} pub trait FloatExt: NumExt {}
fn greater_than_one<T:NumExt>(n: &T) -> bool { *n > NumCast::from(1i).unwrap() } fn greater_than_one<T: NumExt>(n: &T) -> bool { *n > NumCast::from(1i).unwrap() }
fn greater_than_one_float<T:FloatExt>(n: &T) -> bool { *n > NumCast::from(1i).unwrap() } fn greater_than_one_float<T: FloatExt>(n: &T) -> bool { *n > NumCast::from(1i).unwrap() }
pub fn main() {} pub fn main() {}

View file

@ -11,6 +11,7 @@
// Extending Num and using inherited static methods // Extending Num and using inherited static methods
use std::cmp::PartialOrd;
use std::num::NumCast; use std::num::NumCast;
pub trait Num { pub trait Num {
@ -18,7 +19,7 @@ pub trait Num {
fn gt(&self, other: &Self) -> bool; fn gt(&self, other: &Self) -> bool;
} }
pub trait NumExt: Num + NumCast { } pub trait NumExt: NumCast + PartialOrd { }
fn greater_than_one<T:NumExt>(n: &T) -> bool { fn greater_than_one<T:NumExt>(n: &T) -> bool {
n.gt(&NumCast::from(1i).unwrap()) n.gt(&NumCast::from(1i).unwrap())

View file

@ -11,7 +11,7 @@
use std::cmp::PartialOrd; use std::cmp::PartialOrd;
use std::num::NumCast; use std::num::NumCast;
pub trait NumExt: Num + NumCast + PartialOrd { } pub trait NumExt: NumCast + PartialOrd { }
fn greater_than_one<T:NumExt>(n: &T) -> bool { fn greater_than_one<T:NumExt>(n: &T) -> bool {
*n > NumCast::from(1i).unwrap() *n > NumCast::from(1i).unwrap()

View file

@ -12,6 +12,7 @@
// A more complex example of numeric extensions // A more complex example of numeric extensions
use std::cmp::{PartialEq, PartialOrd}; use std::cmp::{PartialEq, PartialOrd};
use std::num::NumCast;
pub trait TypeExt {} pub trait TypeExt {}
@ -32,7 +33,7 @@ impl TypeExt for f32 {}
impl TypeExt for f64 {} impl TypeExt for f64 {}
pub trait NumExt: TypeExt + PartialEq + PartialOrd + Num + NumCast {} pub trait NumExt: TypeExt + PartialEq + PartialOrd + NumCast {}
impl NumExt for u8 {} impl NumExt for u8 {}
impl NumExt for u16 {} impl NumExt for u16 {}

View file

@ -11,11 +11,11 @@
use std::cmp::{PartialEq, PartialOrd}; use std::cmp::{PartialEq, PartialOrd};
use std::num::NumCast; use std::num::NumCast;
pub trait NumExt: PartialEq + PartialOrd + Num + NumCast {} pub trait NumExt: PartialEq + PartialOrd + NumCast {}
impl NumExt for f32 {} impl NumExt for f32 {}
fn num_eq_one<T:NumExt>(n: T) { fn num_eq_one<T: NumExt>(n: T) {
println!("{}", n == NumCast::from(1i).unwrap()) println!("{}", n == NumCast::from(1i).unwrap())
} }

View file

@ -11,7 +11,7 @@
use std::cmp::PartialEq; use std::cmp::PartialEq;
use std::num::NumCast; use std::num::NumCast;
pub trait NumExt: PartialEq + Num + NumCast {} pub trait NumExt: PartialEq + NumCast {}
impl NumExt for f32 {} impl NumExt for f32 {}
impl NumExt for int {} impl NumExt for int {}

View file

@ -10,7 +10,7 @@
// Test for issue #4183: use of Self in supertraits. // Test for issue #4183: use of Self in supertraits.
use std::num; use std::num::Float as StdFloat;
pub static FUZZY_EPSILON: f64 = 0.1; pub static FUZZY_EPSILON: f64 = 0.1;
@ -29,7 +29,7 @@ impl FuzzyEq<f32> for f32 {
} }
fn fuzzy_eq_eps(&self, other: &f32, epsilon: &f32) -> bool { fn fuzzy_eq_eps(&self, other: &f32, epsilon: &f32) -> bool {
num::abs(*self - *other) < *epsilon (*self - *other).abs() < *epsilon
} }
} }
@ -43,7 +43,7 @@ impl FuzzyEq<f64> for f64 {
} }
fn fuzzy_eq_eps(&self, other: &f64, epsilon: &f64) -> bool { fn fuzzy_eq_eps(&self, other: &f64, epsilon: &f64) -> bool {
num::abs(*self - *other) < *epsilon (*self - *other).abs() < *epsilon
} }
} }

View file

@ -10,16 +10,15 @@
// //
// ignore-lexer-test FIXME #15679 // ignore-lexer-test FIXME #15679
#![feature(non_ascii_idents)] #![feature(non_ascii_idents)]
use std::num; use std::num::Float;
pub fn main() { pub fn main() {
let ε = 0.00001f64; let ε = 0.00001f64;
let Π = 3.14f64; let Π = 3.14f64;
let = Π * Π + 1.54; let = Π * Π + 1.54;
assert!(num::abs(( - 1.54) - (Π * Π)) < ε); assert!((( - 1.54) - (Π * Π)).abs() < ε);
assert_eq!(_გემრიელი_სადილი(), 0); assert_eq!(_გემრიელი_სადილი(), 0);
} }