diff options
| author | bors <bors@rust-lang.org> | 2013-04-27 13:09:35 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-04-27 13:09:35 -0700 |
| commit | aa38867e4e7da648a85985251f542bee12a64095 (patch) | |
| tree | a63425d6739dc5cad3d1a09c9e63404a40545ff3 /src/libstd | |
| parent | 5de74f3e754628fa98c0cdf0b95b39f39db50e19 (diff) | |
| parent | 9cdf402c80536c7e138d04433ee3f0a0855f08ce (diff) | |
| download | rust-aa38867e4e7da648a85985251f542bee12a64095.tar.gz rust-aa38867e4e7da648a85985251f542bee12a64095.zip | |
auto merge of #6071 : bjz/rust/numeric-traits, r=graydon
As part of the numeric trait reform (see issue #4819), I have added the following traits to `core::num` and implemented them for Rust's primitive numeric types:
~~~rust
pub trait Bitwise: Not<Self>
+ BitAnd<Self,Self>
+ BitOr<Self,Self>
+ BitXor<Self,Self>
+ Shl<Self,Self>
+ Shr<Self,Self> {}
pub trait BitCount {
fn population_count(&self) -> Self;
fn leading_zeros(&self) -> Self;
fn trailing_zeros(&self) -> Self;
}
pub trait Bounded {
fn min_value() -> Self;
fn max_value() -> Self;
}
pub trait Primitive: Num
+ NumCast
+ Bounded
+ Neg<Self>
+ Add<Self,Self>
+ Sub<Self,Self>
+ Mul<Self,Self>
+ Quot<Self,Self>
+ Rem<Self,Self> {
fn bits() -> uint;
fn bytes() -> uint;
}
pub trait Int: Integer
+ Primitive
+ Bitwise
+ BitCount {}
pub trait Float: Real
+ Signed
+ Primitive {
fn NaN() -> Self;
fn infinity() -> Self;
fn neg_infinity() -> Self;
fn neg_zero() -> Self;
fn is_NaN(&self) -> bool;
fn is_infinite(&self) -> bool;
fn is_finite(&self) -> bool;
fn mantissa_digits() -> uint;
fn digits() -> uint;
fn epsilon() -> Self;
fn min_exp() -> int;
fn max_exp() -> int;
fn min_10_exp() -> int;
fn max_10_exp() -> int;
fn mul_add(&self, a: Self, b: Self) -> Self;
fn next_after(&self, other: Self) -> Self;
}
~~~
Note: I'm not sure my implementation for `BitCount::trailing_zeros` and `BitCount::leading_zeros` is correct for uints. I also need some assistance creating appropriate unit tests for them.
More work needs to be done in implementing specialized primitive floating-point and integer methods, but I'm beginning to reach the limits of my knowledge. Please leave your suggestions/critiques/ideas on #4819 if you have them – I'd very much appreciate hearing them.
I have also added an `Orderable` trait:
~~~rust
pub trait Orderable: Ord {
fn min(&self, other: &Self) -> Self;
fn max(&self, other: &Self) -> Self;
fn clamp(&self, mn: &Self, mx: &Self) -> Self;
}
~~~
This is a temporary trait until we have default methods. We don't want to encumber all implementors of Ord by requiring them to implement these functions, but at the same time we want to be able to take advantage of the speed of the specific numeric functions (like the `fmin` and `fmax` intrinsics).
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/num/bigint.rs | 36 | ||||
| -rw-r--r-- | src/libstd/num/complex.rs | 5 | ||||
| -rw-r--r-- | src/libstd/num/rational.rs | 5 |
3 files changed, 27 insertions, 19 deletions
diff --git a/src/libstd/num/bigint.rs b/src/libstd/num/bigint.rs index 5f0fd76640a..214bb0be0ed 100644 --- a/src/libstd/num/bigint.rs +++ b/src/libstd/num/bigint.rs @@ -148,10 +148,12 @@ impl Shr<uint, BigUint> for BigUint { impl Zero for BigUint { fn zero() -> BigUint { BigUint::new(~[]) } + + fn is_zero(&self) -> bool { self.data.is_empty() } } impl One for BigUint { - pub fn one() -> BigUint { BigUint::new(~[1]) } + fn one() -> BigUint { BigUint::new(~[1]) } } impl Unsigned for BigUint {} @@ -310,7 +312,7 @@ impl ToStrRadix for BigUint { result += [m0.to_uint() as BigDigit]; m = d; } - if m.is_not_zero() { + if !m.is_zero() { result += [m.to_uint() as BigDigit]; } return result; @@ -470,10 +472,6 @@ pub impl BigUint { self.div_mod(other) } - fn is_zero(&self) -> bool { self.data.is_empty() } - - fn is_not_zero(&self) -> bool { !self.data.is_empty() } - fn to_uint(&self) -> uint { match self.data.len() { 0 => 0, @@ -684,6 +682,8 @@ impl Zero for BigInt { pub fn zero() -> BigInt { BigInt::from_biguint(Zero, Zero::zero()) } + + fn is_zero(&self) -> bool { self.sign == Zero } } impl One for BigInt { @@ -909,8 +909,6 @@ pub impl BigInt { fn is_zero(&self) -> bool { self.sign == Zero } - fn is_not_zero(&self) -> bool { self.sign != Zero } - fn to_uint(&self) -> uint { match self.sign { Plus => self.data.to_uint(), @@ -1212,10 +1210,10 @@ mod biguint_tests { let b = BigUint::from_slice(bVec); let c = BigUint::from_slice(cVec); - if a.is_not_zero() { + if !a.is_zero() { assert!(c.quot_rem(&a) == (b, Zero::zero())); } - if b.is_not_zero() { + if !b.is_zero() { assert!(c.quot_rem(&b) == (a, Zero::zero())); } } @@ -1227,7 +1225,7 @@ mod biguint_tests { let c = BigUint::from_slice(cVec); let d = BigUint::from_slice(dVec); - if b.is_not_zero() { assert!(a.quot_rem(&b) == (c, d)); } + if !b.is_zero() { assert!(a.quot_rem(&b) == (c, d)); } } } @@ -1577,7 +1575,7 @@ mod bigint_tests { fn test_div_mod() { fn check_sub(a: &BigInt, b: &BigInt, ans_d: &BigInt, ans_m: &BigInt) { let (d, m) = a.div_mod(b); - if m.is_not_zero() { + if !m.is_zero() { assert!(m.sign == b.sign); } assert!(m.abs() <= b.abs()); @@ -1606,8 +1604,8 @@ mod bigint_tests { let b = BigInt::from_slice(Plus, bVec); let c = BigInt::from_slice(Plus, cVec); - if a.is_not_zero() { check(&c, &a, &b, &Zero::zero()); } - if b.is_not_zero() { check(&c, &b, &a, &Zero::zero()); } + if !a.is_zero() { check(&c, &a, &b, &Zero::zero()); } + if !b.is_zero() { check(&c, &b, &a, &Zero::zero()); } } for quot_rem_quadruples.each |elm| { @@ -1617,7 +1615,7 @@ mod bigint_tests { let c = BigInt::from_slice(Plus, cVec); let d = BigInt::from_slice(Plus, dVec); - if b.is_not_zero() { + if !b.is_zero() { check(&a, &b, &c, &d); } } @@ -1628,7 +1626,7 @@ mod bigint_tests { fn test_quot_rem() { fn check_sub(a: &BigInt, b: &BigInt, ans_q: &BigInt, ans_r: &BigInt) { let (q, r) = a.quot_rem(b); - if r.is_not_zero() { + if !r.is_zero() { assert!(r.sign == a.sign); } assert!(r.abs() <= b.abs()); @@ -1649,8 +1647,8 @@ mod bigint_tests { let b = BigInt::from_slice(Plus, bVec); let c = BigInt::from_slice(Plus, cVec); - if a.is_not_zero() { check(&c, &a, &b, &Zero::zero()); } - if b.is_not_zero() { check(&c, &b, &a, &Zero::zero()); } + if !a.is_zero() { check(&c, &a, &b, &Zero::zero()); } + if !b.is_zero() { check(&c, &b, &a, &Zero::zero()); } } for quot_rem_quadruples.each |elm| { @@ -1660,7 +1658,7 @@ mod bigint_tests { let c = BigInt::from_slice(Plus, cVec); let d = BigInt::from_slice(Plus, dVec); - if b.is_not_zero() { + if !b.is_zero() { check(&a, &b, &c, &d); } } diff --git a/src/libstd/num/complex.rs b/src/libstd/num/complex.rs index ef7fa397d7f..fc17cbc678e 100644 --- a/src/libstd/num/complex.rs +++ b/src/libstd/num/complex.rs @@ -125,6 +125,11 @@ impl<T: Copy + Num> Zero for Cmplx<T> { fn zero() -> Cmplx<T> { Cmplx::new(Zero::zero(), Zero::zero()) } + + #[inline] + fn is_zero(&self) -> bool { + *self == Zero::zero() + } } impl<T: Copy + Num> One for Cmplx<T> { diff --git a/src/libstd/num/rational.rs b/src/libstd/num/rational.rs index 8af1d99fa47..93b63593a5e 100644 --- a/src/libstd/num/rational.rs +++ b/src/libstd/num/rational.rs @@ -191,6 +191,11 @@ impl<T: Copy + Num + Ord> fn zero() -> Ratio<T> { Ratio::new_raw(Zero::zero(), One::one()) } + + #[inline] + fn is_zero(&self) -> bool { + *self == Zero::zero() + } } impl<T: Copy + Num + Ord> |
