Trait bitwise::Word [] [src]

pub trait Word: Sized + Copy + Not<Output=Self> + BitOr<Output=Self> + BitXor<Output=Self> + Add<Output=Self> + Sub<Output=Self> + Mul<Output=Self> + Div<Output=Self> + Shr<u32, Output=Self> + Shl<u32, Output=Self> + BitAnd<Output=Self> + Eq + PartialOrd {
    type Signed: Word;
    type Unsigned: Word;
    fn size() -> usize;
    fn to_unsigned(self) -> Self::Unsigned;
    fn to_signed(self) -> Self::Signed;
    fn zero() -> Self;
    fn one() -> Self;
    fn two() -> Self;
    fn count_zeros(self) -> usize;
    fn count_ones(self) -> usize;
    fn leading_zeros(self) -> usize;
    fn trailing_zeros(self) -> usize;
    fn shift_logical_left(self, n: u32) -> Self;
    fn shift_logical_right(self, n: u32) -> Self;
    fn shift_arithmetic_left(self, n: u32) -> Self;
    fn shift_arithmetic_right(self, n: u32) -> Self;
    fn rotate_left(self, n: u32) -> Self;
    fn rotate_right(self, n: u32) -> Self;
    fn swap_bytes(self) -> Self;
    fn from_be(x: Self) -> Self;
    fn from_le(x: Self) -> Self;
    fn to_be(self) -> Self;
    fn to_le(self) -> Self;
    fn pow(self, exp: u32) -> Self;
    fn reverse_bit_groups(self, subword_bits: u32, group_subwords: u32) -> Self;
    fn set_bit_to(self, bit: u32, value: bool) -> Self;
    fn clear_bits_geq(self, bit: u32) -> Self;
    fn is_aligned(self, alignment: u32) -> bool;
    fn align_up(self, alignment: u32) -> Self;
    fn align_down(self, alignment: u32) -> Self;
    fn outer_perfect_shuffle(self) -> Self;
    fn outer_perfect_unshuffle(self) -> Self;
    fn scatter_bits(self, mask_: Self) -> Self;
    fn gather_bits(self, mask_: Self) -> Self;
    fn gather_bit_range(self, first: u32, length: u32) -> Self;
    fn morton_encode_2d(x: [Self; 2]) -> Self;
    fn morton_encode_3d(x: [Self; 3]) -> Self;
    fn morton_decode_2d(self) -> [Self; 2];
    fn morton_decode_3d(self) -> [Self; 3];

    fn bit_size() -> usize { ... }
    fn leading_ones(self) -> usize { ... }
    fn trailing_ones(self) -> usize { ... }
    fn and_not(self, y: Self) -> Self { ... }
    fn parity(self) -> usize { ... }
    fn next_abs_greater_even(self) -> Self { ... }
    fn prev_abs_smaller_even(self) -> Self { ... }
    fn next_abs_greater_equal_even(self) -> Self { ... }
    fn prev_abs_smaller_equal_even(self) -> Self { ... }
    fn next_abs_greater_odd(self) -> Self { ... }
    fn prev_abs_smaller_odd(self) -> Self { ... }
    fn next_abs_greater_equal_odd(self) -> Self { ... }
    fn prev_abs_smaller_equal_odd(self) -> Self { ... }
    fn clear(self) -> Self { ... }
    fn clear_least_significant_one(self) -> Self { ... }
    fn set_least_significant_zero(self) -> Self { ... }
    fn isolate_least_significant_one(self) -> Self { ... }
    fn isolate_least_significant_zero(self) -> Self { ... }
    fn clear_trailing_ones(self) -> Self { ... }
    fn set_trailing_zeros(self) -> Self { ... }
    fn mask_trailing_zeros(self) -> Self { ... }
    fn mask_trailing_ones(self) -> Self { ... }
    fn mask_trailing_zeros_and_least_significant_one(self) -> Self { ... }
    fn mask_trailing_ones_and_least_significant_zero(self) -> Self { ... }
    fn first_bit_set(self) -> usize { ... }
    fn first_bit_clear(self) -> usize { ... }
    fn reverse_bits(self) -> Self { ... }
    fn reverse_bit_pairs(self) -> Self { ... }
    fn reverse_bit_nibbles(self) -> Self { ... }
    fn reverse_byte_groups(self, bytes_per_block: u32, blocks_per_group: u32) -> Self { ... }
    fn reverse_bytes(self) -> Self { ... }
    fn set_bit(self, bit: u32) -> Self { ... }
    fn clear_bit(self, bit: u32) -> Self { ... }
    fn flip_bit(self, bit: u32) -> Self { ... }
    fn test_bit(self, bit: u32) -> bool { ... }
    fn clear_bits_leq(self, bit: u32) -> Self { ... }
    fn set_bits_geq(self, bit: u32) -> Self { ... }
    fn set_bits_leq(self, bit: u32) -> Self { ... }
    fn flip_bits_geq(self, bit: u32) -> Self { ... }
    fn flip_bits_leq(self, bit: u32) -> Self { ... }
    fn is_pow2(self) -> bool { ... }
    fn ceil_pow2(self) -> Self { ... }
    fn floor_pow2(self) -> Self { ... }
    fn average_floor(x: Self, y: Self) -> Self { ... }
    fn average_ceil(x: Self, y: Self) -> Self { ... }
    fn inner_perfect_shuffle(self) -> Self { ... }
    fn inner_perfect_unshuffle(self) -> Self { ... }
}

Bitwise manipulation algorithms for Words.

Note: this trat is not supposed to be implemented by library users. The distinction between functionality required and inherited has been arbitrarily placed at the boundary between "what is easier to implement within the trait" and "what is easier to implement with a macro" for the primitive integer types.

Associated Types

type Signed: Word

Signed Word Type of the same size as Self.

type Unsigned: Word

Unsigned Word Type of the same size as Self.

Required Methods

fn size() -> usize

Size of the word in bytes.

fn to_unsigned(self) -> Self::Unsigned

Transmutes the integer into an unsigned integer of the same size (bitwise loss-less).

Examples

use bitwise::Word;

assert_eq!((8i32).to_unsigned().to_signed(), 8i32);
assert_eq!((-1i32).to_unsigned().to_signed(), -1i32);

fn to_signed(self) -> Self::Signed

Transmutes an integer into a signed integer of the same size (bitwise loss-less).

Examples

use bitwise::Word;

assert_eq!((8i32).to_unsigned().to_signed(), 8i32);
assert_eq!((-1i32).to_unsigned().to_signed(), -1i32);

fn zero() -> Self

Returns a word with no bits set (an integer of value zero).

fn one() -> Self

Returns a word with the least significant bit set (an integer of value one).

fn two() -> Self

Returns a word with the second least significant bit set (an integer of value two).

fn count_zeros(self) -> usize

Returns the number of zeros in the binary representation of self.

Examples

use bitwise::Word;

let n = 0b0100_1100u8;

assert_eq!(n.count_zeros(), 5);

fn count_ones(self) -> usize

Returns the number of ones in the binary representation of self.

Keywords:

Population count, popcount, hamming weight, sideways sum.

Intrinsics:

  • ABM: popcnt.
  • SSE4.2: popcnt.
  • NEON: vcnt.
  • PowerPC: popcntb.
  • gcc/llvm builtin: __builtin_popcount(x).

Examples

use bitwise::Word;

let n = 0b0100_1100u8;

assert_eq!(n.count_ones(), 3);

fn leading_zeros(self) -> usize

Returns the number of leading zeros in the binary representation of self.

Keywords:

Count leading zeros.

Intrinsics:

  • ABM: lzcnt.
  • BMI 1.0: lzcnt.
  • ARMv5: clz.
  • PowerPC: cntlzd.
  • gcc/llvm builtin: x == 0 ? mem::size_of(x) * 8 : __builtin_clz(x).

Examples

use bitwise::Word;

let n = 0b0010_1000u16;

assert_eq!(n.leading_zeros(), 10);

fn trailing_zeros(self) -> usize

Returns the number of trailing zeros in the binary representation of self.

Keywords:

Count trailing zeros.

Intrinsics:

  • BMI 1.0: tzcnt.
  • gcc/llvm builtin: x == 0 ? mem::size_of(x) * 8 : __builtin_ctz(x).

Examples

use bitwise::Word;

let n = 0b0010_1000u16;

assert_eq!(n.trailing_zeros(), 3);

fn shift_logical_left(self, n: u32) -> Self

Shift the bits to the left by a specified amount, n.

Panics

If n > bit_size().

Examples

use bitwise::Word;

let a = 0b0000_1010u8;
let b = 0b0000_1001u8;

assert_eq!(a.shift_logical_left(4), 0b1010_0000u8);
assert_eq!(b.shift_logical_left(4), 0b1001_0000u8);
b.shift_logical_right((<u8 as Word>::bit_size() - 1) as u32);

fn shift_logical_right(self, n: u32) -> Self

Shift the bits to the right by a specified amount, n, with the high-order bits of the result cleared.

Panics

If n > bit_size().

Examples

use bitwise::Word;

let a = 0b0111_0000u8;
let b = 0b1001_0000u8;

assert_eq!(a.shift_logical_right(4), 0b0000_0111u8);
assert_eq!(b.shift_logical_right(4), 0b0000_1001u8);
b.shift_logical_right((<u8 as Word>::bit_size() - 1) as u32);

fn shift_arithmetic_left(self, n: u32) -> Self

Shift the bits to the left by a specified amount, n (same as shift_logical_left, provided for symmetry).

Panics

If n > bit_size().

Examples

use bitwise::Word;

let a = 0b0000_1010u8;
let b = 0b0000_1001u8;

assert_eq!(a.shift_arithmetic_left(4), 0b1010_0000u8);
assert_eq!(b.shift_arithmetic_left(4), 0b1001_0000u8);
b.shift_arithmetic_left((<u8 as Word>::bit_size() - 1) as u32);

fn shift_arithmetic_right(self, n: u32) -> Self

Shift the bits to the right by a specified amount, n, setting the high-order bits of the result to the value of the most significant bit of self.

Panics

If n > bit_size().

Examples

use bitwise::Word;

let a = 0b0111_0000u8;
let b = 0b1001_0000u8;

assert_eq!(a.shift_arithmetic_right(4), 0b0000_0111u8);
assert_eq!(b.shift_arithmetic_right(4), 0b1111_1001u8);
b.shift_arithmetic_right((<u8 as Word>::bit_size() - 1) as u32);

fn rotate_left(self, n: u32) -> Self

Shifts the bits to the left by a specified amount, n, wrapping the truncated bits to the end of the resulting integer.

Panics

If n > bit_size().

Examples

use bitwise::Word;

let n = 0x0123456789ABCDEFu64;
let m = 0x3456789ABCDEF012u64;

assert_eq!(n.rotate_left(12), m);
n.rotate_left(<u64 as Word>::bit_size() as u32);

fn rotate_right(self, n: u32) -> Self

Shifts the bits to the right by a specified amount, n, wrapping the truncated bits to the beginning of the resulting integer.

Panics

If n > bit_size().

Intrinsics:

  • BMI 2.0: rorx.

Examples

use bitwise::Word;

let n = 0x0123456789ABCDEFu64;
let m = 0xDEF0123456789ABCu64;

assert_eq!(n.rotate_right(12), m);
n.rotate_right(<u64 as Word>::bit_size() as u32);

fn swap_bytes(self) -> Self

Reverses the byte order of the integer.

Examples

use bitwise::Word;

let n = 0x0123456789ABCDEFu64;
let m = 0xEFCDAB8967452301u64;

assert_eq!(n.swap_bytes(), m);

fn from_be(x: Self) -> Self

Convert an integer from big endian to the target's endianness.

On big endian this is a no-op. On little endian the bytes are swapped.

Examples

use bitwise::Word;

let n = 0x0123456789ABCDEFu64;

if cfg!(target_endian = "big") {
    assert_eq!(u64::from_be(n), n)
} else {
    assert_eq!(u64::from_be(n), n.swap_bytes())
}

fn from_le(x: Self) -> Self

Convert an integer from little endian to the target's endianness.

On little endian this is a no-op. On big endian the bytes are swapped.

Examples

use bitwise::Word;

let n = 0x0123456789ABCDEFu64;

if cfg!(target_endian = "little") {
    assert_eq!(u64::from_le(n), n)
} else {
    assert_eq!(u64::from_le(n), n.swap_bytes())
}

fn to_be(self) -> Self

Convert self to big endian from the target's endianness.

On big endian this is a no-op. On little endian the bytes are swapped.

Examples

use bitwise::Word;

let n = 0x0123456789ABCDEFu64;

if cfg!(target_endian = "big") {
    assert_eq!(n.to_be(), n)
} else {
    assert_eq!(n.to_be(), n.swap_bytes())
}

fn to_le(self) -> Self

Convert self to little endian from the target's endianness.

On little endian this is a no-op. On big endian the bytes are swapped.

Examples

use bitwise::Word;

let n = 0x0123456789ABCDEFu64;

if cfg!(target_endian = "little") {
    assert_eq!(n.to_le(), n)
} else {
    assert_eq!(n.to_le(), n.swap_bytes())
}

fn pow(self, exp: u32) -> Self

Raises self to the power of exp, using exponentiation by squaring.

Panics

If the result does not fit in Self.

Examples

use bitwise::Word;

assert_eq!(2i32.pow(4), 16);

fn reverse_bit_groups(self, subword_bits: u32, group_subwords: u32) -> Self

Reverses the bits of self by subword_bits and group_subwords:

  • subword_bits: the bits will be reversed in grous: 1 (single bits), 2 (pair-wise), 4 (nibbles),
  • group_subwords: the subword size is 8 bits: mem::size_of::<u8>(), the bits will be reversed within each subword.

Examples

use bitwise::Word;

let n = 0b0101_1101_1010_0101_u16;

// Single bits:
let s0 = 0b1010_0101_1011_1010u16;
assert_eq!(n.reverse_bit_groups(1, 1), s0);

// Bit pairs:
let s1 = 0b0101_1010_0111_0101u16;
assert_eq!(n.reverse_bit_groups(2, 1), s1);

// Bit nibbles:
let s2 = 0b0101_1010_1101_0101u16;
assert_eq!(n.reverse_bit_groups(4, 1), s2);

// Single bits: group_subwords = 2
let s3 = 0b1011_1010_1010_0101u16;
assert_eq!(n.reverse_bit_groups(1, 2), s3);

// Bit pairs: group_subwords = 2
let s4 = 0b0111_0101_0101_1010u16;
assert_eq!(n.reverse_bit_groups(2, 2), s4);

// Bit nibbles: group_subwords = 2
let s5 = 0b1101_0101_0101_1010u16;
assert_eq!(n.reverse_bit_groups(4, 2), s5);

fn set_bit_to(self, bit: u32, value: bool) -> Self

Sets the bit of self to value.

Panics

If bit >= bit_size().

Examples

use bitwise::Word;

let n  = 0b1001_0011u8;
assert_eq!(n.set_bit_to(6, true), 0b1101_0011u8);
assert_eq!(n.set_bit_to(0, false), 0b1001_0010u8);
assert_eq!(n.set_bit_to(3, true), 0b1001_1011u8);

fn clear_bits_geq(self, bit: u32) -> Self

Clears all bits of self at position >= bit.

Panics

If bit >= bit_size().

Intrinsics:

  • BMI 2.0: bzhi.

Examples

use bitwise::Word;

let n = 0b1111_0010u8;
let s = 0b0001_0010u8;
assert_eq!(n.clear_bits_geq(5), s);

fn is_aligned(self, alignment: u32) -> bool

Is self aligned to alignment bytes.

Returns true if self == 0 or self is a multiple of alignment.

Examples

use bitwise::Word;

assert!(2.is_aligned(1));
assert!(2.is_aligned(2));
assert!(!2.is_aligned(4));
assert!(!2.is_aligned(8));

assert!(3.is_aligned(1));
assert!(!3.is_aligned(2));
assert!(!3.is_aligned(4));
assert!(!3.is_aligned(8));

assert!(4.is_aligned(1));
assert!(4.is_aligned(2));
assert!(4.is_aligned(4));
assert!(!4.is_aligned(8));

fn align_up(self, alignment: u32) -> Self

Align self up to alignment.

Returns n, where n is the least number >= self and is_aligned(n, alignment).

Panics

alignment must be a power of two. which is asserted in debug

Examples

use bitwise::Word;

assert_eq!(2.align_up(1), 2);
assert_eq!(2.align_up(2), 2);
assert_eq!(2.align_up(4), 4);
assert_eq!(2.align_up(8), 8);

assert_eq!(3.align_up(1), 3);
assert_eq!(3.align_up(2), 4);
assert_eq!(3.align_up(4), 4);
assert_eq!(3.align_up(8), 8);

assert_eq!(4.align_up(1), 4);
assert_eq!(4.align_up(2), 4);
assert_eq!(4.align_up(4), 4);
assert_eq!(4.align_up(8), 8);

fn align_down(self, alignment: u32) -> Self

Align self down to alignment.

Returns n, where n is the greatest number <= self and is_aligned(n, alignment).

Panics

alignment must be a power of two.

Examples

use bitwise::Word;

assert_eq!(2.align_down(1), 2);
assert_eq!(2.align_down(2), 2);
assert_eq!(2.align_down(4), 0);
assert_eq!(2.align_down(8), 0);

assert_eq!(3.align_down(1), 3);
assert_eq!(3.align_down(2), 2);
assert_eq!(3.align_down(4), 0);
assert_eq!(3.align_down(8), 0);

assert_eq!(4.align_down(1), 4);
assert_eq!(4.align_down(2), 4);
assert_eq!(4.align_down(4), 4);
assert_eq!(4.align_down(8), 0);

fn outer_perfect_shuffle(self) -> Self

Outer Perfect Shuffle of self.

See also: Hacker's Delight: shuffling bits.

Examples

use bitwise::Word;

let n = 0b0110_0101_1101_1011_1111_1001_0110_0011u32;
//        abcd efgh ijkl mnop ABCD EFGH IJKL MNOP,
let s = 0b0111_1101_0110_0011_1011_0110_1000_1111u32;
//        aAbB cCdD eEfF gGhH iIjJ kKlL mMnN oOpP,

assert_eq!(n.outer_perfect_shuffle(), s);

fn outer_perfect_unshuffle(self) -> Self

Outer Perfect Unshuffle of self.

See also: Hacker's Delight: shuffling bits.

Examples

use bitwise::Word;

let n = 0b0111_1101_0110_0011_1011_0110_1000_1111u32;
//        aAbB cCdD eEfF gGhH iIjJ kKlL mMnN oOpP,
let s = 0b0110_0101_1101_1011_1111_1001_0110_0011u32;
//        abcd efgh ijkl mnop ABCD EFGH IJKL MNOP,

assert_eq!(n.outer_perfect_unshuffle(), s);

fn scatter_bits(self, mask_: Self) -> Self

Scatter the low-ordr bits of self into the positions of the result selected by the mask.

The contiguous low-order bits of self are to be copied to the bits of the destination selected by the mask. in the destination. The bits nothing was copied to are cleared.

Keywords:

Parallel bits deposit, scatter.

Scatter.

Intrinsics:

  • BMI 2.0: pdep.

Examples

use bitwise::Word;

let n  = 0b1011_1110_1001_0011u16;

let m0 = 0b0110_0011_1000_0101u16;
let s0 = 0b0000_0010_0000_0101u16;

let m1 = 0b1110_1011_1110_1111u16;
let s1 = 0b1110_1001_0010_0011u16;

assert_eq!(n.scatter_bits(m0), s0);
assert_eq!(n.scatter_bits(m1), s1);

// The following examples are from Wikipedia:
let w = 0b1101_0101u8;
//        abcd efgh

assert_eq!(w.scatter_bits(0b1111_0000u8), 0b0101_0000u8);
//                                   efgh ____       efgh ____
assert_eq!(w.scatter_bits(0b1111_1100u8), 0b0101_0100u8);
//                                   cdef gh__       cdef gh__
assert_eq!(w.scatter_bits(0b0101_0101u8), 0b0001_0001u8);
//                                   _e_f _g_h       _e_f _g_h
assert_eq!(w.scatter_bits(0b1101_1101u8), 0b0100_1001u8);
//                                   cd_e fg_h       cd_e fg_h
assert_eq!(w.scatter_bits(0b0001_1111u8), 0b0001_0101u8);
//                                   ___d efgh       ___d efgh

fn gather_bits(self, mask_: Self) -> Self

Gather the bits of self selected by the mask into the low-order bits of the result.

The bits from self selected by the mask are copied into the contiguous low order bits of the destination. High-order bits of the destination are cleared.

Keywords:

Gather bits, parallel bits extract.

Intrinsics:

  • BMI 2.0: pext.

Examples

use bitwise::Word;

let n  = 0b1011_1110_1001_0011u16;

let m0 = 0b0110_0011_1000_0101u16;
let s0 = 0b0000_0000_0011_0101u16;

let m1 = 0b1110_1011_1110_1111u16;
let s1 = 0b0001_0111_0100_0011u16;

assert_eq!(n.gather_bits(m0), s0);
assert_eq!(n.gather_bits(m1), s1);

// The following examples are from Wikipedia:
let w = 0b1101_0101u8;
//        abcd efgh

assert_eq!(w.gather_bits(0b1111_0000u8), 0b0000_1101u8);
//                                   abcd ____       ____ abcd
assert_eq!(w.gather_bits(0b1111_1100u8), 0b0011_0101u8);
//                                   abcd ef__       __ab cdef
assert_eq!(w.gather_bits(0b0101_0101u8), 0b0000_1111u8);
//                                   _b_d _f_h       ____ bdfh
assert_eq!(w.gather_bits(0b1101_1101u8), 0b0011_1011u8);
//                                   ab_d ef_h       __ab defh
assert_eq!(w.gather_bits(0b0001_1111u8), 0b0001_0101u8);
//                                   ___d efgh       ___d efgh

fn gather_bit_range(self, first: u32, length: u32) -> Self

Gathers the contiguous low-order bits of self in range [first, first+length] into the low-order bits of the result.

The range increases from low-order to high-order bits, is zero-indexed, and closed.

Keywords:

Extract bit range.

Panics

If first + length >= bit_size().

Intrinsics:

  • BMI 2.0: bextr.

Examples

use bitwise::Word;

let n  = 0b1011_1110_1001_0011u16;
//         abcd efgh ijkl mnop

assert_eq!(n.gather_bit_range(2, 6), 0b0000_0000_0010_0100u16);
//                 [2, 8] => [n, i]    ____ ____ __ij klmn

fn morton_encode_2d(x: [Self; 2]) -> Self

Encode coordinates x into an interleaved Morton index for a Z-Curve.

Layout: xy|xy|xy|xy|... .

Example

use bitwise::Word;

let idx : u64 = 30;
assert_eq!(idx, 0b01_11_10);

let x = idx.morton_decode_2d();

assert!(Word::morton_encode_2d(x) == idx);

assert_eq!(x[0], 0b_110);
assert_eq!(x[1], 0b_011);

fn morton_encode_3d(x: [Self; 3]) -> Self

Encode coordinates x into an interleaved Morton index for a Z-Curve.

Layout: xyz|xyz|xyz|xyz|... .

Example

use bitwise::Word;

let idx : u64 = 30;
assert_eq!(idx, 0b011_110);

let x = idx.morton_decode_3d();

assert!(Word::morton_encode_3d(x) == idx);

assert_eq!(x[0], 0b10);
assert_eq!(x[1], 0b11);
assert_eq!(x[2], 0b01);

fn morton_decode_2d(self) -> [Self; 2]

Decode interleaved Morton index for a Z-Curve into coordinates.

See morton_encode_2d.

fn morton_decode_3d(self) -> [Self; 3]

Decode interleaved Morton index for a Z-Curve into coordinates.

See morton_encode_3d.

Provided Methods

fn bit_size() -> usize

Size of the word in bits.

fn leading_ones(self) -> usize

Returns the number of leading ones in the binary representation of self.

Keywords:

Count leading ones.

Intrinsics:

  • ARMv8: cls.

Examples

use bitwise::Word;

let n = 0b1111_1111_1100_1000u16;

assert_eq!(n.leading_ones(), 10);

fn trailing_ones(self) -> usize

Returns the number of trailing ones in the binary representation of self.

Keywords:

Count trailing ones.

Examples

use bitwise::Word;

let n = 0b0010_0111u16;

assert_eq!(n.trailing_ones(), 3);

fn and_not(self, y: Self) -> Self

Logical and not of self with y.

Intrinsics:

  • BMI 2.0: andn.

Examples

use bitwise::Word;

let n = 0b0100_1101u8;
let m = 0b1110_1010u8;

assert_eq!(n.and_not(m), 0b1010_0010u8);

fn parity(self) -> usize

Returns the number of 1 bits in self mod 2, that is, returns 1 if the number of 1 bits in self is odd, and zero otherwise

Intrinsics:

-gcc/llvm: __builtin_parity(x).

Examples

use bitwise::Word;

let n0 = 0b0000;  // 0 -> even => parity = 0
let n1 = 0b0001;  // 1 -> odd  => partiy = 1
let n2 = 0b0010;  // 1 -> odd  => parity = 1
let n3 = 0b0011;  // 2 -> even => parity = 0

assert_eq!(n0.parity(), 0);
assert_eq!(n1.parity(), 1);
assert_eq!(n2.parity(), 1);
assert_eq!(n3.parity(), 0);

fn next_abs_greater_even(self) -> Self

Returns the next "absolute" even even number x such that |self| < |x| and sign(self) == sign(x).

That is, for positive numbers the next even is greater than self and for negative numbers it is smaller than self (see examples).

Panics

If self overflows.

Examples

use bitwise::Word;

assert_eq!(-3.next_abs_greater_even(), -4);
assert_eq!(-2.next_abs_greater_even(), -4);
assert_eq!(-1.next_abs_greater_even(), -2);
assert_eq!(0.next_abs_greater_even(), 2);
assert_eq!(1.next_abs_greater_even(), 2);
assert_eq!(2.next_abs_greater_even(), 4);
assert_eq!(3.next_abs_greater_even(), 4);

fn prev_abs_smaller_even(self) -> Self

Returns the previous "absolute" even number x such that |x| < |self| and sign(x) == sign(self).

That is, for positive numbers the previous even is smaller than self and for negative numbers it is greater than self (see examples).

Panics

If self overflows. Note that zero is handled as -0 and that the previous even of zero for Unsigned numbers overflows (because its negative).

Examples

use bitwise::Word;

assert_eq!(-3.prev_abs_smaller_even(), -2);
assert_eq!(-2.prev_abs_smaller_even(), 0);
assert_eq!(-1.prev_abs_smaller_even(), 0);
// assert_eq!(0u32.prev_abs_smaller_even(), 2); // overflows
assert_eq!(0.prev_abs_smaller_even(), -2);
assert_eq!(1.prev_abs_smaller_even(), 0);
assert_eq!(2.prev_abs_smaller_even(), 0);
assert_eq!(3.prev_abs_smaller_even(), 2);
assert_eq!(4.prev_abs_smaller_even(), 2);

fn next_abs_greater_equal_even(self) -> Self

Returns the next "absolute" even number x such that |self| <= |x| and sign(self) == sign(x).

That is, for positive numbers the next even is greater or equal than self and for negative numbers it is smaller or equal than self (see examples).

Panics

If self overflows.

Examples

use bitwise::Word;

assert_eq!(-3.next_abs_greater_equal_even(), -4);
assert_eq!(-2.next_abs_greater_equal_even(), -2);
assert_eq!(-1.next_abs_greater_equal_even(), -2);
assert_eq!(0.next_abs_greater_equal_even(), 0);
assert_eq!(1.next_abs_greater_equal_even(), 2);
assert_eq!(2.next_abs_greater_equal_even(), 2);
assert_eq!(3.next_abs_greater_equal_even(), 4);

fn prev_abs_smaller_equal_even(self) -> Self

Returns the previous "absolute" even number x such that |x| <= |self| and sign(x) == sign(self).

That is, for positive numbers the previous even is smaller or equalt than self and for negative numbers it is greater or equalt than self (see examples).

Panics

If self overflows.

Examples

use bitwise::Word;

assert_eq!(-3.prev_abs_smaller_equal_even(), -2);
assert_eq!(-2.prev_abs_smaller_equal_even(), -2);
assert_eq!(-1.prev_abs_smaller_equal_even(), 0);
assert_eq!(0u32.prev_abs_smaller_equal_even(), 0);
assert_eq!(0.prev_abs_smaller_equal_even(), 0);
assert_eq!(1.prev_abs_smaller_equal_even(), 0);
assert_eq!(2.prev_abs_smaller_equal_even(), 2);
assert_eq!(3.prev_abs_smaller_equal_even(), 2);
assert_eq!(4.prev_abs_smaller_equal_even(), 4);

fn next_abs_greater_odd(self) -> Self

Returns the next "absolute" odd number x such that |self| < |x| and sign(self) == sign(x).

That is, for positive numbers the next odd is greater than self and for negative numbers it is smaller than self (see examples).

Panics

If self overflows.

Examples

use bitwise::Word;

assert_eq!(-3.next_abs_greater_odd(), -5);
assert_eq!(-2.next_abs_greater_odd(), -3);
assert_eq!(-1.next_abs_greater_odd(), -3);
assert_eq!(0.next_abs_greater_odd(), 1);
assert_eq!(1.next_abs_greater_odd(), 3);
assert_eq!(2.next_abs_greater_odd(), 3);
assert_eq!(3.next_abs_greater_odd(), 5);

fn prev_abs_smaller_odd(self) -> Self

Returns the previous "absolute" odd number x such that |x| < |self| and sign(x) == sign(self).

That is, for positive numbers the previous odd is smaller than self and for negative numbers it is greater than self (see examples).

Panics

If self overflows. Note that zero is handled as -0 and that the previous odd of zero and one for Unsigned numbers overflows (because its negative).

Examples

use bitwise::Word;

assert_eq!(-4.prev_abs_smaller_odd(), -3);
assert_eq!(-3.prev_abs_smaller_odd(), -1);
assert_eq!(-2.prev_abs_smaller_odd(), -1);
assert_eq!(-1.prev_abs_smaller_odd(), 1);
// assert_eq!(0u32.prev_abs_smaller_odd(), 2); // overflows
//assert_eq!(1u32.prev_abs_smaller_odd(), 2); // overflows
assert_eq!(0.prev_abs_smaller_odd(), -1);
assert_eq!(1.prev_abs_smaller_odd(), -1);
assert_eq!(2.prev_abs_smaller_odd(), 1);
assert_eq!(3.prev_abs_smaller_odd(), 1);
assert_eq!(4.prev_abs_smaller_odd(), 3);

fn next_abs_greater_equal_odd(self) -> Self

Returns the next "absolute" odd odd number x such that |self| <= |x| and sign(self) == sign(x).

That is, for positive numbers the next odd is greater or equal than self and for negative numbers it is smaller or equal than self (see examples).

Panics

If self overflows.

Examples

use bitwise::Word;

assert_eq!(-3.next_abs_greater_equal_odd(), -3);
assert_eq!(-2.next_abs_greater_equal_odd(), -3);
assert_eq!(-1.next_abs_greater_equal_odd(), -1);
assert_eq!(0.next_abs_greater_equal_odd(), 1);
assert_eq!(1.next_abs_greater_equal_odd(), 1);
assert_eq!(2.next_abs_greater_equal_odd(), 3);
assert_eq!(3.next_abs_greater_equal_odd(), 3);

fn prev_abs_smaller_equal_odd(self) -> Self

Returns the previous "absolute" odd number x such that |x| <= |self| and sign(x) == sign(self).

That is, for positive numbers the previous odd is smaller or equalt than self and for negative numbers it is greater or equalt than self (see examples).

Panics

If self overflows. Note that the previous of zero is negative and will overflow for Unsigned Integers.

Examples

use bitwise::Word;

assert_eq!(-3.prev_abs_smaller_equal_odd(), -3);
assert_eq!(-2.prev_abs_smaller_equal_odd(), -1);
assert_eq!(-1.prev_abs_smaller_equal_odd(), -1);
// assert_eq!(0u32.prev_abs_smaller_equal_odd(), -1); // overflows
assert_eq!(0.prev_abs_smaller_equal_odd(), -1);
assert_eq!(1.prev_abs_smaller_equal_odd(), 1);
assert_eq!(2.prev_abs_smaller_equal_odd(), 1);
assert_eq!(3.prev_abs_smaller_equal_odd(), 3);
assert_eq!(4.prev_abs_smaller_equal_odd(), 3);

fn clear(self) -> Self

Clear all bits of self.

Equivalent to zero().

Example

use bitwise::Word;

assert_eq!(0b1010_1010u8.clear(), 0u8);

fn clear_least_significant_one(self) -> Self

Clear least significant 1 bit of self; returns 0 if self is 0.

Intrinsics:

  • BMI 1.0: blsr.

Examples

use bitwise::Word;

let n = 0b0110;
let s = 0b0100;

assert_eq!(n.clear_least_significant_one(), s);

fn set_least_significant_zero(self) -> Self

Set least significant 0 bit of self.

Intrinsics:

  • TBM: blcs.

Examples

use bitwise::Word;

let n = 0b0101;
let s = 0b0111;

assert_eq!(n.set_least_significant_zero(), s);

fn isolate_least_significant_one(self) -> Self

Isolate least significant 1 bit of self and returns it; returns 0 if self is 0.

Intrinsics:

  • BMI 1.0: blsi.
  • TBM: blsic, not.

Examples

use bitwise::Word;

let n = 0b0110;
let s = 0b0010;

assert_eq!(n.isolate_least_significant_one(), s);

fn isolate_least_significant_zero(self) -> Self

Set the least significant zero bit of self to 1 and all of the rest to 0.

Intrinsics:

  • TBM: blcic (or: blci, not).

Examples

use bitwise::Word;

let n = 0b0101;
let s = 0b0010;

assert_eq!(n.isolate_least_significant_zero(), s);

fn clear_trailing_ones(self) -> Self

Clear the trailing 1's in self.

Intrinsics:

  • TBM: blcfill.

Examples

use bitwise::Word;

let n = 0b0110_1111;
let s = 0b0110_0000;

assert_eq!(n.clear_trailing_ones(), s);

fn set_trailing_zeros(self) -> Self

Set all of the trailing 0's in self.

Intrinsics:

  • TBM: blsfill.

Examples

use bitwise::Word;

let n = 0b0110_0000u8;
let s = 0b0111_1111u8;

assert_eq!(n.set_trailing_zeros(), s);

fn mask_trailing_zeros(self) -> Self

Returns a mask with all of the trailing 0's of self set.

Intrinsics:

  • TBM: tzmsk.

Examples

use bitwise::Word;

let n = 0b0110_0000u8;
let s = 0b0001_1111u8;

assert_eq!(n.mask_trailing_zeros(), s);

fn mask_trailing_ones(self) -> Self

Returns a mask with all of the trailing 1's of self set.

Intrinsics:

  • TBM: tlmskc, not.

Examples

use bitwise::Word;

let n = 0b0101_1111u8;
let s = 0b0001_1111u8;

assert_eq!(n.mask_trailing_ones(), s);

fn mask_trailing_zeros_and_least_significant_one(self) -> Self

Returns a mask with all of the trailing 0's of self set and the least significant 1 bit set.

Intrinsics:

  • TBM: blsmsk.

Examples

use bitwise::Word;

let n = 0b0101_0000u8;
let s = 0b0001_1111u8;

assert_eq!(n.mask_trailing_zeros_and_least_significant_one(), s);

fn mask_trailing_ones_and_least_significant_zero(self) -> Self

Returns a mask with all of the trailing 1's of self set and the least significant 0 bit set.

Intrinsics:

  • TBM: blcmsk.

Examples

use bitwise::Word;

let n = 0b0101_1111u8;
let s = 0b0011_1111u8;

assert_eq!(n.mask_trailing_ones_and_least_significant_zero(), s);

fn first_bit_set(self) -> usize

Returns the position of the first bit that is set (starting from the low-order bits).

Returns bit_size() if no bit is found.

Keywords:

Find first bit set, find first one, bit scan forward.

Examples:

use bitwise::Word;

assert_eq!(0b0101_1111u8.first_bit_set(), 0);
assert_eq!(0b0101_1100u8.first_bit_set(), 2);
assert_eq!(0b1000_0000u8.first_bit_set(), 7);
assert_eq!(0b0000_0000u8.first_bit_set(), 8);

fn first_bit_clear(self) -> usize

Returns the position of the first bit that is set (starting from the low-order bits).

Returns bit_size() if no bit is found.

Keywords:

Find first zero.

Examples:

use bitwise::Word;

assert_eq!(0b1111_1111u8.first_bit_clear(), 8);
assert_eq!(0b0111_1111u8.first_bit_clear(), 7);
assert_eq!(0b1010_0011u8.first_bit_clear(), 2);
assert_eq!(0b1000_1010u8.first_bit_clear(), 0);

fn reverse_bits(self) -> Self

Reverses the bits of self.

Intrinsics:

  • ARM: rbit (u32 ARMv7, u64 ARMv8).

Examples

use bitwise::Word;

let n = 0b1011_0010u8;
let s = 0b0100_1101u8;
assert_eq!(n.reverse_bits(), s);

let n1 = 0b1011_0010_1010_1001u16;
let s1 = 0b1001_0101_0100_1101u16;
assert_eq!(n1.reverse_bits(), s1);

fn reverse_bit_pairs(self) -> Self

Reverses the pairs of bits of self.

Examples

use bitwise::Word;

let n = 0b1011_0010u8;
let s = 0b1000_1110u8;
assert_eq!(n.reverse_bit_pairs(), s);

let n1 = 0b1011_0010_1010_1001u16;
let s1 = 0b0110_1010_1000_1110u16;
assert_eq!(n1.reverse_bit_pairs(), s1);

fn reverse_bit_nibbles(self) -> Self

Reverses the nibbles of self.

Examples

use bitwise::Word;

let n = 0b1011_0010u8;
let s = 0b0010_1011u8;
assert_eq!(n.reverse_bit_nibbles(), s);

let n1 = 0b1011_0010_1010_1001u16;
let s1 = 0b1001_1010_0010_1011u16;
assert_eq!(n1.reverse_bit_nibbles(), s1);

fn reverse_byte_groups(self, bytes_per_block: u32, blocks_per_group: u32) -> Self

Reverses the bytes of self.

  • bytes_per_block: number of bytes per block to reverse.
  • blocks_per_group: number of blocks per group of blocks.

Examples

use bitwise::Word;

let n = 0b0101_1101_1010_0101_u16;

// Single bytes:
let s0 = 0b1010_0101_0101_1101u16;
assert_eq!(n.reverse_byte_groups(1, 1), s0);

// Single bytes: group_subwords = 2
let s3 = 0b0101_1101_1010_0101u16;
assert_eq!(n.reverse_byte_groups(1, 2), s3);

fn reverse_bytes(self) -> Self

Reverses the bytes of self (equivalent to swap bytes).

Intrinsics:

  • x86_64: bswap.
  • ARM: rev (v5), revsh (v5), rev16 (v6,v8), rev32(v8).
  • gcc/llvm: __builtin_bswap16/32/64.

Examples

use bitwise::Word;

let n = 0b1011_0010u8;
let s = 0b1011_0010u8;
assert_eq!(n.reverse_bytes(), s);
assert_eq!(n.swap_bytes(), s);

let n1 = 0b1011_0010_1010_1001u16;
let s1 = 0b1010_1001_1011_0010u16;
assert_eq!(n1.reverse_bytes(), s1);
assert_eq!(n1.swap_bytes(), s1);

fn set_bit(self, bit: u32) -> Self

Sets the bit of self.

Panics

If bit >= bit_size().

Examples

use bitwise::Word;

let n  = 0b1011_0010u8;
let s0 = 0b1111_0010u8;
let s1 = 0b1011_0011u8;
let s2 = 0b1011_1010u8;
assert_eq!(n.set_bit(6), s0);
assert_eq!(n.set_bit(0), s1);
assert_eq!(n.set_bit(3), s2);

fn clear_bit(self, bit: u32) -> Self

Clears the bit of self.

Panics

If bit >= bit_size().

Examples

use bitwise::Word;

let n = 0b1011_0010u8;
let s0 = 0b0011_0010u8;
let s1 = 0b1011_0000u8;
let s2 = 0b1001_0010u8;
assert_eq!(n.clear_bit(7), s0);
assert_eq!(n.clear_bit(1), s1);
assert_eq!(n.clear_bit(5), s2);

fn flip_bit(self, bit: u32) -> Self

Flip the bit of self.

Panics

If bit >= bit_size().

Examples

use bitwise::Word;

let n = 0b1011_0010u8;
let s0 = 0b0011_0010u8;
let s1 = 0b1111_0010u8;
let s2 = 0b1001_0010u8;
assert_eq!(n.flip_bit(7), s0);
assert_eq!(n.flip_bit(6), s1);
assert_eq!(n.flip_bit(5), s2);

fn test_bit(self, bit: u32) -> bool

Test the bit of self.

Panics

If bit >= bit_size().

Examples

use bitwise::Word;

let n = 0b1011_0010u8;
assert_eq!(n.test_bit(7), true);
assert_eq!(n.test_bit(6), false);
assert_eq!(n.test_bit(5), true);

fn clear_bits_leq(self, bit: u32) -> Self

Clears all bits of self at position <= bit.

Panics

If bit >= bit_size().

Examples

use bitwise::Word;

let n = 0b1111_0010u8;
let s = 0b1100_0000u8;
assert_eq!(n.clear_bits_leq(5), s);

fn set_bits_geq(self, bit: u32) -> Self

Sets all bits of self at position >= bit.

Panics

If bit >= bit_size().

Examples

use bitwise::Word;

let n = 0b1000_0010u8;
let s = 0b1110_0010u8;
assert_eq!(n.set_bits_geq(5), s);

fn set_bits_leq(self, bit: u32) -> Self

Sets all bits of self at position <= bit.

Panics

If bit >= bit_size().

Examples

use bitwise::Word;

let n = 0b1000_0010u8;
let s = 0b1011_1111u8;
assert_eq!(n.set_bits_leq(5), s);

fn flip_bits_geq(self, bit: u32) -> Self

Flip all bits of self at position >= bit.

Panics

If bit >= bit_size().

Examples

use bitwise::Word;

let n = 0b1001_0010u8;
let s = 0b0111_0010u8;
assert_eq!(n.flip_bits_geq(5), s);

fn flip_bits_leq(self, bit: u32) -> Self

Flip all bits of self at position <= bit.

Panics

If bit >= bit_size().

Examples

use bitwise::Word;

let n = 0b1011_0010u8;
let s = 0b1000_1101u8;
assert_eq!(n.flip_bits_leq(5), s);

fn is_pow2(self) -> bool

Is self a power of 2.

Examples

use bitwise::Word;

assert!(2.is_pow2());
assert!(!3.is_pow2());
assert!(4.is_pow2());
assert!(!5.is_pow2());
assert!(!6.is_pow2());
assert!(!7.is_pow2());
assert!(8.is_pow2());

fn ceil_pow2(self) -> Self

Round self to the next power of 2.

Panics

If the next power of 2 cannot be represented by Self.

Examples

use bitwise::Word;

assert_eq!(2.ceil_pow2(), 2);
assert_eq!(3.ceil_pow2(), 4);
assert_eq!(4.ceil_pow2(), 4);
assert_eq!(5.ceil_pow2(), 8);
assert_eq!(6.ceil_pow2(), 8);
assert_eq!(7.ceil_pow2(), 8);
assert_eq!(8.ceil_pow2(), 8);
assert_eq!(2u32.pow(30).ceil_pow2(), 2u32.pow(30));
assert_eq!((2u32.pow(30) + 1).ceil_pow2(), 2u32.pow(31));
assert_eq!(2u32.pow(31).ceil_pow2(), 2u32.pow(31));
// panics:
// assert_eq!((2u32.pow(31) + 1).ceil_pow2(), 2u32.pow(32));

fn floor_pow2(self) -> Self

Round self to the previous power of 2.

Panics

If self <= 0.

Examples

use bitwise::Word;

assert_eq!(2.floor_pow2(), 2);
assert_eq!(3.floor_pow2(), 2);
assert_eq!(4.floor_pow2(), 4);
assert_eq!(5.floor_pow2(), 4);
assert_eq!(6.floor_pow2(), 4);
assert_eq!(7.floor_pow2(), 4);
assert_eq!(8.floor_pow2(), 8);

fn average_floor(x: Self, y: Self) -> Self

Average without overflow (rounds to the smallest value).

Example

use bitwise::Word;

// The following would overflow:
let a = u64::max_value() / 2;
let b = a + 1;
let result = u64::max_value() / 2;
assert_eq!(<u64 as Word>::average_floor(a, b), result);
assert_eq!(<u64 as Word>::average_floor(b, a), result);

fn average_ceil(x: Self, y: Self) -> Self

Average without overflow (rounds to the largest value).

Example

use bitwise::Word;

// The following would overflow:
let a = u64::max_value() / 2 + 1;
let b = a - 1;
let result = u64::max_value() / 2 + 1;
assert_eq!(<u64 as Word>::average_ceil(a, b), result);
assert_eq!(<u64 as Word>::average_ceil(b, a), result);

fn inner_perfect_shuffle(self) -> Self

Inner Perfect Shuffle of self.

See also: Hacker's Delight: shuffling bits.

Examples

use bitwise::Word;

let n = 0b0110_0101_1101_1011_1111_1001_0110_0011u32;
//        abcd efgh ijkl mnop ABCD EFGH IJKL MNOP,
let s = 0b1011_1110_1001_0011_0111_1001_0100_1111u32;
//        AaBb CcDd EeFf GgHh IiJj KkLl MmNn OoPp

assert_eq!(n.inner_perfect_shuffle(), s);

fn inner_perfect_unshuffle(self) -> Self

Inner Perfect Unshuffle of self.

See also: Hacker's Delight: shuffling bits.

Examples

use bitwise::Word;

let n = 0b1011_1110_1001_0011_0111_1001_0100_1111u32;
//        AaBb CcDd EeFf GgHh IiJj KkLl MmNn OoPp
let s = 0b0110_0101_1101_1011_1111_1001_0110_0011u32;
//        abcd efgh ijkl mnop ABCD EFGH IJKL MNOP,

assert_eq!(n.inner_perfect_unshuffle(), s);

Implementors