Rename Bitwise::population_count to Bitwise::count_ones and add Bitwise::count_zeros

These are inspired by the [functions in the Julia standard library](http://docs.julialang.org/en/release-0.2/stdlib/base/#Base.count_ones).
This commit is contained in:
Brendan Zabarauskas 2014-02-17 10:12:10 +11:00
parent 0ba6d4885f
commit 79f52cf9ba
10 changed files with 91 additions and 41 deletions

View File

@ -129,7 +129,7 @@ impl<E:CLike> Iterator<E> for Items<E> {
}
fn size_hint(&self) -> (uint, Option<uint>) {
let exact = self.bits.population_count();
let exact = self.bits.count_ones();
(exact, Some(exact))
}
}

View File

@ -432,7 +432,7 @@ fn generic_type_of(cx: &CrateContext, r: &Repr, name: Option<&str>, sizing: bool
4 => Type::array(&Type::i32(), align_units),
8 if machine::llalign_of_min(cx, Type::i64()) == 8 =>
Type::array(&Type::i64(), align_units),
a if a.population_count() == 1 => Type::array(&Type::vector(&Type::i32(), a / 4),
a if a.count_ones() == 1 => Type::array(&Type::vector(&Type::i32(), a / 4),
align_units),
_ => fail!("unsupported enum alignment: {:?}", align)
};

View File

@ -25,15 +25,17 @@ use unstable::intrinsics;
int_module!(i16, 16)
impl Bitwise for i16 {
/// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
/// Returns the number of ones in the binary representation of the number.
#[inline]
fn population_count(&self) -> i16 { unsafe { intrinsics::ctpop16(*self) } }
fn count_ones(&self) -> i16 { unsafe { intrinsics::ctpop16(*self) } }
/// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
/// Returns the number of leading zeros in the in the binary representation
/// of the number.
#[inline]
fn leading_zeros(&self) -> i16 { unsafe { intrinsics::ctlz16(*self) } }
/// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
/// Returns the number of trailing zeros in the in the binary representation
/// of the number.
#[inline]
fn trailing_zeros(&self) -> i16 { unsafe { intrinsics::cttz16(*self) } }
}

View File

@ -25,15 +25,17 @@ use unstable::intrinsics;
int_module!(i32, 32)
impl Bitwise for i32 {
/// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
/// Returns the number of ones in the binary representation of the number.
#[inline]
fn population_count(&self) -> i32 { unsafe { intrinsics::ctpop32(*self) } }
fn count_ones(&self) -> i32 { unsafe { intrinsics::ctpop32(*self) } }
/// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
/// Returns the number of leading zeros in the in the binary representation
/// of the number.
#[inline]
fn leading_zeros(&self) -> i32 { unsafe { intrinsics::ctlz32(*self) } }
/// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
/// Returns the number of trailing zeros in the in the binary representation
/// of the number.
#[inline]
fn trailing_zeros(&self) -> i32 { unsafe { intrinsics::cttz32(*self) } }
}

View File

@ -27,15 +27,16 @@ use unstable::intrinsics;
int_module!(i64, 64)
impl Bitwise for i64 {
/// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
/// Returns the number of ones in the binary representation of the number.
#[inline]
fn population_count(&self) -> i64 { unsafe { intrinsics::ctpop64(*self) } }
fn count_ones(&self) -> i64 { unsafe { intrinsics::ctpop64(*self) } }
/// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
/// Returns the number of leading zeros in the in the binary representation
/// of the number.
#[inline]
fn leading_zeros(&self) -> i64 { unsafe { intrinsics::ctlz64(*self) } }
/// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
/// Counts the number of trailing zeros.
#[inline]
fn trailing_zeros(&self) -> i64 { unsafe { intrinsics::cttz64(*self) } }
}

View File

@ -25,15 +25,17 @@ use unstable::intrinsics;
int_module!(i8, 8)
impl Bitwise for i8 {
/// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
/// Returns the number of ones in the binary representation of the number.
#[inline]
fn population_count(&self) -> i8 { unsafe { intrinsics::ctpop8(*self) } }
fn count_ones(&self) -> i8 { unsafe { intrinsics::ctpop8(*self) } }
/// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
/// Returns the number of leading zeros in the in the binary representation
/// of the number.
#[inline]
fn leading_zeros(&self) -> i8 { unsafe { intrinsics::ctlz8(*self) } }
/// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
/// Returns the number of trailing zeros in the in the binary representation
/// of the number.
#[inline]
fn trailing_zeros(&self) -> i8 { unsafe { intrinsics::cttz8(*self) } }
}

View File

@ -27,30 +27,34 @@ use unstable::intrinsics;
#[cfg(target_word_size = "32")]
impl Bitwise for int {
/// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
/// Returns the number of ones in the binary representation of the number.
#[inline]
fn population_count(&self) -> int { (*self as i32).population_count() as int }
fn count_ones(&self) -> int { (*self as i32).count_ones() as int }
/// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
/// Returns the number of leading zeros in the in the binary representation
/// of the number.
#[inline]
fn leading_zeros(&self) -> int { (*self as i32).leading_zeros() as int }
/// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
/// Returns the number of trailing zeros in the in the binary representation
/// of the number.
#[inline]
fn trailing_zeros(&self) -> int { (*self as i32).trailing_zeros() as int }
}
#[cfg(target_word_size = "64")]
impl Bitwise for int {
/// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
/// Returns the number of ones in the binary representation of the number.
#[inline]
fn population_count(&self) -> int { (*self as i64).population_count() as int }
fn count_ones(&self) -> int { (*self as i64).count_ones() as int }
/// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
/// Returns the number of leading zeros in the in the binary representation
/// of the number.
#[inline]
fn leading_zeros(&self) -> int { (*self as i64).leading_zeros() as int }
/// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
/// Returns the number of trailing zeros in the in the binary representation
/// of the number.
#[inline]
fn trailing_zeros(&self) -> int { (*self as i64).trailing_zeros() as int }
}

View File

@ -614,8 +614,17 @@ mod tests {
}
#[test]
fn test_bitcount() {
assert_eq!((0b010101 as $T).population_count(), 3);
fn test_count_ones() {
assert_eq!((0b0101100 as $T).count_ones(), 3);
assert_eq!((0b0100001 as $T).count_ones(), 2);
assert_eq!((0b1111001 as $T).count_ones(), 5);
}
#[test]
fn test_count_zeros() {
assert_eq!((0b0101100 as $T).count_zeros(), BITS as $T - 3);
assert_eq!((0b0100001 as $T).count_zeros(), BITS as $T - 2);
assert_eq!((0b1111001 as $T).count_zeros(), BITS as $T - 5);
}
#[test]

View File

@ -375,18 +375,35 @@ pub trait Bitwise: Bounded
+ BitXor<Self,Self>
+ Shl<Self,Self>
+ Shr<Self,Self> {
/// Returns the number of bits set in the number.
/// Returns the number of ones in the binary representation of the number.
///
/// # Example
///
/// ```rust
/// use std::num::Bitwise;
///
/// let n = 0b0101000u16;
/// assert_eq!(n.population_count(), 2);
/// let n = 0b01001100u8;
/// assert_eq!(n.count_ones(), 3);
/// ```
fn population_count(&self) -> Self;
/// Returns the number of leading zeros in the number.
fn count_ones(&self) -> Self;
/// Returns the number of zeros in the binary representation of the number.
///
/// # Example
///
/// ```rust
/// use std::num::Bitwise;
///
/// let n = 0b01001100u8;
/// assert_eq!(n.count_zeros(), 5);
/// ```
#[inline]
fn count_zeros(&self) -> Self {
(!*self).count_ones()
}
/// Returns the number of leading zeros in the in the binary representation
/// of the number.
///
/// # Example
///
@ -397,7 +414,9 @@ pub trait Bitwise: Bounded
/// assert_eq!(n.leading_zeros(), 10);
/// ```
fn leading_zeros(&self) -> Self;
/// Returns the number of trailing zeros in the number.
/// Returns the number of trailing zeros in the in the binary representation
/// of the number.
///
/// # Example
///

View File

@ -266,19 +266,21 @@ impl ToStrRadix for $T {
impl Primitive for $T {}
impl Bitwise for $T {
/// Counts the number of bits set. Wraps LLVM's `ctpop` intrinsic.
/// Returns the number of ones in the binary representation of the number.
#[inline]
fn population_count(&self) -> $T {
(*self as $T_SIGNED).population_count() as $T
fn count_ones(&self) -> $T {
(*self as $T_SIGNED).count_ones() as $T
}
/// Counts the number of leading zeros. Wraps LLVM's `ctlz` intrinsic.
/// Returns the number of leading zeros in the in the binary representation
/// of the number.
#[inline]
fn leading_zeros(&self) -> $T {
(*self as $T_SIGNED).leading_zeros() as $T
}
/// Counts the number of trailing zeros. Wraps LLVM's `cttz` intrinsic.
/// Returns the number of trailing zeros in the in the binary representation
/// of the number.
#[inline]
fn trailing_zeros(&self) -> $T {
(*self as $T_SIGNED).trailing_zeros() as $T
@ -375,8 +377,17 @@ mod tests {
}
#[test]
fn test_bitcount() {
assert_eq!((0b010101 as $T).population_count(), 3);
fn test_count_ones() {
assert_eq!((0b0101100 as $T).count_ones(), 3);
assert_eq!((0b0100001 as $T).count_ones(), 2);
assert_eq!((0b1111001 as $T).count_ones(), 5);
}
#[test]
fn test_count_zeros() {
assert_eq!((0b0101100 as $T).count_zeros(), BITS as $T - 3);
assert_eq!((0b0100001 as $T).count_zeros(), BITS as $T - 2);
assert_eq!((0b1111001 as $T).count_zeros(), BITS as $T - 5);
}
#[test]