replace midpoint with mean
midpoint makes more sense for integers, where it would be used for example to find the midpoint in a binary search. With floating-point and fixed-point numbers, it makes more sense to talk about mean.
This commit is contained in:
parent
94f5042bf1
commit
05c5f398cf
|
@ -94,7 +94,7 @@ The conversions supported cover the following cases.
|
|||
* [`to_be`][f-tb-1-7], [`to_le`][f-tl-1-7]
|
||||
* [`swap_bytes`][f-sb-1-7]
|
||||
* [`reverse_bits`][f-rb-1-7]
|
||||
* [`midpoint`][f-m-1-7]
|
||||
* [`mean`][f-m-1-7]
|
||||
* The following methods were added to the [`Wrapping`][w-1-7] and
|
||||
[`Unwrapped`][u-1-7] wrappers:
|
||||
* [`from_be_bytes`][f-fbb-1-7], [`from_le_bytes`][f-flb-1-7],
|
||||
|
@ -153,7 +153,7 @@ The conversions supported cover the following cases.
|
|||
[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.FixedU32.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-m-1-7]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.mean
|
||||
[f-npot-1-7]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedU32.html#method.next_power_of_two
|
||||
[f-rb-1-7]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.reverse_bits
|
||||
[f-sb-1-7]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.swap_bytes
|
||||
|
|
|
@ -21,7 +21,7 @@ Version 1.7.0 (unreleased)
|
|||
* [`to_be`][f-tb-1-7], [`to_le`][f-tl-1-7]
|
||||
* [`swap_bytes`][f-sb-1-7]
|
||||
* [`reverse_bits`][f-rb-1-7]
|
||||
* [`midpoint`][f-m-1-7]
|
||||
* [`mean`][f-m-1-7]
|
||||
* The following methods were added to the [`Wrapping`][w-1-7] and
|
||||
[`Unwrapped`][u-1-7] wrappers:
|
||||
* [`from_be_bytes`][f-fbb-1-7], [`from_le_bytes`][f-flb-1-7],
|
||||
|
@ -78,7 +78,7 @@ Version 1.7.0 (unreleased)
|
|||
[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.FixedU32.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-m-1-7]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.mean
|
||||
[f-npot-1-7]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedU32.html#method.next_power_of_two
|
||||
[f-rb-1-7]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.reverse_bits
|
||||
[f-sb-1-7]: https://tspiteri.gitlab.io/fixed/dev/fixed/struct.FixedI32.html#method.swap_bytes
|
||||
|
|
|
@ -899,51 +899,30 @@ assert_eq!(Fix::from_num(6.5).next_power_of_two(), Fix::from_num(8));
|
|||
}
|
||||
|
||||
comment! {
|
||||
"Returns the midpoint of `self` and `other`, rounding towards `self`.
|
||||
"Returns the mean of `self` and `other`.
|
||||
|
||||
# Examples
|
||||
|
||||
```rust
|
||||
use fixed::{types::extra::U4, ", $s_fixed, "};
|
||||
type Fix = ", $s_fixed, "<U4>;
|
||||
assert_eq!(Fix::from_num(3).midpoint(Fix::from_num(4)), Fix::from_num(3.5));
|
||||
assert_eq!(Fix::from_num(3).mean(Fix::from_num(4)), Fix::from_num(3.5));
|
||||
",
|
||||
if_signed_else_empty_str! {
|
||||
$Signedness,
|
||||
"assert_eq!(Fix::from_num(-3).midpoint(Fix::from_num(4)), Fix::from_num(0.5));
|
||||
"assert_eq!(Fix::from_num(-3).mean(Fix::from_num(4)), Fix::from_num(0.5));
|
||||
",
|
||||
},
|
||||
"
|
||||
// Midpoint of 0b0.0011 and 0b0.00100 is 0b0.0011_1, which has to be rounded.
|
||||
assert_eq!(Fix::from_bits(3).midpoint(Fix::from_bits(4)), Fix::from_bits(3));
|
||||
assert_eq!(Fix::from_bits(4).midpoint(Fix::from_bits(3)), Fix::from_bits(4));
|
||||
```
|
||||
"```
|
||||
";
|
||||
#[inline]
|
||||
pub const fn midpoint(self, other: $Fixed<Frac>) -> $Fixed<Frac> {
|
||||
// This shoud return a + (b - a) / 2, where / 2 rounds
|
||||
// towards zero so that the midpoint rounds towards a.
|
||||
//
|
||||
// The first step replaces division with rounding to 0, / 2,
|
||||
// with flooring division, >> 1.
|
||||
// This is necessary because (2 * x + y) / 2 is not always = x + y / 2,
|
||||
// because the signum of the dividend affects the rounding direction,
|
||||
// but (2 * x + y) >> 1 is always = x + (y >> 1).
|
||||
//
|
||||
// a + (b - a) / 2
|
||||
// = a + ((b - a + b<a) >> 1)
|
||||
// = 2 * (a>>1) + (a&1) + ((2 * (b>>1) + (b&1) - 2 * (a>>1) - (a&1) + b<a) >> 1)
|
||||
// = 2 * (a>>1) + (a&1) + (b>>1) - (a>>1) + (((b&1) - (a&1) + b<a) >> 1)
|
||||
// = (a>>1) + (b>>1) + (a&1) + (((b&1) - (a&1) + b<a) >> 1)
|
||||
// = (a>>1) + (b>>1) + ((2 * (a&1) + (b&1) - (a&1) + b<a) >> 1)
|
||||
// = (a>>1) + (b>>1) + (((a&1) + (b&1) + b<a) >> 1)
|
||||
// Let inc = (((a&1) + (b&1) + b<a) >> 1).
|
||||
// Then inc is 1 if two or three of (a&1), (b&1), (b<a) are 1, and 0 otherwise.
|
||||
// That is, if b < a then inc is (a&1) | (b&1), else inc is (a&1) & (b&1).
|
||||
// That is, if b < a then inc is 1 & (a|b), else inc is 1 & (a&b).
|
||||
pub const fn mean(self, other: $Fixed<Frac>) -> $Fixed<Frac> {
|
||||
// a & b == common bits
|
||||
// a ^ b == different bits
|
||||
// a + b == 2 * (a & b) + (a ^ b)
|
||||
// (a + b) / 2 = (a & b) + (a ^ b) / 2
|
||||
let (a, b) = (self.to_bits(), other.to_bits());
|
||||
let inc = 1 & if b < a { a | b } else { a & b };
|
||||
$Fixed::from_bits((a >> 1) + (b >> 1) + inc)
|
||||
$Fixed::from_bits((a & b) + ((a ^ b) >> 1))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -827,8 +827,8 @@ where
|
|||
/// Shifts to the right by `n` bits, wrapping the truncated bits to the left end.
|
||||
fn rotate_right(self, n: u32) -> Self;
|
||||
|
||||
/// Returns the midpoint of `self` and `other`, rounding towards `self`.
|
||||
fn midpoint(self, other: Self) -> Self;
|
||||
/// Returns the mean of `self` and `other`.
|
||||
fn mean(self, other: Self) -> Self;
|
||||
|
||||
/// Returns the reciprocal.
|
||||
///
|
||||
|
@ -2498,7 +2498,7 @@ macro_rules! impl_fixed {
|
|||
trait_delegate! { fn reverse_bits(self) -> Self }
|
||||
trait_delegate! { fn rotate_left(self, n: u32) -> Self }
|
||||
trait_delegate! { fn rotate_right(self, n: u32) -> Self }
|
||||
trait_delegate! { fn midpoint(self, other: Self) -> Self }
|
||||
trait_delegate! { fn mean(self, other: Self) -> Self }
|
||||
trait_delegate! { fn recip(self) -> Self }
|
||||
trait_delegate! { fn mul_add(self, mul: Self, add: Self) -> Self }
|
||||
trait_delegate! { fn div_euclid(self, rhs: Self) -> Self }
|
||||
|
|
|
@ -845,7 +845,7 @@ impl<F: Fixed> Unwrapped<F> {
|
|||
Unwrapped(self.0.rotate_right(n))
|
||||
}
|
||||
|
||||
/// Returns the midpoint of `self` and `other`, rounding towards `self`.
|
||||
/// Returns the mean of `self` and `other`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -853,12 +853,12 @@ impl<F: Fixed> Unwrapped<F> {
|
|||
/// use fixed::{types::I16F16, Unwrapped};
|
||||
/// let three = Unwrapped(I16F16::from_num(3));
|
||||
/// let four = Unwrapped(I16F16::from_num(4));
|
||||
/// assert_eq!(three.midpoint(four), Unwrapped(I16F16::from_num(3.5)));
|
||||
/// assert_eq!(three.midpoint(-four), Unwrapped(I16F16::from_num(-0.5)));
|
||||
/// assert_eq!(three.mean(four), Unwrapped(I16F16::from_num(3.5)));
|
||||
/// assert_eq!(three.mean(-four), Unwrapped(I16F16::from_num(-0.5)));
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn midpoint(self, other: Unwrapped<F>) -> Unwrapped<F> {
|
||||
Unwrapped(self.0.midpoint(other.0))
|
||||
pub fn mean(self, other: Unwrapped<F>) -> Unwrapped<F> {
|
||||
Unwrapped(self.0.mean(other.0))
|
||||
}
|
||||
|
||||
/// Returns the reciprocal (inverse), 1/`self`.
|
||||
|
|
|
@ -801,7 +801,7 @@ impl<F: Fixed> Wrapping<F> {
|
|||
Wrapping(self.0.rotate_right(n))
|
||||
}
|
||||
|
||||
/// Returns the midpoint of `self` and `other`, rounding towards `self`.
|
||||
/// Returns the mean of `self` and `other`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -809,12 +809,12 @@ impl<F: Fixed> Wrapping<F> {
|
|||
/// use fixed::{types::I16F16, Wrapping};
|
||||
/// let three = Wrapping(I16F16::from_num(3));
|
||||
/// let four = Wrapping(I16F16::from_num(4));
|
||||
/// assert_eq!(three.midpoint(four), Wrapping(I16F16::from_num(3.5)));
|
||||
/// assert_eq!(three.midpoint(-four), Wrapping(I16F16::from_num(-0.5)));
|
||||
/// assert_eq!(three.mean(four), Wrapping(I16F16::from_num(3.5)));
|
||||
/// assert_eq!(three.mean(-four), Wrapping(I16F16::from_num(-0.5)));
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn midpoint(self, other: Wrapping<F>) -> Wrapping<F> {
|
||||
Wrapping(self.0.midpoint(other.0))
|
||||
pub fn mean(self, other: Wrapping<F>) -> Wrapping<F> {
|
||||
Wrapping(self.0.mean(other.0))
|
||||
}
|
||||
|
||||
/// Returns the reciprocal (inverse), 1/`self`.
|
||||
|
|
Loading…
Reference in New Issue