Add is_zero method to Zero

This commit is contained in:
Brendan Zabarauskas 2013-04-25 15:30:56 +10:00
parent ac69ee418b
commit ad0b337036
9 changed files with 67 additions and 56 deletions

View File

@ -12,7 +12,7 @@
use from_str;
use libc::c_int;
use num::strconv;
use num::{Zero, One, strconv};
use prelude::*;
pub use cmath::c_float_targ_consts::*;
@ -154,12 +154,6 @@ pub fn gt(x: f32, y: f32) -> bool { return x > y; }
// FIXME (#1999): replace the predicates below with llvm intrinsics or
// calls to the libmath macros in the rust runtime for performance.
/// Returns true if `x` is a zero number (positive or negative zero)
#[inline(always)]
pub fn is_zero(x: f32) -> bool {
return x == 0.0f32 || x == -0.0f32;
}
/// Returns true if `x`is an infinite number
#[inline(always)]
pub fn is_infinite(x: f32) -> bool {
@ -245,12 +239,16 @@ impl Ord for f32 {
fn gt(&self, other: &f32) -> bool { (*self) > (*other) }
}
impl num::Zero for f32 {
impl Zero for f32 {
#[inline(always)]
fn zero() -> f32 { 0.0 }
/// Returns true if the number is equal to either `0.0` or `-0.0`
#[inline(always)]
fn is_zero(&self) -> bool { *self == 0.0 || *self == -0.0 }
}
impl num::One for f32 {
impl One for f32 {
#[inline(always)]
fn one() -> f32 { 1.0 }
}

View File

@ -12,7 +12,7 @@
use from_str;
use libc::c_int;
use num::strconv;
use num::{Zero, One, strconv};
use prelude::*;
pub use cmath::c_double_targ_consts::*;
@ -174,12 +174,6 @@ pub fn ge(x: f64, y: f64) -> bool { return x >= y; }
#[inline(always)]
pub fn gt(x: f64, y: f64) -> bool { return x > y; }
/// Returns true if `x` is a zero number (positive or negative zero)
#[inline(always)]
pub fn is_zero(x: f64) -> bool {
return x == 0.0f64 || x == -0.0f64;
}
/// Returns true if `x`is an infinite number
#[inline(always)]
pub fn is_infinite(x: f64) -> bool {
@ -266,12 +260,16 @@ impl Ord for f64 {
fn gt(&self, other: &f64) -> bool { (*self) > (*other) }
}
impl num::Zero for f64 {
impl Zero for f64 {
#[inline(always)]
fn zero() -> f64 { 0.0 }
/// Returns true if the number is equal to either `0.0` or `-0.0`
#[inline(always)]
fn is_zero(&self) -> bool { *self == 0.0 || *self == -0.0 }
}
impl num::One for f64 {
impl One for f64 {
#[inline(always)]
fn one() -> f64 { 1.0 }
}

View File

@ -22,7 +22,7 @@
use from_str;
use libc::c_int;
use num::strconv;
use num::{Zero, One, strconv};
use prelude::*;
pub use f64::{add, sub, mul, quot, rem, lt, le, eq, ne, ge, gt};
@ -337,8 +337,6 @@ pub fn pow_with_uint(base: uint, pow: uint) -> float {
return total;
}
#[inline(always)]
pub fn is_zero(x: float) -> bool { f64::is_zero(x as f64) }
#[inline(always)]
pub fn is_infinite(x: float) -> bool { f64::is_infinite(x as f64) }
#[inline(always)]
@ -393,12 +391,16 @@ impl Ord for float {
fn gt(&self, other: &float) -> bool { (*self) > (*other) }
}
impl num::Zero for float {
impl Zero for float {
#[inline(always)]
fn zero() -> float { 0.0 }
/// Returns true if the number is equal to either `0.0` or `-0.0`
#[inline(always)]
fn is_zero(&self) -> bool { *self == 0.0 || *self == -0.0 }
}
impl num::One for float {
impl One for float {
#[inline(always)]
fn one() -> float { 1.0 }
}
@ -867,11 +869,11 @@ mod tests {
}
// note: -0 == 0, hence these slightly more complex tests
match from_str(~"-0") {
Some(v) if is_zero(v) => assert!(v.is_negative()),
Some(v) if v.is_zero() => assert!(v.is_negative()),
_ => fail!()
}
match from_str(~"0") {
Some(v) if is_zero(v) => assert!(v.is_positive()),
Some(v) if v.is_zero() => assert!(v.is_positive()),
_ => fail!()
}
@ -914,11 +916,11 @@ mod tests {
}
// note: -0 == 0, hence these slightly more complex tests
match from_str_hex(~"-0") {
Some(v) if is_zero(v) => assert!(v.is_negative()),
Some(v) if v.is_zero() => assert!(v.is_negative()),
_ => fail!()
}
match from_str_hex(~"0") {
Some(v) if is_zero(v) => assert!(v.is_positive()),
Some(v) if v.is_zero() => assert!(v.is_positive()),
_ => fail!()
}
assert_eq!(from_str_hex(~"e"), Some(14.));

View File

@ -12,7 +12,7 @@ use T = self::inst::T;
use from_str::FromStr;
use num::{ToStrRadix, FromStrRadix};
use num::strconv;
use num::{Zero, One, strconv};
use prelude::*;
pub use cmp::{min, max};
@ -152,12 +152,15 @@ impl Eq for T {
fn ne(&self, other: &T) -> bool { return (*self) != (*other); }
}
impl num::Zero for T {
impl Zero for T {
#[inline(always)]
fn zero() -> T { 0 }
#[inline(always)]
fn is_zero(&self) -> bool { *self == 0 }
}
impl num::One for T {
impl One for T {
#[inline(always)]
fn one() -> T { 1 }
}

View File

@ -37,13 +37,12 @@ pub trait IntConvertible {
}
pub trait Zero {
// FIXME (#5527): These should be associated constants
fn zero() -> Self;
fn zero() -> Self; // FIXME (#5527): This should be an associated constant
fn is_zero(&self) -> bool;
}
pub trait One {
// FIXME (#5527): These should be associated constants
fn one() -> Self;
fn one() -> Self; // FIXME (#5527): This should be an associated constant
}
pub trait Signed: Num

View File

@ -13,7 +13,7 @@ use T_SIGNED = self::inst::T_SIGNED;
use from_str::FromStr;
use num::{ToStrRadix, FromStrRadix};
use num::strconv;
use num::{Zero, One, strconv};
use prelude::*;
pub use cmp::{min, max};
@ -118,12 +118,15 @@ impl Eq for T {
fn ne(&self, other: &T) -> bool { return (*self) != (*other); }
}
impl num::Zero for T {
impl Zero for T {
#[inline(always)]
fn zero() -> T { 0 }
#[inline(always)]
fn is_zero(&self) -> bool { *self == 0 }
}
impl num::One for T {
impl One for T {
#[inline(always)]
fn one() -> T { 1 }
}

View File

@ -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);
}
}

View File

@ -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> {

View File

@ -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>