add highest_one method

This commit is contained in:
Trevor Spiteri 2021-03-20 22:15:37 +01:00
parent 6187d714ab
commit fa1cecc104
6 changed files with 85 additions and 8 deletions

View File

@ -101,10 +101,12 @@ The conversions supported cover the following cases.
[`from_ne_bytes`][f-fnb-1-7]
* [`to_be_bytes`][f-tbb-1-7], [`to_le_bytes`][f-tlb-1-7],
[`to_ne_bytes`][f-tnb-1-7]
* The [`significant_bits`][f-signi-1-7] method was added to all
unsigned fixed-point types, to the [`FixedUnsigned`][tfu-1-7]
trait, and to the [`Wrapping`][w-1-7] and [`Unwrapped`][u-1-7]
wrappers for unsigned numbers.
* The following methods were added to all unsigned fixed-point
types, to the [`FixedUnsigned`][tfu-1-7] trait, and to the
[`Wrapping`][w-1-7] and [`Unwrapped`][u-1-7] wrappers for unsigned
numbers:
* [`significant_bits`][f-signi-1-7]
* [`highest_one`][f-ho-1-7]
* The [`signed_bits`][f-signe-1-7] method was added to all signed
fixed-point types, to the [`FixedSigned`][tfs-1-7] trait, and to
the [`Wrapping`][w-1-7] and [`Unwrapped`][u-1-7] wrappers for
@ -149,6 +151,7 @@ The conversions supported cover the following cases.
[f-fl-1-7]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.from_le
[f-flb-1-7]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.from_le_bytes
[f-fnb-1-7]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.from_ne_bytes
[f-ho-1-7]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.highest_one
[f-is-1-7]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#associatedconstant.IS_SIGNED
[f-m-1-7]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.midpoint
[f-npot-1-7]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedU32.html#method.next_power_of_two

View File

@ -28,10 +28,12 @@ Version 1.7.0 (unreleased)
[`from_ne_bytes`][f-fnb-1-7]
* [`to_be_bytes`][f-tbb-1-7], [`to_le_bytes`][f-tlb-1-7],
[`to_ne_bytes`][f-tnb-1-7]
* The [`significant_bits`][f-signi-1-7] method was added to all
unsigned fixed-point types, to the [`FixedUnsigned`][tfu-1-7]
trait, and to the [`Wrapping`][w-1-7] and [`Unwrapped`][u-1-7]
wrappers for unsigned numbers.
* The following methods were added to all unsigned fixed-point
types, to the [`FixedUnsigned`][tfu-1-7] trait, and to the
[`Wrapping`][w-1-7] and [`Unwrapped`][u-1-7] wrappers for unsigned
numbers:
* [`significant_bits`][f-signi-1-7]
* [`highest_one`][f-ho-1-7]
* The [`signed_bits`][f-signe-1-7] method was added to all signed
fixed-point types, to the [`FixedSigned`][tfs-1-7] trait, and to
the [`Wrapping`][w-1-7] and [`Unwrapped`][u-1-7] wrappers for
@ -74,6 +76,7 @@ Version 1.7.0 (unreleased)
[f-fl-1-7]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.from_le
[f-flb-1-7]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.from_le_bytes
[f-fnb-1-7]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.from_ne_bytes
[f-ho-1-7]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.highest_one
[f-is-1-7]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#associatedconstant.IS_SIGNED
[f-m-1-7]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.midpoint
[f-npot-1-7]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedU32.html#method.next_power_of_two

View File

@ -836,6 +836,34 @@ assert_eq!(Fix::MIN.unsigned_abs(), min_as_unsigned);
if_unsigned! {
$Signedness;
comment! {
"Returns the highest one in the binary
representation, or zero if `self` is zero.
If `self` > 0, the highest one is equal to the largest power of two
that is  `self`.
# Examples
```rust
use fixed::{types::extra::U4, ", $s_fixed, "};
type Fix = ", $s_fixed, "<U4>;
assert_eq!(Fix::from_bits(0b11_0010).highest_one(), Fix::from_bits(0b10_0000));
assert_eq!(Fix::from_num(3.125).highest_one(), Fix::from_num(2));
```
";
#[inline]
pub const fn highest_one(self) -> $Fixed<Frac> {
const ONE: $Inner = 1;
let bits = self.to_bits();
if bits == 0 {
self
} else {
$Fixed::from_bits(ONE << (ONE.leading_zeros() - bits.leading_zeros()))
}
}
}
comment! {
"Returns the smallest power of two that is ≥ `self`.

View File

@ -1540,6 +1540,10 @@ pub trait FixedUnsigned: Fixed {
/// [`true`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
fn is_power_of_two(self) -> bool;
/// Returns the highest one in the binary representation, or zero
/// if `self` is zero.
fn highest_one(self) -> Self;
/// Returns the smallest power of two that is ≥ `self`.
fn next_power_of_two(self) -> Self;
@ -2801,6 +2805,7 @@ macro_rules! impl_fixed {
impl<Frac: $LeEqU> FixedUnsigned for $Fixed<Frac> {
trait_delegate! { fn significant_bits(self) -> u32 }
trait_delegate! { fn is_power_of_two(self) -> bool }
trait_delegate! { fn highest_one(self) -> Self }
trait_delegate! { fn next_power_of_two(self) -> Self }
trait_delegate! { fn checked_next_power_of_two(self) -> Option<Self> }
trait_delegate! { fn wrapping_next_power_of_two(self) -> Self }

View File

@ -1173,6 +1173,25 @@ impl<F: FixedUnsigned> Unwrapped<F> {
self.0.is_power_of_two()
}
/// Returns the highest one in the binary representation, or zero
/// if `self` is zero.
///
/// If `self` > 0, the highest one is equal to the largest power
/// of two that is ≤ `self`.
///
/// # Examples
///
/// ```rust
/// use fixed::{types::U4F4, Unwrapped};
/// type T = Unwrapped<U4F4>;
/// assert_eq!(T::from_bits(0b11_0010).highest_one(), T::from_bits(0b10_0000));
/// assert_eq!(T::from_num(3.125).highest_one(), T::from_num(2));
/// ```
#[inline]
pub fn highest_one(self) -> Unwrapped<F> {
Unwrapped(self.0.highest_one())
}
/// Returns the smallest power of two that is ≥ `self`.
///
/// # Panics

View File

@ -1090,6 +1090,25 @@ impl<F: FixedUnsigned> Wrapping<F> {
self.0.is_power_of_two()
}
/// Returns the highest one in the binary representation, or zero
/// if `self` is zero.
///
/// If `self` > 0, the highest one is equal to the largest power
/// of two that is ≤ `self`.
///
/// # Examples
///
/// ```rust
/// use fixed::{types::U4F4, Wrapping};
/// type T = Wrapping<U4F4>;
/// assert_eq!(T::from_bits(0b11_0010).highest_one(), T::from_bits(0b10_0000));
/// assert_eq!(T::from_num(3.125).highest_one(), T::from_num(2));
/// ```
#[inline]
pub fn highest_one(self) -> Wrapping<F> {
Wrapping(self.0.highest_one())
}
/// Returns the smallest power of two that is ≥ `self`.
///
/// If the next power of two is too large to fit, it is wrapped to zero.