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.
~~~
# use std::num::Float;
# struct Point {x: f64, y: f64}
# fn sqrt(f: f64) -> f64 { 0.0 }
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.
```{rust}
# use std::num::Float;
# use std::sync::Future;
fn partial_sum(start: uint) -> f64 {
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.
```{rust}
use std::num::Float;
use std::rand;
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 RandomAccessIterator CloneableIterator
syn keyword rustTrait OrdIterator MutableDoubleEndedIterator
syn keyword rustTrait Num NumCast CheckedAdd CheckedSub CheckedMul CheckedDiv
syn keyword rustTrait Signed Unsigned Primitive Int Float
syn keyword rustTrait NumCast Int SignedInt UnsignedInt Float
syn keyword rustTrait FloatMath ToPrimitive FromPrimitive
syn keyword rustTrait Box
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;
use std::mem;
use std::num;
use std::num::{Int, UnsignedInt};
use std::ptr;
use std::rc::Rc;
use std::rt::heap::{allocate, deallocate};
@ -132,7 +132,7 @@ impl Drop for Arena {
#[inline]
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
@ -187,7 +187,7 @@ impl Arena {
self.chunks.borrow_mut().push(self.copy_head.borrow().clone());
*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);
}
@ -228,7 +228,7 @@ impl Arena {
self.chunks.borrow_mut().push(self.head.borrow().clone());
*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);
}
@ -376,8 +376,8 @@ fn calculate_size<T>(capacity: uint) -> uint {
let mut size = mem::size_of::<TypedArenaChunk<T>>();
size = round_up(size, mem::min_align_of::<T>());
let elem_size = mem::size_of::<T>();
let elems_size = elem_size.checked_mul(&capacity).unwrap();
size = size.checked_add(&elems_size).unwrap();
let elems_size = elem_size.checked_mul(capacity).unwrap();
size = size.checked_add(elems_size).unwrap();
size
}
@ -432,7 +432,7 @@ impl<T> TypedArenaChunk<T> {
#[inline]
fn end(&self) -> *const u8 {
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)
}
}
@ -481,7 +481,7 @@ impl<T> TypedArena<T> {
fn grow(&self) {
unsafe {
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);
self.ptr.set((*chunk).start() as *const T);
self.end.set((*chunk).end() as *const T);

View File

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

View File

@ -15,6 +15,7 @@
use core::prelude::*;
use core::fmt;
use core::num::Int;
// 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 core::intrinsics::TypeId;
use core::mem;
use core::num::Int;
use vec::Vec;

View File

@ -21,7 +21,7 @@ use core::default::Default;
use core::fmt;
use core::kinds::marker::{ContravariantLifetime, InvariantType};
use core::mem;
use core::num;
use core::num::{Int, UnsignedInt};
use core::ops;
use core::ptr;
use core::raw::Slice as RawSlice;
@ -161,7 +161,7 @@ impl<T> Vec<T> {
} else if capacity == 0 {
Vec::new()
} else {
let size = capacity.checked_mul(&mem::size_of::<T>())
let size = capacity.checked_mul(mem::size_of::<T>())
.expect("capacity overflow");
let ptr = unsafe { allocate(size, mem::min_align_of::<T>()) };
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"]
pub fn reserve(&mut self, additional: uint) {
if self.cap - self.len < additional {
match self.len.checked_add(&additional) {
match self.len.checked_add(additional) {
None => panic!("Vec::reserve: `uint` overflow"),
// if the checked_add
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
if amort_cap == 0 {
self.grow_capacity(new_cap);
@ -624,7 +624,7 @@ impl<T> Vec<T> {
#[unstable = "matches collection reform specification, waiting for dust to settle"]
pub fn reserve_exact(&mut self, additional: uint) {
if self.cap - self.len < additional {
match self.len.checked_add(&additional) {
match self.len.checked_add(additional) {
None => panic!("Vec::reserve: `uint` overflow"),
Some(new_cap) => self.grow_capacity(new_cap)
}
@ -957,7 +957,7 @@ impl<T> Vec<T> {
pub fn push(&mut self, value: T) {
if mem::size_of::<T>() == 0 {
// 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); }
return
}
@ -1050,7 +1050,7 @@ impl<T> Vec<T> {
if mem::size_of::<T>() == 0 { return }
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");
unsafe {
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:
//!
//! ```rust
//! use core::num::SignedInt;
//!
//! // Our type.
//! struct SketchyNum {
//! num : int

View File

@ -13,8 +13,8 @@
use char;
use fmt;
use iter::{range, DoubleEndedIterator};
use num::{Float, FPNaN, FPInfinite, ToPrimitive, Primitive};
use num::{Zero, One, cast};
use num::{Float, FPNaN, FPInfinite, ToPrimitive};
use num::cast;
use result::Ok;
use slice::{mod, SlicePrelude};
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
* 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,
radix: uint,
negative_zero: bool,
@ -97,8 +97,8 @@ pub fn float_to_str_bytes_common<T: Primitive + Float, U>(
_ => ()
}
let _0: T = Zero::zero();
let _1: T = One::one();
let _0: T = Float::zero();
let _1: T = Float::one();
match num.classify() {
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) => {
impl Float for $ty {
fn fmt(&self, fmt: &mut Formatter) -> Result {
use num::{Float, Signed};
use num::Float;
let digits = match fmt.precision {
Some(i) => float::DigExact(i),
@ -641,7 +641,7 @@ macro_rules! floating(($ty:ident) => {
impl LowerExp for $ty {
fn fmt(&self, fmt: &mut Formatter) -> Result {
use num::{Float, Signed};
use num::Float;
let digits = match fmt.precision {
Some(i) => float::DigExact(i),
@ -662,7 +662,7 @@ macro_rules! floating(($ty:ident) => {
impl UpperExp for $ty {
fn fmt(&self, fmt: &mut Formatter) -> Result {
use num::{Float, Signed};
use num::Float;
let digits = match fmt.precision {
Some(i) => float::DigExact(i),

View File

@ -16,7 +16,7 @@
use fmt;
use iter::DoubleEndedIterator;
use num::{Int, cast, zero};
use num::{Int, cast};
use slice::SlicePrelude;
/// 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 {
// The radix can be as low as 2, so we need a buffer of at least 64
// characters for a base 2 number.
let zero = Int::zero();
let is_positive = x >= zero;
let mut buf = [0u8, ..64];
let base = cast(self.base()).unwrap();
let mut curr = buf.len();
let is_positive = x >= zero();
let base = cast(self.base()).unwrap();
if is_positive {
// Accumulate each digit of the number from the least significant
// to the most significant figure.
@ -47,16 +48,16 @@ trait GenericRadix {
x = x / base; // Deaccumulate the number.
*byte = self.digit(cast(n).unwrap()); // Store the digit in the buffer.
curr -= 1;
if x == zero() { break; } // No more digits left to accumulate.
if x == zero { break }; // No more digits left to accumulate.
}
} else {
// Do the same as above, but accounting for two's complement.
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.
*byte = self.digit(cast(n).unwrap()); // Store the digit in the buffer.
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..])

View File

@ -60,10 +60,10 @@ This `for` loop syntax can be applied to any iterator over any type.
use clone::Clone;
use cmp;
use cmp::{PartialEq, PartialOrd, Ord};
use cmp::Ord;
use mem;
use num::{Zero, One, CheckedAdd, CheckedSub, Saturating, ToPrimitive, Int};
use ops::{Add, Mul, Sub};
use num::{ToPrimitive, Int};
use ops::Add;
use option::{Option, Some, None};
use uint;
#[deprecated = "renamed to Extend"] pub use self::Extend as Extendable;
@ -573,6 +573,8 @@ pub trait Iterator<A> {
/// # Example
///
/// ```rust
/// use core::num::SignedInt;
///
/// let xs = [-3i, 0, 1, 5, -10];
/// assert_eq!(*xs.iter().max_by(|x| x.abs()).unwrap(), -10);
/// ```
@ -597,6 +599,8 @@ pub trait Iterator<A> {
/// # Example
///
/// ```rust
/// use core::num::SignedInt;
///
/// let xs = [-3i, 0, 1, 5, -10];
/// assert_eq!(*xs.iter().min_by(|x| x.abs()).unwrap(), 0);
/// ```
@ -785,13 +789,28 @@ pub trait AdditiveIterator<A> {
fn sum(&mut self) -> A;
}
impl<A: Add<A, A> + Zero, T: Iterator<A>> AdditiveIterator<A> for T {
#[inline]
fn sum(&mut self) -> A {
let zero: A = Zero::zero();
self.fold(zero, |s, x| s + x)
}
macro_rules! impl_additive {
($A:ty, $init:expr) => {
impl<T: Iterator<$A>> AdditiveIterator<$A> for T {
#[inline]
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.
pub trait MultiplicativeIterator<A> {
@ -812,13 +831,28 @@ pub trait MultiplicativeIterator<A> {
fn product(&mut self) -> A;
}
impl<A: Mul<A, A> + One, T: Iterator<A>> MultiplicativeIterator<A> for T {
#[inline]
fn product(&mut self) -> A {
let one: A = One::one();
self.fold(one, |p, x| p * x)
}
macro_rules! impl_multiplicative {
($A:ty, $init:expr) => {
impl<T: Iterator<$A>> MultiplicativeIterator<$A> for T {
#[inline]
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.
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 upper = match (a_upper, b_upper) {
(Some(x), Some(y)) => x.checked_add(&y),
(Some(x), Some(y)) => x.checked_add(y),
_ => None
};
@ -1415,7 +1449,7 @@ impl<A, T: Iterator<A>> Iterator<A> for Peekable<A, T> {
if self.peeked.is_some() {
let lo = lo.saturating_add(1);
let hi = match hi {
Some(x) => x.checked_add(&1),
Some(x) => x.checked_add(1),
None => None
};
(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 lo = flo.saturating_add(blo);
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)
}
}
@ -1905,7 +1939,7 @@ impl<A: Add<A, A> + Clone> Iterator<A> for Counter<A> {
pub struct Range<A> {
state: A,
stop: A,
one: A
one: A,
}
/// Returns an iterator over the given range [start, stop) (that is, starting
@ -1922,12 +1956,16 @@ pub struct Range<A> {
/// }
/// ```
#[inline]
pub fn range<A: Add<A, A> + PartialOrd + Clone + One>(start: A, stop: A) -> Range<A> {
Range{state: start, stop: stop, one: One::one()}
pub fn range<A: Int>(start: A, stop: A) -> Range<A> {
Range {
state: start,
stop: stop,
one: Int::one(),
}
}
// 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]
fn next(&mut self) -> Option<A> {
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.
let bound = match self.state.to_i64() {
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 {
Some(Some(bound)) => bound.to_uint(),
_ => None,
@ -1954,7 +1992,7 @@ impl<A: Add<A, A> + PartialOrd + Clone + ToPrimitive> Iterator<A> for Range<A> {
},
None => match self.state.to_u64() {
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 {
Some(Some(bound)) => bound.to_uint(),
_ => 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
/// 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]
fn next_back(&mut self) -> Option<A> {
if self.stop > self.state {
@ -1995,12 +2033,14 @@ pub struct RangeInclusive<A> {
/// Return an iterator over the range [start, stop]
#[inline]
pub fn range_inclusive<A: Add<A, A> + PartialOrd + Clone + One>(start: A, stop: A)
-> RangeInclusive<A> {
RangeInclusive{range: range(start, stop), done: false}
pub fn range_inclusive<A: Int>(start: A, stop: A) -> RangeInclusive<A> {
RangeInclusive {
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]
fn next(&mut self) -> Option<A> {
match self.range.next() {
@ -2024,7 +2064,7 @@ impl<A: Add<A, A> + PartialOrd + Clone + ToPrimitive> Iterator<A> for RangeInclu
} else {
let lo = lo.saturating_add(1);
let hi = match hi {
Some(x) => x.checked_add(&1),
Some(x) => x.checked_add(1),
None => None
};
(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>
for RangeInclusive<A> {
impl<A: Int + ToPrimitive> DoubleEndedIterator<A> for RangeInclusive<A> {
#[inline]
fn next_back(&mut self) -> Option<A> {
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.
#[inline]
pub fn range_step<A: CheckedAdd + PartialOrd +
Clone + Zero>(start: A, stop: A, step: A) -> RangeStep<A> {
let rev = step < Zero::zero();
pub fn range_step<A: Int>(start: A, stop: A, step: A) -> RangeStep<A> {
let rev = step < Int::zero();
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]
fn next(&mut self) -> Option<A> {
if (self.rev && self.state > self.stop) || (!self.rev && self.state < self.stop) {
let result = self.state.clone();
match self.state.checked_add(&self.step) {
let result = self.state;
match self.state.checked_add(self.step) {
Some(x) => self.state = x,
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.
#[inline]
pub fn range_step_inclusive<A: CheckedAdd + PartialOrd + Clone + Zero>(start: A, stop: A,
step: A) -> RangeStepInclusive<A> {
let rev = step < Zero::zero();
RangeStepInclusive{state: start, stop: stop, step: step, rev: rev, done: false}
pub fn range_step_inclusive<A: Int>(start: A, stop: A, step: A) -> RangeStepInclusive<A> {
let rev = step < Int::zero();
RangeStepInclusive {
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]
fn next(&mut self) -> Option<A> {
if !self.done && ((self.rev && self.state >= self.stop) ||
(!self.rev && self.state <= self.stop)) {
let result = self.state.clone();
match self.state.checked_add(&self.step) {
let result = self.state;
match self.state.checked_add(self.step) {
Some(x) => self.state = x,
None => self.done = true
}

View File

@ -114,9 +114,15 @@ impl Float for f32 {
#[inline]
fn neg_infinity() -> f32 { NEG_INFINITY }
#[inline]
fn zero() -> f32 { 0.0 }
#[inline]
fn neg_zero() -> f32 { -0.0 }
#[inline]
fn one() -> f32 { 1.0 }
/// Returns `true` if the number is NaN.
#[inline]
fn is_nan(self) -> bool { self != self }
@ -177,9 +183,15 @@ impl Float for f32 {
#[inline]
fn max_10_exp(_: Option<f32>) -> int { MAX_10_EXP }
#[inline]
fn min_value() -> f32 { MIN_VALUE }
#[inline]
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.
fn integer_decode(self) -> (u64, i16, i8) {
let bits: u32 = unsafe { mem::transmute(self) };
@ -222,12 +234,49 @@ impl Float for f32 {
/// The fractional part of the number, satisfying:
///
/// ```rust
/// use core::num::Float;
///
/// let x = 1.65f32;
/// assert!(x == x.trunc() + x.fract())
/// ```
#[inline]
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
/// error. This produces a more accurate result with better performance than
/// a separate multiplication operation followed by an add.
@ -240,6 +289,7 @@ impl Float for f32 {
#[inline]
fn recip(self) -> f32 { 1.0 / self }
#[inline]
fn powi(self, n: i32) -> f32 {
unsafe { intrinsics::powif32(self, n) }
}

View File

@ -120,9 +120,15 @@ impl Float for f64 {
#[inline]
fn neg_infinity() -> f64 { NEG_INFINITY }
#[inline]
fn zero() -> f64 { 0.0 }
#[inline]
fn neg_zero() -> f64 { -0.0 }
#[inline]
fn one() -> f64 { 1.0 }
/// Returns `true` if the number is NaN.
#[inline]
fn is_nan(self) -> bool { self != self }
@ -183,9 +189,15 @@ impl Float for f64 {
#[inline]
fn max_10_exp(_: Option<f64>) -> int { MAX_10_EXP }
#[inline]
fn min_value() -> f64 { MIN_VALUE }
#[inline]
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.
fn integer_decode(self) -> (u64, i16, i8) {
let bits: u64 = unsafe { mem::transmute(self) };
@ -228,12 +240,49 @@ impl Float for f64 {
/// The fractional part of the number, satisfying:
///
/// ```rust
/// use core::num::Float;
///
/// let x = 1.65f64;
/// assert!(x == x.trunc() + x.fract())
/// ```
#[inline]
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
/// error. This produces a more accurate result with better performance than
/// a separate multiplication operation followed by an add.

View File

@ -13,6 +13,7 @@
macro_rules! assert_approx_eq(
($a:expr, $b:expr) => ({
use num::Float;
let (a, b) = (&$a, &$b);
assert!((*a - *b).abs() < 1.0e-6,
"{} 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::{Iterator, DoubleEndedIterator, RandomAccessIterator, CloneableIterator};
pub use iter::{OrdIterator, MutableDoubleEndedIterator, ExactSize};
pub use num::{Num, NumCast, CheckedAdd, CheckedSub, CheckedMul};
pub use num::{Signed, Unsigned, Float};
pub use num::{Primitive, Int, ToPrimitive, FromPrimitive};
pub use num::{ToPrimitive, FromPrimitive};
pub use option::{Option, Some, None};
pub use ptr::RawPtr;
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 default::Default;
use iter::*;
use num::{CheckedAdd, Saturating, div_rem};
use num::{Int, div_rem};
use ops;
use option::{None, Option, Some};
use ptr;
@ -1346,7 +1346,7 @@ impl<'a, T> Iterator<&'a [T]> for Windows<'a, T> {
(0, Some(0))
} else {
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::range;
use kinds::Sized;
use num::{CheckedMul, Saturating};
use num::Int;
use option::{Option, None, Some};
use raw::Repr;
use slice::{mod, SlicePrelude};
@ -750,7 +750,7 @@ impl<'a> Iterator<u16> for Utf16CodeUnits<'a> {
// every char gets either one u16 or two u16,
// so this iterator is between 1 or 2 times as
// 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]
fn test_user_defined_eq() {
use core::num::SignedInt;
// Our type.
struct SketchyNum {
num : int

View File

@ -10,9 +10,9 @@
use core::iter::*;
use core::iter::order::*;
use core::num::SignedInt;
use core::uint;
use core::cmp;
use core::num;
use core::ops::Slice;
use test::Bencher;
@ -689,50 +689,6 @@ fn test_double_ended_range() {
#[test]
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(-10i, -1).collect::<Vec<int>>() ==
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
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(Foo, Foo).size_hint(), (0, None));
}
#[test]

View File

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

View File

@ -8,7 +8,10 @@
// option. This file may not be copied, modified, or distributed
// 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 i8;
@ -24,7 +27,12 @@ mod u64;
mod uint;
/// 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.sub(&two), cast(8i).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)]
mod tests {
use core::$T_i::*;
use core::num::Int;
use num;
use core::num::CheckedDiv;
#[test]
fn test_overflows() {
@ -120,8 +120,8 @@ mod tests {
#[test]
fn test_unsigned_checked_div() {
assert!(10u.checked_div(&2) == Some(5));
assert!(5u.checked_div(&0) == None);
assert!(10u.checked_div(2) == Some(5));
assert!(5u.checked_div(0) == None);
}
}
))

View File

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

View File

@ -23,7 +23,7 @@ that do not need to record state.
#![experimental]
use core::prelude::*;
use core::num;
use core::num::{Float, Int};
use {Rng, Rand};
@ -127,7 +127,7 @@ impl<'a, T: Clone> WeightedChoice<'a, T> {
// weights so we can binary search. This *could* drop elements
// with weight == 0 as an optimisation.
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,
None => panic!("WeightedChoice::new called with a total weight \
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 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])
if test_x < x_tab[i + 1] {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -15,7 +15,7 @@
#![allow(deprecated)] // to_be32
use std::iter::range_step;
use std::num::Zero;
use std::num::Int;
use std::slice::bytes::{MutableByteVector, copy_memory};
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
/// 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();
if new_high_bits > Zero::zero() {
if new_high_bits > Int::zero() {
panic!("numeric overflow occurred.")
}
match bits.checked_add(&new_low_bits) {
match bits.checked_add(new_low_bits) {
Some(x) => return x,
None => panic!("numeric overflow occurred.")
}
@ -528,10 +528,10 @@ mod tests {
extern crate rand;
use super::{Digest, Sha256, FixedBuffer};
use std::num::Bounded;
use self::rand::isaac::IsaacRng;
use self::rand::Rng;
use serialize::hex::FromHex;
use std::num::Int;
// A normal addition - no overflow occurs
#[test]
@ -543,7 +543,7 @@ mod tests {
#[test]
#[should_fail]
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 {

View File

@ -15,7 +15,6 @@
use std::ops::Add;
use std::num::Zero;
use std::iter::AdditiveIterator;
use syntax::attr::{Deprecated, Experimental, Unstable, Stable, Frozen, Locked};
use syntax::ast::Public;
@ -55,6 +54,18 @@ impl Add<Counts, Counts> for 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 {
self.deprecated + self.experimental + self.unstable + self.stable +
self.frozen + self.locked + self.unmarked
@ -92,14 +103,14 @@ fn visible(item: &Item) -> bool {
fn count_stability(stab: Option<&Stability>) -> Counts {
match stab {
None => Counts { unmarked: 1, .. Zero::zero() },
None => Counts { unmarked: 1, .. Counts::zero() },
Some(ref stab) => match stab.level {
Deprecated => Counts { deprecated: 1, .. Zero::zero() },
Experimental => Counts { experimental: 1, .. Zero::zero() },
Unstable => Counts { unstable: 1, .. Zero::zero() },
Stable => Counts { stable: 1, .. Zero::zero() },
Frozen => Counts { frozen: 1, .. Zero::zero() },
Locked => Counts { locked: 1, .. Zero::zero() },
Deprecated => Counts { deprecated: 1, .. Counts::zero() },
Experimental => Counts { experimental: 1, .. Counts::zero() },
Unstable => Counts { unstable: 1, .. Counts::zero() },
Stable => Counts { stable: 1, .. Counts::zero() },
Frozen => Counts { frozen: 1, .. Counts::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) {
Some(v) => {
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() {
count = count +
i.impl_.items.iter().map(|ti| summarize_item(ti).0).sum();
count + i.impl_.items.iter()
.map(|ti| summarize_item(ti).0)
.fold(Counts::zero(), |acc, c| acc + c)
} else {
count
}
count
}).sum()
}
None => Zero::zero()
}).fold(Counts::zero(), |acc, c| acc + c)
},
None => {
Counts::zero()
},
}
}
@ -136,14 +151,14 @@ fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
let subcounts = subitems.iter().filter(|i| visible(*i))
.map(summarize_item)
.map(|s| s.val0())
.sum();
.fold(Counts::zero(), |acc, x| acc + x);
(item_counts + subcounts, None)
}
// `pub` automatically
EnumItem(Enum { variants: ref subitems, .. }) => {
let subcounts = subitems.iter().map(summarize_item)
.map(|s| s.val0())
.sum();
.fold(Counts::zero(), |acc, x| acc + x);
(item_counts + subcounts, None)
}
TraitItem(Trait {
@ -161,7 +176,7 @@ fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
.map(extract_item)
.map(summarize_item)
.map(|s| s.val0())
.sum();
.fold(Counts::zero(), |acc, x| acc + x);
(item_counts + subcounts, None)
}
ModuleItem(Module { ref items, .. }) => {
@ -182,7 +197,7 @@ fn summarize_item(item: &Item) -> (Counts, Option<ModuleSummary>) {
}))
}
// no stability information for the following items:
ViewItemItem(_) | PrimitiveItem(_) => (Zero::zero(), None),
ViewItemItem(_) | PrimitiveItem(_) => (Counts::zero(), None),
_ => (item_counts, None)
}
}
@ -192,7 +207,7 @@ pub fn build(krate: &Crate) -> ModuleSummary {
match krate.module {
None => ModuleSummary {
name: krate.name.clone(),
counts: Zero::zero(),
counts: Counts::zero(),
submodules: Vec::new(),
},
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::io::MemWriter;
use std::mem::{swap, transmute};
use std::num::{FPNaN, FPInfinite};
use std::num::{Float, FPNaN, FPInfinite, Int};
use std::str::ScalarValue;
use std::string;
use std::vec::Vec;
@ -609,7 +609,7 @@ impl<'a> PrettyEncoder<'a> {
/// This is safe to set during encoding.
pub fn set_indent<'a>(&mut self, indent: uint) {
// 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.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 {
res /= exp;
} else {
@ -2417,6 +2417,7 @@ mod tests {
TrailingCharacters, TrailingComma};
use std::{i64, u64, f32, f64, io};
use std::collections::TreeMap;
use std::num::Float;
use std::string;
#[deriving(Decodable, Eq, PartialEq, Show)]

View File

@ -18,7 +18,7 @@ use hash::{Hash, Hasher, RandomSipHasher};
use iter::{mod, Iterator, FromIterator, Extend};
use kinds::Sized;
use mem::{mod, replace};
use num;
use num::UnsignedInt;
use ops::{Deref, Index, IndexMut};
use option::{Some, None, Option};
use result::{Result, Ok, Err};
@ -549,7 +549,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
/// ```
#[inline]
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 {
hasher: hasher,
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);
/// ```
pub fn reserve(&mut self, new_minimum_capacity: uint) {
let cap = num::next_power_of_two(
max(INITIAL_CAPACITY, new_minimum_capacity));
let cap = max(INITIAL_CAPACITY, new_minimum_capacity).next_power_of_two();
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.
fn resize(&mut self, new_capacity: uint) {
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 old_size = old_table.size();

View File

@ -17,7 +17,7 @@ use iter::{Iterator, count};
use kinds::{Sized, marker};
use mem::{min_align_of, size_of};
use mem;
use num::{CheckedAdd, CheckedMul, is_power_of_two};
use num::{Int, UnsignedInt};
use ops::{Deref, DerefMut, Drop};
use option::{Some, None, Option};
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.
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)
}
@ -581,9 +581,9 @@ impl<K, V> RawTable<K, V> {
vals_size, min_align_of::< V >());
// One check for overflow that covers calculation and rounding of size.
let size_of_bucket = size_of::<u64>().checked_add(&size_of::<K>()).unwrap()
.checked_add(&size_of::<V>()).unwrap();
assert!(size >= capacity.checked_mul(&size_of_bucket)
let size_of_bucket = size_of::<u64>().checked_add(size_of::<K>()).unwrap()
.checked_add(size_of::<V>()).unwrap();
assert!(size >= capacity.checked_mul(size_of_bucket)
.expect("capacity overflow"),
"capacity overflow");

View File

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

View File

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

View File

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

View File

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

View File

@ -18,13 +18,13 @@
use option::Option;
#[cfg(test)] use cmp::PartialEq;
#[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::{Signed, abs, abs_sub, signum};
pub use core::num::{Unsigned, pow, Bounded};
pub use core::num::{Primitive, Int, Saturating};
pub use core::num::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv};
pub use core::num::{Primitive, Int, SignedInt, UnsignedInt};
pub use core::num::{cast, FromPrimitive, NumCast, ToPrimitive};
pub use core::num::{next_power_of_two, is_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.
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.
fn cbrt(self) -> Self;
/// 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)
}
// 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
#[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.sub(&two), cast(8i).unwrap());
assert_eq!(ten.mul(&two), cast(20i).unwrap());
@ -624,46 +641,46 @@ mod tests {
#[test]
fn test_checked_add() {
let five_less = 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(&2), Some(uint::MAX - 3));
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(&5), Some(uint::MAX));
assert_eq!(five_less.checked_add(&6), None);
assert_eq!(five_less.checked_add(&7), None);
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(2), Some(uint::MAX - 3));
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(5), Some(uint::MAX));
assert_eq!(five_less.checked_add(6), None);
assert_eq!(five_less.checked_add(7), None);
}
#[test]
fn test_checked_sub() {
assert_eq!(5u.checked_sub(&0), Some(5));
assert_eq!(5u.checked_sub(&1), Some(4));
assert_eq!(5u.checked_sub(&2), Some(3));
assert_eq!(5u.checked_sub(&3), Some(2));
assert_eq!(5u.checked_sub(&4), Some(1));
assert_eq!(5u.checked_sub(&5), Some(0));
assert_eq!(5u.checked_sub(&6), None);
assert_eq!(5u.checked_sub(&7), None);
assert_eq!(5u.checked_sub(0), Some(5));
assert_eq!(5u.checked_sub(1), Some(4));
assert_eq!(5u.checked_sub(2), Some(3));
assert_eq!(5u.checked_sub(3), Some(2));
assert_eq!(5u.checked_sub(4), Some(1));
assert_eq!(5u.checked_sub(5), Some(0));
assert_eq!(5u.checked_sub(6), None);
assert_eq!(5u.checked_sub(7), None);
}
#[test]
fn test_checked_mul() {
let third = uint::MAX / 3;
assert_eq!(third.checked_mul(&0), Some(0));
assert_eq!(third.checked_mul(&1), Some(third));
assert_eq!(third.checked_mul(&2), Some(third * 2));
assert_eq!(third.checked_mul(&3), Some(third * 3));
assert_eq!(third.checked_mul(&4), None);
assert_eq!(third.checked_mul(0), Some(0));
assert_eq!(third.checked_mul(1), Some(third));
assert_eq!(third.checked_mul(2), Some(third * 2));
assert_eq!(third.checked_mul(3), Some(third * 3));
assert_eq!(third.checked_mul(4), None);
}
macro_rules! test_next_power_of_two(
($test_name:ident, $T:ident) => (
fn $test_name() {
#![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;
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 }
}
}
@ -680,15 +697,15 @@ mod tests {
($test_name:ident, $T:ident) => (
fn $test_name() {
#![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;
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 }
}
assert!(checked_next_power_of_two::<$T>($T::MAX / 2).is_some());
assert_eq!(checked_next_power_of_two::<$T>($T::MAX - 1), None);
assert_eq!(checked_next_power_of_two::<$T>($T::MAX), None);
assert!(($T::MAX / 2).checked_next_power_of_two().is_some());
assert_eq!(($T::MAX - 1).checked_next_power_of_two(), None);
assert_eq!($T::MAX.checked_next_power_of_two(), None);
}
)
)
@ -760,10 +777,7 @@ mod tests {
assert_pow!((3i, 0 ) => 1);
assert_pow!((5i, 1 ) => 5);
assert_pow!((-4i, 2 ) => 16);
assert_pow!((0.5f64, 5 ) => 0.03125);
assert_pow!((8i, 3 ) => 512);
assert_pow!((8.0f64, 5 ) => 32768.0);
assert_pow!((8.5f64, 5 ) => 44370.53125);
assert_pow!((2u64, 50) => 1125899906842624);
}
}

View File

@ -17,8 +17,7 @@ use char::Char;
use from_str::from_str;
use iter::Iterator;
use num;
use num::{Int, Bounded};
use num::{Float, FPNaN, FPInfinite, ToPrimitive};
use num::{Int, Float, FPNaN, FPInfinite, ToPrimitive};
use option::{None, Option, Some};
use slice::{SlicePrelude, CloneSliceAllocPrelude};
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|) {
assert!(2 <= radix && radix <= 36);
let _0: T = num::zero();
let _0: T = Int::zero();
let neg = num < _0;
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].
let current_digit_signed = deccum % radix_gen;
let current_digit = if current_digit_signed < _0 {
-current_digit_signed
_0 - current_digit_signed
} else {
current_digit_signed
};
@ -195,8 +194,8 @@ pub fn float_to_str_bytes_common<T: Float>(
_ => ()
}
let _0: T = num::zero();
let _1: T = num::one();
let _0: T = Float::zero();
let _1: T = Float::one();
match num.classify() {
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 {}",
radix);
let _0: T = num::zero();
let _1: T = num::one();
let _0: T = Float::zero();
let _1: T = Float::one();
let radix_t: T = num::cast(radix as int).unwrap();
// Special values
@ -559,8 +558,8 @@ pub fn from_str_radix_float<T: Float>(src: &str, radix: uint) -> Option<T> {
};
match (is_positive, exp) {
(true, Some(exp)) => num::pow(base, exp),
(false, Some(exp)) => _1 / num::pow(base, exp),
(true, Some(exp)) => base.powi(exp as i32),
(false, Some(exp)) => _1 / base.powi(exp as i32),
(_, 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()
}
let _0: T = num::zero();
let _1: T = num::one();
let is_signed = _0 > Bounded::min_value();
let _0: T = Int::zero();
let _1: T = Int::one();
let is_signed = _0 > Int::min_value();
let (is_positive, src) = match src.slice_shift_char() {
(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,
None => return None,
};
result = match result.checked_mul(&radix) {
result = match result.checked_mul(radix) {
Some(result) => result,
None => return None,
};
result = match result.checked_add(&x) {
result = match result.checked_add(x) {
Some(result) => result,
None => return None,
};
@ -616,11 +615,11 @@ pub fn from_str_radix_int<T: Int>(src: &str, radix: uint) -> Option<T> {
Some(x) => x,
None => return None,
};
result = match result.checked_mul(&radix) {
result = match result.checked_mul(radix) {
Some(result) => result,
None => return None,
};
result = match result.checked_sub(&x) {
result = match result.checked_sub(x) {
Some(result) => result,
None => return None,
};

View File

@ -67,9 +67,7 @@
#[doc(no_inline)] pub use iter::{Iterator, DoubleEndedIterator};
#[doc(no_inline)] pub use iter::{RandomAccessIterator, CloneableIterator};
#[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::{Signed, Unsigned, Primitive, Int, Float};
#[doc(no_inline)] pub use num::{FloatMath, ToPrimitive, FromPrimitive};
#[doc(no_inline)] pub use num::{ToPrimitive, FromPrimitive};
#[doc(no_inline)] pub use boxed::Box;
#[doc(no_inline)] pub use option::{Option, Some, None};
#[doc(no_inline)] pub use path::{GenericPath, Path, PosixPath, WindowsPath};

View File

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

View File

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

View File

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

View File

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

View File

@ -15,8 +15,7 @@
use {fmt, i64};
use ops::{Add, Sub, Mul, Div, Neg};
use option::{Option, Some, None};
use num;
use num::{CheckedAdd, CheckedMul};
use num::Int;
use result::{Result, Ok, Err};
/// The number of nanoseconds in a microsecond.
@ -69,7 +68,7 @@ impl Duration {
/// Fails when the duration is out of bounds.
#[inline]
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)
}
@ -78,7 +77,7 @@ impl Duration {
/// Fails when the duration is out of bounds.
#[inline]
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)
}
@ -87,7 +86,7 @@ impl Duration {
/// Fails when the duration is out of bounds.
#[inline]
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)
}
@ -96,7 +95,7 @@ impl Duration {
/// Fails when the duration is out of bounds.
#[inline]
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)
}
@ -199,33 +198,64 @@ impl Duration {
/// Returns the total number of whole microseconds in the duration,
/// or `None` on overflow (exceeding 2^63 microseconds in either direction).
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;
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,
/// or `None` on overflow (exceeding 2^63 nanoseconds in either direction).
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();
secs_part.checked_add(&(nanos_part as i64))
secs_part.checked_add(nanos_part as i64)
}
}
impl num::Bounded for Duration {
#[inline] fn min_value() -> Duration { MIN }
#[inline] fn max_value() -> Duration { MAX }
}
/// Add two durations, returning `None` if overflow occured.
pub 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 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]
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 }
}
/// Returns `true` if the duration equals `Duration::zero()`.
#[inline]
fn is_zero(&self) -> bool {
pub fn is_zero(&self) -> bool {
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 {
fn sub(&self, rhs: &Duration) -> Duration {
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 {
fn mul(&self, rhs: &i32) -> Duration {
// 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 {
use super::{Duration, MIN, MAX};
use {i32, i64};
use num::{Zero, CheckedAdd, CheckedSub};
use option::{Some, None};
use to_string::ToString;
#[test]
fn test_duration() {
let d: Duration = Zero::zero();
assert_eq!(d, Zero::zero());
assert!(Duration::seconds(1) != Zero::zero());
assert!(Duration::seconds(1) != Duration::zero());
assert_eq!(Duration::seconds(1) + Duration::seconds(2), Duration::seconds(3));
assert_eq!(Duration::seconds(86399) + Duration::seconds(4),
Duration::days(1) + Duration::seconds(3));
@ -411,8 +408,7 @@ mod tests {
#[test]
fn test_duration_num_days() {
let d: Duration = Zero::zero();
assert_eq!(d.num_days(), 0);
assert_eq!(Duration::zero().num_days(), 0);
assert_eq!(Duration::days(1).num_days(), 1);
assert_eq!(Duration::days(-1).num_days(), -1);
assert_eq!(Duration::seconds(86399).num_days(), 0);
@ -425,8 +421,7 @@ mod tests {
#[test]
fn test_duration_num_seconds() {
let d: Duration = Zero::zero();
assert_eq!(d.num_seconds(), 0);
assert_eq!(Duration::zero().num_seconds(), 0);
assert_eq!(Duration::seconds(1).num_seconds(), 1);
assert_eq!(Duration::seconds(-1).num_seconds(), -1);
assert_eq!(Duration::milliseconds(999).num_seconds(), 0);
@ -437,8 +432,7 @@ mod tests {
#[test]
fn test_duration_num_milliseconds() {
let d: Duration = Zero::zero();
assert_eq!(d.num_milliseconds(), 0);
assert_eq!(Duration::zero().num_milliseconds(), 0);
assert_eq!(Duration::milliseconds(1).num_milliseconds(), 1);
assert_eq!(Duration::milliseconds(-1).num_milliseconds(), -1);
assert_eq!(Duration::microseconds(999).num_milliseconds(), 0);
@ -453,8 +447,7 @@ mod tests {
#[test]
fn test_duration_num_microseconds() {
let d: Duration = Zero::zero();
assert_eq!(d.num_microseconds(), Some(0));
assert_eq!(Duration::zero().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::nanoseconds(999).num_microseconds(), Some(0));
@ -478,8 +471,7 @@ mod tests {
#[test]
fn test_duration_num_nanoseconds() {
let d: Duration = Zero::zero();
assert_eq!(d.num_nanoseconds(), Some(0));
assert_eq!(Duration::zero().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(i64::MAX).num_nanoseconds(), Some(i64::MAX));
@ -512,10 +504,9 @@ mod tests {
#[test]
fn test_duration_mul() {
let d: Duration = Zero::zero();
assert_eq!(d * i32::MAX, d);
assert_eq!(d * i32::MIN, d);
assert_eq!(Duration::nanoseconds(1) * 0, Zero::zero());
assert_eq!(Duration::zero() * i32::MAX, Duration::zero());
assert_eq!(Duration::zero() * i32::MIN, Duration::zero());
assert_eq!(Duration::nanoseconds(1) * 0, Duration::zero());
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));
@ -530,9 +521,8 @@ mod tests {
#[test]
fn test_duration_div() {
let d: Duration = Zero::zero();
assert_eq!(d / i32::MAX, d);
assert_eq!(d / i32::MIN, d);
assert_eq!(Duration::zero() / i32::MAX, Duration::zero());
assert_eq!(Duration::zero() / i32::MIN, Duration::zero());
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]
fn test_duration_fmt() {
let d: Duration = Zero::zero();
assert_eq!(d.to_string(), "PT0S".to_string());
assert_eq!(Duration::zero().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::seconds(42).to_string(), "PT42S".to_string());

View File

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

View File

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

View File

@ -20,6 +20,7 @@ use ptr::P;
use std::cell::{Cell, RefCell};
use std::io::File;
use std::rc::Rc;
use std::num::Int;
use std::str;
use std::iter;
@ -63,7 +64,7 @@ impl ParseSess {
pub fn reserve_node_ids(&self, count: ast::NodeId) -> ast::NodeId {
let v = self.node_id.get();
match v.checked_add(&count) {
match v.checked_add(count) {
Some(next) => { self.node_id.set(next); }
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::mem::replace;
use std::mem;
use std::num::Float;
use std::rc::Rc;
use std::iter;

View File

@ -58,6 +58,7 @@ use std::io::fs::PathExtensions;
use std::io::stdio::StdWriter;
use std::io::{File, ChanReader, ChanWriter};
use std::io;
use std::num::{Float, FloatMath, Int};
use std::os;
use std::string::String;
use std::task::TaskBuilder;
@ -105,7 +106,6 @@ enum NamePadding { PadNone, PadOnLeft, PadOnRight }
impl TestDesc {
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 fill = column_count.saturating_sub(name.len());
let mut pad = " ".repeat(fill);

View File

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

View File

@ -31,7 +31,7 @@ extern crate libc;
use std::fmt::Show;
use std::fmt;
use std::io::BufReader;
use std::num;
use std::num::SignedInt;
use std::string::String;
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' => {
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;
m -= h * 60_i32;
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"),
};
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;
m -= h * 60_i32;
write!(fmt, "{}{}{:02d}:{:02d}", s, sign, h as int, m as int)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -15,6 +15,7 @@
use std::io;
use std::io::stdio::StdReader;
use std::io::BufferedReader;
use std::num::Int;
use std::os;
// 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
// except according to those terms.
use std::num::SignedInt;
fn main() {
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
// 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 {
*self + rhs //~ ERROR expected `Self`, found `T`
}
}
impl<T: Num> BrokenAdd for T {}
impl<T: Int> BrokenAdd for T {}
pub fn main() {
let foo: u8 = 0u8;

View File

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

View File

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

View File

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

View File

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

View File

@ -12,11 +12,11 @@
use std::cmp::{PartialEq, PartialOrd};
use std::num::NumCast;
pub trait NumExt: Num + NumCast + PartialEq + PartialOrd {}
pub trait NumExt: NumCast + PartialEq + PartialOrd {}
pub trait FloatExt: NumExt {}
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<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() }
pub fn main() {}

View File

@ -11,6 +11,7 @@
// Extending Num and using inherited static methods
use std::cmp::PartialOrd;
use std::num::NumCast;
pub trait Num {
@ -18,7 +19,7 @@ pub trait Num {
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 {
n.gt(&NumCast::from(1i).unwrap())

View File

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

View File

@ -12,6 +12,7 @@
// A more complex example of numeric extensions
use std::cmp::{PartialEq, PartialOrd};
use std::num::NumCast;
pub trait TypeExt {}
@ -32,7 +33,7 @@ impl TypeExt for f32 {}
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 u16 {}

View File

@ -11,11 +11,11 @@
use std::cmp::{PartialEq, PartialOrd};
use std::num::NumCast;
pub trait NumExt: PartialEq + PartialOrd + Num + NumCast {}
pub trait NumExt: PartialEq + PartialOrd + NumCast {}
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())
}

View File

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

View File

@ -10,7 +10,7 @@
// 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;
@ -29,7 +29,7 @@ impl FuzzyEq<f32> for f32 {
}
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 {
num::abs(*self - *other) < *epsilon
(*self - *other).abs() < *epsilon
}
}

View File

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