// Copyright © 2018–2020 Trevor Spiteri
// This library is free software: you can redistribute it and/or
// modify it under the terms of either
//
// * the Apache License, Version 2.0 or
// * the MIT License
//
// at your option.
//
// You should have recieved copies of the Apache License and the MIT
// License along with the library. If not, see
// <https://www.apache.org/licenses/LICENSE-2.0> and
// <https://opensource.org/licenses/MIT>.
/*!
Traits for conversions and for generic use of fixed-point numbers.
*/
use crate::{
helpers::{FloatHelper, FloatKind, FromFloatHelper, IntHelper, Sealed, Widest},
types::extra::{LeEqU128, LeEqU16, LeEqU32, LeEqU64, LeEqU8, Unsigned},
FixedI128, FixedI16, FixedI32, FixedI64, FixedI8, FixedU128, FixedU16, FixedU32, FixedU64,
FixedU8, ParseFixedError,
};
use core::{
fmt::{Binary, Debug, Display, LowerHex, Octal, UpperHex},
hash::Hash,
mem,
ops::{
Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div,
DivAssign, Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub,
SubAssign,
},
str::FromStr,
};
#[cfg(feature = "f16")]
use half::{bf16, f16};
#[cfg(feature = "num-traits")]
use num_traits::{
bounds::Bounded,
identities::Zero,
ops::{
checked::{
CheckedAdd, CheckedDiv, CheckedMul, CheckedNeg, CheckedRem, CheckedShl, CheckedShr,
CheckedSub,
},
saturating::{SaturatingAdd, SaturatingMul, SaturatingSub},
wrapping::{WrappingAdd, WrappingMul, WrappingNeg, WrappingShl, WrappingShr, WrappingSub},
},
};
#[cfg(feature = "serde")]
use serde::{de::Deserialize, ser::Serialize};
macro_rules! comment_features {
($comment:expr) => {
#[cfg(all(
not(feature = "f16"),
not(feature = "num-traits"),
not(feature = "serde")
))]
doc_comment! {
$comment;
pub trait FixedOptionalFeatures {}
}
#[cfg(all(not(feature = "f16"), not(feature = "num-traits"), feature = "serde"))]
doc_comment! {
$comment;
pub trait FixedOptionalFeatures: Serialize + for<'de> Deserialize<'de> {}
}
#[cfg(all(not(feature = "f16"), feature = "num-traits", not(feature = "serde")))]
doc_comment! {
$comment;
pub trait FixedOptionalFeatures
where
Self: Bounded + Zero,
Self: CheckedAdd + CheckedSub + CheckedNeg + CheckedMul,
Self: CheckedDiv + CheckedRem + CheckedShl + CheckedShr,
Self: SaturatingAdd + SaturatingSub + SaturatingMul,
Self: WrappingAdd + WrappingSub + WrappingNeg + WrappingMul,
Self: WrappingShl + WrappingShr,
{
}
}
#[cfg(all(not(feature = "f16"), feature = "num-traits", feature = "serde"))]
doc_comment! {
$comment;
pub trait FixedOptionalFeatures
where
Self: Bounded + Zero,
Self: CheckedAdd + CheckedSub + CheckedNeg + CheckedMul,
Self: CheckedDiv + CheckedRem + CheckedShl + CheckedShr,
Self: SaturatingAdd + SaturatingSub + SaturatingMul,
Self: WrappingAdd + WrappingSub + WrappingNeg + WrappingMul,
Self: WrappingShl + WrappingShr,
Self: Serialize + for<'de> Deserialize<'de>,
{
}
}
#[cfg(all(feature = "f16", not(feature = "num-traits"), not(feature = "serde")))]
doc_comment! {
$comment;
pub trait FixedOptionalFeatures: PartialOrd<f16> + PartialOrd<bf16> {}
}
#[cfg(all(feature = "f16", not(feature = "num-traits"), feature = "serde"))]
doc_comment! {
$comment;
pub trait FixedOptionalFeatures
where
Self: PartialOrd<f16> + PartialOrd<bf16>,
Self: Serialize + for<'de> Deserialize<'de>,
{
}
}
#[cfg(all(feature = "f16", feature = "num-traits", not(feature = "serde")))]
doc_comment! {
$comment;
pub trait FixedOptionalFeatures
where
Self: PartialOrd<f16> + PartialOrd<bf16>,
Self: Bounded + Zero,
Self: CheckedAdd + CheckedSub + CheckedNeg + CheckedMul,
Self: CheckedDiv + CheckedRem + CheckedShl + CheckedShr,
Self: SaturatingAdd + SaturatingSub + SaturatingMul,
Self: WrappingAdd + WrappingSub + WrappingNeg + WrappingMul,
Self: WrappingShl + WrappingShr,
{
}
}
#[cfg(all(feature = "f16", feature = "num-traits", feature = "serde"))]
doc_comment! {
$comment;
pub trait FixedOptionalFeatures
where
Self: PartialOrd<f16> + PartialOrd<bf16>,
Self: Bounded + Zero,
Self: CheckedAdd + CheckedSub + CheckedNeg + CheckedMul,
Self: CheckedDiv + CheckedRem + CheckedShl + CheckedShr,
Self: SaturatingAdd + SaturatingSub + SaturatingMul,
Self: WrappingAdd + WrappingSub + WrappingNeg + WrappingMul,
Self: WrappingShl + WrappingShr,
Self: Serialize + for<'de> Deserialize<'de>,
{
}
}
};
}
comment_features! {
"This trait is used to provide supertraits to the [`Fixed`] trait
depending on the crate’s [optional features].
1. If the `f16` feature is enabled,
<code>[PartialOrd][`PartialOrd`]<[f16][`f16`]></code> and
<code>[PartialOrd][`PartialOrd`]<[bf16][`bf16`]></code> are
supertraits of [`Fixed`].
2. If the `num-traits` experimental feature is enabled, the following
are supertraits of [`Fixed`]:
* [`Bounded`], [`Zero`] (but *not* [`One`] because not all
fixed-point numbers can represent the value 1)
* [`CheckedAdd`], [`CheckedSub`], [`CheckedNeg`],
[`CheckedMul`], [`CheckedDiv`], [`CheckedRem`],
[`CheckedShl`], [`CheckedShr`]
* [`SaturatingAdd`], [`SaturatingSub`], [`SaturatingMul`]
* [`WrappingAdd`], [`WrappingSub`], [`WrappingNeg`],
[`WrappingMul`], [`WrappingShl`], [`WrappingShr`]
3. If the `serde` feature is enabled, [`Serialize`] and
[`Deserialize`] are supertraits of [`Fixed`].
[`Bounded`]: https://docs.rs/num-traits/^0.2/num_traits/bounds/trait.Bounded.html
[`CheckedAdd`]: https://docs.rs/num-traits/^0.2/num_traits/ops/checked/trait.CheckedAdd.html
[`CheckedDiv`]: https://docs.rs/num-traits/^0.2/num_traits/ops/checked/trait.CheckedDiv.html
[`CheckedMul`]: https://docs.rs/num-traits/^0.2/num_traits/ops/checked/trait.CheckedMul.html
[`CheckedNeg`]: https://docs.rs/num-traits/^0.2/num_traits/ops/checked/trait.CheckedNeg.html
[`CheckedRem`]: https://docs.rs/num-traits/^0.2/num_traits/ops/checked/trait.CheckedRem.html
[`CheckedShl`]: https://docs.rs/num-traits/^0.2/num_traits/ops/checked/trait.CheckedShl.html
[`CheckedShr`]: https://docs.rs/num-traits/^0.2/num_traits/ops/checked/trait.CheckedShr.html
[`CheckedSub`]: https://docs.rs/num-traits/^0.2/num_traits/ops/checked/trait.CheckedSub.html
[`Deserialize`]: https://docs.rs/serde/^1/serde/de/trait.Deserialize.html
[`Fixed`]: trait.Fixed.html
[`One`]: https://docs.rs/num-traits/^0.2/num_traits/identities/trait.One.html
[`PartialOrd`]: https://doc.rust-lang.org/nightly/core/cmp/trait.PartialOrd.html
[`SaturatingAdd`]: https://docs.rs/num-traits/^0.2/num_traits/ops/saturating/trait.SaturatingAdd.html
[`SaturatingMul`]: https://docs.rs/num-traits/^0.2/num_traits/ops/saturating/trait.SaturatingMul.html
[`SaturatingSub`]: https://docs.rs/num-traits/^0.2/num_traits/ops/saturating/trait.SaturatingSub.html
[`Serialize`]: https://docs.rs/serde/^1/serde/ser/trait.Serialize.html
[`WrappingAdd`]: https://docs.rs/num-traits/^0.2/num_traits/ops/wrapping/trait.WrappingAdd.html
[`WrappingMul`]: https://docs.rs/num-traits/^0.2/num_traits/ops/wrapping/trait.WrappingMul.html
[`WrappingNeg`]: https://docs.rs/num-traits/^0.2/num_traits/ops/wrapping/trait.WrappingNeg.html
[`WrappingShl`]: https://docs.rs/num-traits/^0.2/num_traits/ops/wrapping/trait.WrappingShl.html
[`WrappingShr`]: https://docs.rs/num-traits/^0.2/num_traits/ops/wrapping/trait.WrappingShr.html
[`WrappingSub`]: https://docs.rs/num-traits/^0.2/num_traits/ops/wrapping/trait.WrappingSub.html
[`Zero`]: https://docs.rs/num-traits/^0.2/num_traits/identities/trait.Zero.html
[`bf16`]: https://docs.rs/half/^1/half/struct.bf16.html
[`f16`]: https://docs.rs/half/^1/half/struct.f16.html
[optional features]: ../index.html#optional-features
"
}
/// This trait provides methods common to all fixed-point numbers.
///
/// It can be helpful when writing generic code that makes use of
/// fixed-point numbers. For methods only available on signed
/// fixed-point numbers, use the [`FixedSigned`] trait instead, and
/// for methods only available on unsigned fixed-point numbers, use
/// [`FixedUnsigned`].
///
/// This trait is sealed and cannot be implemented for more types; it
/// is implemented for [`FixedI8`], [`FixedI16`], [`FixedI32`],
/// [`FixedI64`], [`FixedI128`], [`FixedU8`], [`FixedU16`],
/// [`FixedU32`], [`FixedU64`], and [`FixedU128`].
///
/// # Examples
///
/// ```rust
/// use fixed::{
/// traits::Fixed,
/// types::{I8F8, I16F16},
/// };
///
/// fn checked_add_twice<F: Fixed>(lhs: F, rhs: F) -> Option<F> {
/// lhs.checked_add(rhs)?.checked_add(rhs)
/// }
///
/// let val1 = checked_add_twice(I8F8::from_num(5), Fixed::from_num(1.75));
/// assert_eq!(val1, Some(Fixed::from_num(8.5)));
/// // can use with different fixed-point type
/// let val2 = checked_add_twice(I16F16::from_num(5), Fixed::from_num(1.75));
/// assert_eq!(val2, Some(Fixed::from_num(8.5)));
/// ```
///
/// The following example fails to compile, since the compiler cannot
/// infer that 500 in the `checked_mul_int` call is of type `F::Bits`.
///
/// ```compile_fail
/// use fixed::traits::Fixed;
///
/// fn checked_add_times_500<F: Fixed>(lhs: F, rhs: F) -> Option<F> {
/// rhs.checked_mul_int(500)?.checked_add(lhs)
/// }
/// ```
///
/// One way to fix this is to add a trait bound indicating that any
/// [`u16`] (which can represent 500) can be converted into `F::Bits`.
///
/// ```rust
/// use fixed::{traits::Fixed, types::U12F4};
///
/// fn checked_add_times_500<F: Fixed>(lhs: F, rhs: F) -> Option<F>
/// where
/// u16: Into<F::Bits>,
/// {
/// rhs.checked_mul_int(500.into())?.checked_add(lhs)
/// }
///
/// let val = checked_add_times_500(U12F4::from_num(0.25), Fixed::from_num(1.5));
/// assert_eq!(val, Some(Fixed::from_num(750.25)));
/// ```
///
/// While this works in most cases, [`u16`] cannot be converted to
/// [`i16`], even if the value 500 does fit in [`i16`], so that the
/// following example would fail to compile.
///
/// ```compile_fail
/// use fixed::{traits::Fixed, types::I12F4};
///
/// fn checked_add_times_500<F: Fixed>(lhs: F, rhs: F) -> Option<F>
/// where
/// u16: Into<F::Bits>,
/// {
/// rhs.checked_mul_int(500.into())?.checked_add(lhs)
/// }
///
/// // I12F4::Bits is i16, and u16 does not implement Into<i16>
/// let val = checked_add_times_500(I12F4::from_num(0.25), Fixed::from_num(1.5));
/// # let _ = val;
/// ```
///
/// We can use [`TryFrom`] to fix this, as we know that
/// `F::Bits::try_from(500_u16)` will work for both [`u16`] and
/// [`i16`]. (The function will always return [`None`] when `F::Bits`
/// is [`u8`] or [`i8`].)
///
/// ```rust
/// use fixed::{traits::Fixed, types::I12F4};
/// use core::convert::TryInto;
///
/// fn checked_add_times_500<F: Fixed>(lhs: F, rhs: F) -> Option<F>
/// where
/// u16: TryInto<F::Bits>,
/// {
/// rhs.checked_mul_int(500.try_into().ok()?)?.checked_add(lhs)
/// }
///
/// let val = checked_add_times_500(I12F4::from_num(0.25), Fixed::from_num(1.5));
/// assert_eq!(val, Some(Fixed::from_num(750.25)));
/// ```
///
/// [`FixedI128`]: ../struct.FixedI128.html
/// [`FixedI16`]: ../struct.FixedI16.html
/// [`FixedI32`]: ../struct.FixedI32.html
/// [`FixedI64`]: ../struct.FixedI64.html
/// [`FixedI8`]: ../struct.FixedI8.html
/// [`FixedSigned`]: trait.FixedSigned.html
/// [`FixedU128`]: ../struct.FixedU128.html
/// [`FixedU16`]: ../struct.FixedU16.html
/// [`FixedU32`]: ../struct.FixedU32.html
/// [`FixedU64`]: ../struct.FixedU64.html
/// [`FixedU8`]: ../struct.FixedU8.html
/// [`FixedUnsigned`]: trait.FixedUnsigned.html
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
/// [`TryFrom`]: https://doc.rust-lang.org/nightly/core/convert/trait.TryFrom.html
/// [`i16`]: https://doc.rust-lang.org/nightly/std/primitive.i16.html
/// [`i8`]: https://doc.rust-lang.org/nightly/std/primitive.i8.html
/// [`u16`]: https://doc.rust-lang.org/nightly/std/primitive.u16.html
/// [`u8`]: https://doc.rust-lang.org/nightly/std/primitive.u8.html
pub trait Fixed
where
Self: Copy + Default + Hash + Ord,
Self: Debug + Display + Binary + Octal + LowerHex + UpperHex,
Self: FromStr<Err = ParseFixedError>,
Self: FromFixed + ToFixed,
Self: Add<Output = Self> + AddAssign + Sub<Output = Self> + SubAssign,
Self: Mul<Output = Self> + MulAssign + Div<Output = Self> + DivAssign,
Self: Rem<Output = Self> + RemAssign,
Self: Mul<<Self as Fixed>::Bits, Output = Self> + MulAssign<<Self as Fixed>::Bits>,
Self: Div<<Self as Fixed>::Bits, Output = Self> + DivAssign<<Self as Fixed>::Bits>,
Self: Rem<<Self as Fixed>::Bits, Output = Self> + RemAssign<<Self as Fixed>::Bits>,
Self: Not<Output = Self> + BitAnd<Output = Self> + BitAndAssign,
Self: BitOr<Output = Self> + BitOrAssign + BitXor<Output = Self> + BitXorAssign,
Self: Shl<u32, Output = Self> + ShlAssign<u32> + Shr<u32, Output = Self> + ShrAssign<u32>,
Self: PartialOrd<i8> + PartialOrd<i16> + PartialOrd<i32>,
Self: PartialOrd<i64> + PartialOrd<i128> + PartialOrd<isize>,
Self: PartialOrd<u8> + PartialOrd<u16> + PartialOrd<u32>,
Self: PartialOrd<u64> + PartialOrd<u128> + PartialOrd<usize>,
Self: PartialOrd<f32> + PartialOrd<f64>,
Self: FixedOptionalFeatures,
Self: Sealed,
{
/// The primitive integer underlying type.
type Bits;
/// A byte array with the same size as the type.
type Bytes;
/// The number of fractional bits.
///
/// <code><F as [Fixed]>::Frac::[U32]</code> is equivalent to
/// <code><F as [Fixed]>::[frac_nbits][`frac_nbits`]()</code>.
///
/// [Fixed]: trait.Fixed.html
/// [U32]: ../types/extra/trait.Unsigned.html#associatedconstant.U32
/// [`frac_nbits`]: #tymethod.frac_nbits
type Frac: Unsigned;
/// The smallest value that can be represented.
const MIN: Self;
/// The largest value that can be represented.
const MAX: Self;
/// The number of integer bits.
const INT_NBITS: u32;
/// The number of fractional bits.
const FRAC_NBITS: u32;
/// Creates a fixed-point number that has a bitwise representation
/// identical to the given integer.
fn from_bits(bits: Self::Bits) -> Self;
/// Creates an integer that has a bitwise representation identical
/// to the given fixed-point number.
fn to_bits(self) -> Self::Bits;
/// Creates a fixed-point number from its representation as a byte
/// array in big endian.
fn from_be_bytes(bytes: Self::Bytes) -> Self;
/// Creates a fixed-point number from its representation as a byte
/// array in little endian.
fn from_le_bytes(bytes: Self::Bytes) -> Self;
/// Creates a fixed-point number from its representation as a byte
/// array in native endian.
fn from_ne_bytes(bytes: Self::Bytes) -> Self;
/// Returns the memory representation of this fixed-point number
/// as a byte array in big-endian byte order.
fn to_be_bytes(self) -> Self::Bytes;
/// Returns the memory representation of this fixed-point number
/// as a byte array in little-endian byte order.
fn to_le_bytes(self) -> Self::Bytes;
/// Returns the memory representation of this fixed-point number
/// as a byte array in native byte order.
fn to_ne_bytes(self) -> Self::Bytes;
/// Creates a fixed-point number from another number.
///
/// Returns the same value as [`src.to_fixed()`][`to_fixed`].
///
/// [`to_fixed`]: trait.ToFixed.html#tymethod.to_fixed
fn from_num<Src: ToFixed>(src: Src) -> Self;
/// Converts a fixed-point number to another number.
///
/// Returns the same value as [`Dst::from_fixed(self)`][`from_fixed`].
///
/// [`from_fixed`]: trait.FromFixed.html#tymethod.from_fixed
fn to_num<Dst: FromFixed>(self) -> Dst;
/// Creates a fixed-point number from another number if it fits,
/// otherwise returns [`None`].
///
/// Returns the same value as [`src.checked_to_fixed()`][`checked_to_fixed`].
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
/// [`checked_to_fixed`]: trait.ToFixed.html#tymethod.checked_to_fixed
fn checked_from_num<Src: ToFixed>(src: Src) -> Option<Self>;
/// Converts a fixed-point number to another number if it fits,
/// otherwise returns [`None`].
///
/// Returns the same value as [`Dst::checked_from_fixed(self)`][`checked_from_fixed`].
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
/// [`checked_from_fixed`]: trait.FromFixed.html#tymethod.checked_from_fixed
fn checked_to_num<Dst: FromFixed>(self) -> Option<Dst>;
/// Creates a fixed-point number from another number, saturating the
/// value if it does not fit.
///
/// Returns the same value as [`src.saturating_to_fixed()`][`saturating_to_fixed`].
///
/// [`saturating_to_fixed`]: trait.ToFixed.html#tymethod.saturating_to_fixed
fn saturating_from_num<Src: ToFixed>(src: Src) -> Self;
/// Converts a fixed-point number to another number, saturating the
/// value if it does not fit.
///
/// Returns the same value as [`Dst::saturating_from_fixed(self)`][`saturating_from_fixed`].
///
/// [`saturating_from_fixed`]: trait.FromFixed.html#tymethod.saturating_from_fixed
fn saturating_to_num<Dst: FromFixed>(self) -> Dst;
/// Creates a fixed-point number from another number, wrapping the
/// value on overflow.
///
/// Returns the same value as [`src.wrapping_to_fixed()`][`wrapping_to_fixed`].
///
/// [`wrapping_to_fixed`]: trait.ToFixed.html#tymethod.wrapping_to_fixed
fn wrapping_from_num<Src: ToFixed>(src: Src) -> Self;
/// Converts a fixed-point number to another number, wrapping the
/// value on overflow.
///
/// Returns the same value as [`Src::wrapping_from_fixed(self)`][`wrapping_from_fixed`].
///
/// [`wrapping_from_fixed`]: trait.FromFixed.html#tymethod.wrapping_from_fixed
fn wrapping_to_num<Dst: FromFixed>(self) -> Dst;
/// Creates a fixed-point number from another number.
///
/// Returns the same value as [`src.overflowing_to_fixed()`][`overflowing_to_fixed`].
///
/// [`overflowing_to_fixed`]: trait.ToFixed.html#tymethod.overflowing_to_fixed
fn overflowing_from_num<Src: ToFixed>(src: Src) -> (Self, bool);
/// Converts a fixed-point number to another number.
///
/// Returns the same value as [`Dst::overflowing_from_fixed(self)`][`overflowing_from_fixed`].
///
/// [`overflowing_from_fixed`]: trait.FromFixed.html#tymethod.overflowing_from_fixed
fn overflowing_to_num<Dst: FromFixed>(self) -> (Dst, bool);
/// Parses a string slice containing binary digits to return a fixed-point number.
///
/// Rounding is to the nearest, with ties rounded to even.
fn from_str_binary(src: &str) -> Result<Self, ParseFixedError>;
/// Parses a string slice containing octal digits to return a fixed-point number.
///
/// Rounding is to the nearest, with ties rounded to even.
fn from_str_octal(src: &str) -> Result<Self, ParseFixedError>;
/// Parses a string slice containing hexadecimal digits to return a fixed-point number.
///
/// Rounding is to the nearest, with ties rounded to even.
fn from_str_hex(src: &str) -> Result<Self, ParseFixedError>;
/// Parses a string slice containing decimal digits to return a
/// fixed-point number, saturating on overflow.
///
/// Rounding is to the nearest, with ties rounded to even.
fn saturating_from_str(src: &str) -> Result<Self, ParseFixedError>;
/// Parses a string slice containing binary digits to return a
/// fixed-point number, saturating on overflow.
///
/// Rounding is to the nearest, with ties rounded to even.
fn saturating_from_str_binary(src: &str) -> Result<Self, ParseFixedError>;
/// Parses a string slice containing octal digits to return a
/// fixed-point number, saturating on overflow.
///
/// Rounding is to the nearest, with ties rounded to even.
fn saturating_from_str_octal(src: &str) -> Result<Self, ParseFixedError>;
/// Parses a string slice containing hexadecimal digits to return a
/// fixed-point number, saturating on overflow.
///
/// Rounding is to the nearest, with ties rounded to even.
fn saturating_from_str_hex(src: &str) -> Result<Self, ParseFixedError>;
/// Parses a string slice containing decimal digits to return a
/// fixed-point number, wrapping on overflow.
///
/// Rounding is to the nearest, with ties rounded to even.
fn wrapping_from_str(src: &str) -> Result<Self, ParseFixedError>;
/// Parses a string slice containing binary digits to return a
/// fixed-point number, wrapping on overflow.
///
/// Rounding is to the nearest, with ties rounded to even.
fn wrapping_from_str_binary(src: &str) -> Result<Self, ParseFixedError>;
/// Parses a string slice containing octal digits to return a
/// fixed-point number, wrapping on overflow.
///
/// Rounding is to the nearest, with ties rounded to even.
fn wrapping_from_str_octal(src: &str) -> Result<Self, ParseFixedError>;
/// Parses a string slice containing hexadecimal digits to return a
/// fixed-point number, wrapping on overflow.
///
/// Rounding is to the nearest, with ties rounded to even.
fn wrapping_from_str_hex(src: &str) -> Result<Self, ParseFixedError>;
/// Parses a string slice containing decimal digits to return a
/// fixed-point number.
///
/// Returns a [tuple] of the fixed-point number and a [`bool`],
/// indicating whether an overflow has occurred. On overflow, the
/// wrapped value is returned.
///
/// Rounding is to the nearest, with ties rounded to even.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
fn overflowing_from_str(src: &str) -> Result<(Self, bool), ParseFixedError>;
/// Parses a string slice containing binary digits to return a
/// fixed-point number.
///
/// Returns a [tuple] of the fixed-point number and a [`bool`],
/// indicating whether an overflow has occurred. On overflow, the
/// wrapped value is returned.
///
/// Rounding is to the nearest, with ties rounded to even.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
fn overflowing_from_str_binary(src: &str) -> Result<(Self, bool), ParseFixedError>;
/// Parses a string slice containing octal digits to return a
/// fixed-point number.
///
/// Returns a [tuple] of the fixed-point number and a [`bool`],
/// indicating whether an overflow has occurred. On overflow, the
/// wrapped value is returned.
///
/// Rounding is to the nearest, with ties rounded to even.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
fn overflowing_from_str_octal(src: &str) -> Result<(Self, bool), ParseFixedError>;
/// Parses a string slice containing hexadecimal digits to return a
/// fixed-point number.
///
/// Returns a [tuple] of the fixed-point number and a [`bool`],
/// indicating whether an overflow has occurred. On overflow, the
/// wrapped value is returned.
///
/// Rounding is to the nearest, with ties rounded to even.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
fn overflowing_from_str_hex(src: &str) -> Result<(Self, bool), ParseFixedError>;
/// Returns the integer part.
fn int(self) -> Self;
/// Returns the fractional part.
fn frac(self) -> Self;
/// Rounds to the next integer towards 0.
fn round_to_zero(self) -> Self;
/// Rounds to the next integer towards +∞.
fn ceil(self) -> Self;
/// Rounds to the next integer towards −∞.
fn floor(self) -> Self;
/// Rounds to the nearest integer, with ties rounded away from zero.
fn round(self) -> Self;
/// Rounds to the nearest integer, with ties rounded to even.
fn round_ties_to_even(self) -> Self;
/// Checked ceil. Rounds to the next integer towards +∞, returning
/// [`None`] on overflow.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
fn checked_ceil(self) -> Option<Self>;
/// Checked floor. Rounds to the next integer towards −∞, returning
/// [`None`] on overflow.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
fn checked_floor(self) -> Option<Self>;
/// Checked round. Rounds to the nearest integer, with ties
/// rounded away from zero, returning [`None`] on overflow.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
fn checked_round(self) -> Option<Self>;
/// Checked round. Rounds to the nearest integer, with ties
/// rounded to even, returning [`None`] on overflow.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
fn checked_round_ties_to_even(self) -> Option<Self>;
/// Saturating ceil. Rounds to the next integer towards +∞,
/// saturating on overflow.
fn saturating_ceil(self) -> Self;
/// Saturating floor. Rounds to the next integer towards −∞,
/// saturating on overflow.
fn saturating_floor(self) -> Self;
/// Saturating round. Rounds to the nearest integer, with ties
/// rounded away from zero, and saturating on overflow.
fn saturating_round(self) -> Self;
/// Saturating round. Rounds to the nearest integer, with ties
/// rounded to_even, and saturating on overflow.
fn saturating_round_ties_to_even(self) -> Self;
/// Wrapping ceil. Rounds to the next integer towards +∞, wrapping
/// on overflow.
fn wrapping_ceil(self) -> Self;
/// Wrapping floor. Rounds to the next integer towards −∞,
/// wrapping on overflow.
fn wrapping_floor(self) -> Self;
/// Wrapping round. Rounds to the next integer to the nearest,
/// with ties rounded away from zero, and wrapping on overflow.
fn wrapping_round(self) -> Self;
/// Wrapping round. Rounds to the next integer to the nearest,
/// with ties rounded to even, and wrapping on overflow.
fn wrapping_round_ties_to_even(self) -> Self;
/// Overflowing ceil. Rounds to the next integer towards +∞.
///
/// Returns a [tuple] of the fixed-point number and a [`bool`],
/// indicating whether an overflow has occurred. On overflow, the
/// wrapped value is returned.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
fn overflowing_ceil(self) -> (Self, bool);
/// Overflowing floor. Rounds to the next integer towards −∞.
///
/// Returns a [tuple] of the fixed-point number and a [`bool`],
/// indicating whether an overflow has occurred. On overflow, the
/// wrapped value is returned.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
fn overflowing_floor(self) -> (Self, bool);
/// Overflowing round. Rounds to the next integer to the nearest,
/// with ties rounded away from zero.
///
/// Returns a [tuple] of the fixed-point number and a [`bool`],
/// indicating whether an overflow has occurred. On overflow, the
/// wrapped value is returned.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
fn overflowing_round(self) -> (Self, bool);
/// Overflowing round. Rounds to the next integer to the nearest,
/// with ties rounded to even.
///
/// Returns a [tuple] of the fixed-point number and a [`bool`],
/// indicating whether an overflow has occurred. On overflow, the
/// wrapped value is returned.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
fn overflowing_round_ties_to_even(self) -> (Self, bool);
/// Returns the number of ones in the binary representation.
fn count_ones(self) -> u32;
/// Returns the number of zeros in the binary representation.
fn count_zeros(self) -> u32;
/// Returns the number of leading ones in the binary representation.
fn leading_ones(self) -> u32;
/// Returns the number of leading zeros in the binary representation.
fn leading_zeros(self) -> u32;
/// Returns the number of trailing ones in the binary representation.
fn trailing_ones(self) -> u32;
/// Returns the number of trailing zeros in the binary representation.
fn trailing_zeros(self) -> u32;
/// Integer base-2 logarithm, rounded down.
///
/// # Panics
///
/// Panics if the fixed-point number is ≤ 0.
fn int_log2(self) -> i32;
/// Integer base-10 logarithm, rounded down.
///
/// # Panics
///
/// Panics if the fixed-point number is ≤ 0.
fn int_log10(self) -> i32;
/// Checked integer base-2 logarithm, rounded down. Returns the
/// logarithm or [`None`] if the fixed-point number is ≤ 0.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
fn checked_int_log2(self) -> Option<i32>;
/// Checked integer base-10 logarithm, rounded down. Returns the
/// logarithm or [`None`] if the fixed-point number is ≤ 0.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
fn checked_int_log10(self) -> Option<i32>;
/// Shifts to the left by `n` bits, wrapping the truncated bits to the right end.
fn rotate_left(self, n: u32) -> Self;
/// Shifts to the right by `n` bits, wrapping the truncated bits to the left end.
fn rotate_right(self, n: u32) -> Self;
/// Euclidean division by an integer.
///
/// # Panics
///
/// Panics if the divisor is zero or if the division results in overflow.
fn div_euclid(self, rhs: Self) -> Self;
/// Remainder for Euclidean division.
///
/// # Panics
///
/// Panics if the divisor is zero.
fn rem_euclid(self, rhs: Self) -> Self;
/// Euclidean division by an integer.
///
/// # Panics
///
/// Panics if the divisor is zero or if the division results in overflow.
fn div_euclid_int(self, rhs: Self::Bits) -> Self;
/// Remainder for Euclidean division by an integer.
///
/// # Panics
///
/// Panics if the divisor is zero or if the division results in overflow.
fn rem_euclid_int(self, rhs: Self::Bits) -> Self;
/// Checked negation. Returns the negated value, or [`None`] on overflow.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
fn checked_neg(self) -> Option<Self>;
/// Checked addition. Returns the sum, or [`None`] on overflow.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
fn checked_add(self, rhs: Self) -> Option<Self>;
/// Checked subtraction. Returns the difference, or [`None`] on overflow.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
fn checked_sub(self, rhs: Self) -> Option<Self>;
/// Checked multiplication. Returns the product, or [`None`] on overflow.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
fn checked_mul(self, rhs: Self) -> Option<Self>;
/// Checked division. Returns the quotient, or [`None`] if the
/// divisor is zero or on overflow.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
fn checked_div(self, rhs: Self) -> Option<Self>;
/// Checked remainder. Returns the remainder, or [`None`] if the
/// divisor is zero.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
fn checked_rem(self, rhs: Self) -> Option<Self>;
/// Checked remainder for Euclidean division. Returns the
/// remainder, or [`None`] if the divisor is zero or the division
/// results in overflow.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
fn checked_div_euclid(self, rhs: Self) -> Option<Self>;
/// Checked remainder for Euclidean division. Returns the
/// remainder, or [`None`] if the divisor is zero.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
fn checked_rem_euclid(self, rhs: Self) -> Option<Self>;
/// Checked multiplication by an integer. Returns the product, or
/// [`None`] on overflow.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
fn checked_mul_int(self, rhs: Self::Bits) -> Option<Self>;
/// Checked division by an integer. Returns the quotient, or
/// [`None`] if the divisor is zero or if the division results in
/// overflow.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
fn checked_div_int(self, rhs: Self::Bits) -> Option<Self>;
/// Checked fixed-point remainder for division by an integer.
/// Returns the remainder, or [`None`] if the divisor is zero or
/// if the division results in overflow.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
fn checked_rem_int(self, rhs: Self::Bits) -> Option<Self>;
/// Checked Euclidean division by an integer. Returns the
/// quotient, or [`None`] if the divisor is zero or if the
/// division results in overflow.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
fn checked_div_euclid_int(self, rhs: Self::Bits) -> Option<Self>;
/// Checked remainder for Euclidean division by an integer.
/// Returns the remainder, or [`None`] if the divisor is zero or
/// if the remainder results in overflow.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
fn checked_rem_euclid_int(self, rhs: Self::Bits) -> Option<Self>;
/// Checked shift left. Returns the shifted number, or [`None`] if
/// `rhs` ≥ the number of bits.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
fn checked_shl(self, rhs: u32) -> Option<Self>;
/// Checked shift right. Returns the shifted number, or [`None`]
/// if `rhs` ≥ the number of bits.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
fn checked_shr(self, rhs: u32) -> Option<Self>;
/// Saturated negation. Returns the negated value, saturating on overflow.
fn saturating_neg(self) -> Self;
/// Saturating addition. Returns the sum, saturating on overflow.
fn saturating_add(self, rhs: Self) -> Self;
/// Saturating subtraction. Returns the difference, saturating on overflow.
fn saturating_sub(self, rhs: Self) -> Self;
/// Saturating multiplication. Returns the product, saturating on overflow.
fn saturating_mul(self, rhs: Self) -> Self;
/// Saturating division. Returns the quotient, saturating on overflow.
///
/// # Panics
///
/// Panics if the divisor is zero.
fn saturating_div(self, rhs: Self) -> Self;
/// Saturating Euclidean division. Returns the quotient, saturating on overflow.
///
/// # Panics
///
/// Panics if the divisor is zero.
fn saturating_div_euclid(self, rhs: Self) -> Self;
/// Saturating multiplication by an integer. Returns the product, saturating on overflow.
fn saturating_mul_int(self, rhs: Self::Bits) -> Self;
/// Wrapping negation. Returns the negated value, wrapping on overflow.
fn wrapping_neg(self) -> Self;
/// Wrapping addition. Returns the sum, wrapping on overflow.
fn wrapping_add(self, rhs: Self) -> Self;
/// Wrapping subtraction. Returns the difference, wrapping on overflow.
fn wrapping_sub(self, rhs: Self) -> Self;
/// Wrapping multiplication. Returns the product, wrapping on overflow.
fn wrapping_mul(self, rhs: Self) -> Self;
/// Wrapping division. Returns the quotient, wrapping on overflow.
///
/// # Panics
///
/// Panics if the divisor is zero.
fn wrapping_div(self, rhs: Self) -> Self;
/// Wrapping Euclidean division. Returns the quotient, wrapping on overflow.
///
/// # Panics
///
/// Panics if the divisor is zero.
fn wrapping_div_euclid(self, rhs: Self) -> Self;
/// Wrapping multiplication by an integer. Returns the product, wrapping on overflow.
fn wrapping_mul_int(self, rhs: Self::Bits) -> Self;
/// Wrapping division by an integer. Returns the quotient, wrapping on overflow.
///
/// Overflow can only occur when dividing the minimum value by −1.
///
/// # Panics
///
/// Panics if the divisor is zero.
fn wrapping_div_int(self, rhs: Self::Bits) -> Self;
/// Wrapping Euclidean division by an integer. Returns the
/// quotient, wrapping on overflow.
///
/// Overflow can only occur when dividing the minimum value by −1.
///
/// # Panics
///
/// Panics if the divisor is zero.
fn wrapping_div_euclid_int(self, rhs: Self::Bits) -> Self;
/// Wrapping remainder for Euclidean division by an integer.
/// Returns the remainder, wrapping on overflow.
///
/// # Panics
///
/// Panics if the divisor is zero.
fn wrapping_rem_euclid_int(self, rhs: Self::Bits) -> Self;
/// Wrapping shift left. Wraps `rhs` if `rhs` ≥ the number of
/// bits, then shifts and returns the number.
fn wrapping_shl(self, rhs: u32) -> Self;
/// Wrapping shift right. Wraps `rhs` if `rhs` ≥ the number of
/// bits, then shifts and returns the number.
fn wrapping_shr(self, rhs: u32) -> Self;
/// Overflowing negation.
///
/// Returns a [tuple] of the negated value and a [`bool`],
/// indicating whether an overflow has occurred. On overflow, the
/// wrapped value is returned.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
fn overflowing_neg(self) -> (Self, bool);
/// Overflowing addition.
///
/// Returns a [tuple] of the sum and a [`bool`], indicating whether
/// an overflow has occurred. On overflow, the wrapped value is
/// returned.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
fn overflowing_add(self, rhs: Self) -> (Self, bool);
/// Overflowing subtraction.
///
/// Returns a [tuple] of the difference and a [`bool`], indicating
/// whether an overflow has occurred. On overflow, the wrapped
/// value is returned.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
fn overflowing_sub(self, rhs: Self) -> (Self, bool);
/// Overflowing multiplication.
///
/// Returns a [tuple] of the product and a [`bool`], indicating
/// whether an overflow has occurred. On overflow, the wrapped
/// value is returned.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
fn overflowing_mul(self, rhs: Self) -> (Self, bool);
/// Overflowing division.
///
/// Returns a [tuple] of the quotient and a [`bool`], indicating
/// whether an overflow has occurred. On overflow, the wrapped
/// value is returned.
///
/// # Panics
///
/// Panics if the divisor is zero.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
fn overflowing_div(self, rhs: Self) -> (Self, bool);
/// Overflowing Euclidean division.
///
/// Returns a [tuple] of the quotient and a [`bool`], indicating
/// whether an overflow has occurred. On overflow, the wrapped
/// value is returned.
///
/// # Panics
///
/// Panics if the divisor is zero.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool);
/// Overflowing multiplication by an integer.
///
/// Returns a [tuple] of the product and a [`bool`], indicating
/// whether an overflow has occurred. On overflow, the wrapped
/// value is returned.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
fn overflowing_mul_int(self, rhs: Self::Bits) -> (Self, bool);
/// Overflowing division by an integer.
///
/// Returns a [tuple] of the quotient and a [`bool`], indicating
/// whether an overflow has occurred. On overflow, the wrapped
/// value is returned.
///
/// # Panics
///
/// Panics if the divisor is zero.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
fn overflowing_div_int(self, rhs: Self::Bits) -> (Self, bool);
/// Overflowing Euclidean division by an integer.
///
/// Returns a [tuple] of the quotient and a [`bool`], indicating
/// whether an overflow has occurred. On overflow, the wrapped
/// value is returned.
///
/// # Panics
///
/// Panics if the divisor is zero.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
fn overflowing_div_euclid_int(self, rhs: Self::Bits) -> (Self, bool);
/// Overflowing remainder for Euclidean division by an integer.
///
/// Returns a [tuple] of the remainder and a [`bool`], indicating
/// whether an overflow has occurred. On overflow, the wrapped
/// value is returned.
///
/// # Panics
///
/// Panics if the divisor is zero.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
fn overflowing_rem_euclid_int(self, rhs: Self::Bits) -> (Self, bool);
/// Overflowing shift left.
///
/// Returns a [tuple] of the shifted value and a [`bool`],
/// indicating whether an overflow has occurred. On overflow, the
/// wrapped value is returned.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
fn overflowing_shl(self, rhs: u32) -> (Self, bool);
/// Overflowing shift right.
///
/// Returns a [tuple] of the shifted value and a [`bool`],
/// indicating whether an overflow has occurred. On overflow, the
/// wrapped value is returned.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
fn overflowing_shr(self, rhs: u32) -> (Self, bool);
}
/// This trait provides methods common to all signed fixed-point numbers.
///
/// Methods common to all fixed-point numbers including unsigned
/// fixed-point numbers are provided by the [`Fixed`] supertrait.
///
/// This trait is sealed and cannot be implemented for more types; it
/// is implemented for [`FixedI8`], [`FixedI16`], [`FixedI32`],
/// [`FixedI64`], and [`FixedI128`].
///
/// [`FixedI128`]: ../struct.FixedI128.html
/// [`FixedI16`]: ../struct.FixedI16.html
/// [`FixedI32`]: ../struct.FixedI32.html
/// [`FixedI64`]: ../struct.FixedI64.html
/// [`FixedI8`]: ../struct.FixedI8.html
/// [`Fixed`]: trait.Fixed.html
pub trait FixedSigned: Fixed + Neg<Output = Self> {
/// Returns [`true`] if the number is > 0.
///
/// [`true`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
fn is_positive(self) -> bool;
/// Returns [`true`] if the number is < 0.
///
/// [`true`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
fn is_negative(self) -> bool;
/// Returns the absolute value.
fn abs(self) -> Self;
/// Returns a number representing the sign of `self`.
///
/// # Panics
///
/// When debug assertions are enabled, this method panics
/// * if the value is positive and the fixed-point number has
/// zero or one integer bits such that it cannot hold the
/// value 1.
/// * if the value is negative and the fixed-point number has
/// zero integer bits, such that it cannot hold the value −1.
///
/// When debug assertions are not enabled, the wrapped value can
/// be returned in those cases, but it is not considered a
/// breaking change if in the future it panics; using this method
/// when 1 and −1 cannot be represented is almost certainly a bug.
fn signum(self) -> Self;
/// Checked absolute value. Returns the absolute value, or [`None`] on overflow.
///
/// Overflow can only occur when trying to find the absolute value of the minimum value.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
fn checked_abs(self) -> Option<Self>;
/// Checked signum. Returns a number representing the sign of
/// `self`, or [`None`] on overflow.
///
/// Overflow can only occur
/// * if the value is positive and the fixed-point number has zero
/// or one integer bits such that it cannot hold the value 1.
/// * if the value is negative and the fixed-point number has zero
/// integer bits, such that it cannot hold the value −1.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
fn checked_signum(self) -> Option<Self>;
/// Saturating absolute value. Returns the absolute value, saturating on overflow.
///
/// Overflow can only occur when trying to find the absolute value of the minimum value.
fn saturating_abs(self) -> Self;
/// Saturating signum. Returns a number representing the sign of
/// `self`, saturating on overflow.
///
/// Overflow can only occur
/// * if the value is positive and the fixed-point number has zero
/// or one integer bits such that it cannot hold the value 1.
/// * if the value is negative and the fixed-point number has zero
/// integer bits, such that it cannot hold the value −1.
fn saturating_signum(self) -> Self;
/// Wrapping absolute value. Returns the absolute value, wrapping on overflow.
///
/// Overflow can only occur when trying to find the absolute value of the minimum value.
fn wrapping_abs(self) -> Self;
/// Wrapping signum. Returns a number representing the sign of
/// `self`, wrapping on overflow.
///
/// Overflow can only occur
/// * if the value is positive and the fixed-point number has zero
/// or one integer bits such that it cannot hold the value 1.
/// * if the value is negative and the fixed-point number has zero
/// integer bits, such that it cannot hold the value −1.
fn wrapping_signum(self) -> Self;
/// Overflowing absolute value.
///
/// Returns a [tuple] of the fixed-point number and a [`bool`],
/// indicating whether an overflow has occurred. On overflow, the
/// wrapped value is returned.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
fn overflowing_abs(self) -> (Self, bool);
/// Overflowing signum.
///
/// Returns a [tuple] of the signum and a [`bool`], indicating
/// whether an overflow has occurred. On overflow, the wrapped
/// value is returned.
///
/// Overflow can only occur
/// * if the value is positive and the fixed-point number has zero
/// or one integer bits such that it cannot hold the value 1.
/// * if the value is negative and the fixed-point number has zero
/// integer bits, such that it cannot hold the value −1.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
fn overflowing_signum(self) -> (Self, bool);
}
/// This trait provides methods common to all unsigned fixed-point numbers.
///
/// Methods common to all fixed-point numbers including signed
/// fixed-point numbers are provided by the [`Fixed`] supertrait.
///
/// This trait is sealed and cannot be implemented for more types; it
/// is implemented for [`FixedU8`], [`FixedU16`], [`FixedU32`],
/// [`FixedU64`], and [`FixedU128`].
///
/// [`FixedU128`]: ../struct.FixedU128.html
/// [`FixedU16`]: ../struct.FixedU16.html
/// [`FixedU32`]: ../struct.FixedU32.html
/// [`FixedU64`]: ../struct.FixedU64.html
/// [`FixedU8`]: ../struct.FixedU8.html
/// [`Fixed`]: trait.Fixed.html
pub trait FixedUnsigned: Fixed {
/// Returns [`true`] if the fixed-point number is
/// 2<sup><i>k</i></sup> for some integer <i>k</i>.
///
/// [`true`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
fn is_power_of_two(self) -> bool;
/// Returns the smallest power of two that is ≥ `self`.
fn next_power_of_two(self) -> Self;
/// Returns the smallest power of two that is ≥ `self`, or [`None`] if the
/// next power of two is too large to represent.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
fn checked_next_power_of_two(self) -> Option<Self>;
/// Returns the smallest power of two that is ≥ `self`, wrapping
/// to 0 if the next power of two is too large to represent.
fn wrapping_next_power_of_two(self) -> Self;
}
/// This trait provides lossless conversions that might be fallible.
///
/// This trait is implemented for conversions between integer
/// primitives, floating-point primitives and fixed-point numbers.
///
/// # Examples
///
/// ```rust
/// use fixed::traits::LosslessTryFrom;
/// use fixed::types::{I24F8, I4F12};
/// // original is 0x000001.23, lossless is 0x1.230
/// let original = I24F8::from_bits(0x0000_0123);
/// let lossless = I4F12::lossless_try_from(original);
/// assert_eq!(lossless, Some(I4F12::from_bits(0x1230)));
/// // too_large is 0x000012.34, 0x12.340 does not fit in I4F12
/// let too_large = I24F8::from_bits(0x0000_1234);
/// let overflow = I4F12::lossless_try_from(too_large);
/// assert_eq!(overflow, None);
/// ```
pub trait LosslessTryFrom<Src>: Sized {
/// Performs the conversion.
fn lossless_try_from(src: Src) -> Option<Self>;
}
/// This trait provides lossless conversions that might be fallible.
/// This is the reciprocal of [`LosslessTryFrom`].
///
/// Usually [`LosslessTryFrom`] should be implemented instead of this
/// trait; there is a blanket implementation which provides this trait
/// when [`LosslessTryFrom`] is implemented (similar to [`Into`] and
/// [`From`]).
///
/// # Examples
///
/// ```rust
/// use fixed::traits::LosslessTryInto;
/// use fixed::types::{I24F8, I4F12};
/// // original is 0x000001.23, lossless is 0x1.230
/// let original = I24F8::from_bits(0x0000_0123);
/// let lossless: Option<I4F12> = original.lossless_try_into();
/// assert_eq!(lossless, Some(I4F12::from_bits(0x1230)));
/// // too_large is 0x000012.34, 0x12.340 does not fit in I4F12
/// let too_large = I24F8::from_bits(0x0000_1234);
/// let overflow: Option<I4F12> = too_large.lossless_try_into();
/// assert_eq!(overflow, None);
/// ```
///
/// [`From`]: https://doc.rust-lang.org/nightly/core/convert/trait.From.html
/// [`Into`]: https://doc.rust-lang.org/nightly/core/convert/trait.Into.html
/// [`LosslessTryFrom`]: trait.LosslessTryFrom.html
pub trait LosslessTryInto<Dst> {
/// Performs the conversion.
fn lossless_try_into(self) -> Option<Dst>;
}
impl<Src, Dst> LosslessTryInto<Dst> for Src
where
Dst: LosslessTryFrom<Src>,
{
fn lossless_try_into(self) -> Option<Dst> {
Dst::lossless_try_from(self)
}
}
/// This trait provides infallible conversions that might be lossy.
///
/// This trait is implemented for conversions between integer
/// primitives, floating-point primitives and fixed-point numbers.
///
/// # Examples
///
/// ```rust
/// use fixed::traits::LossyFrom;
/// use fixed::types::{I12F4, I8F24};
/// // original is 0x12.345678, lossy is 0x012.3
/// let original = I8F24::from_bits(0x1234_5678);
/// let lossy = I12F4::lossy_from(original);
/// assert_eq!(lossy, I12F4::from_bits(0x0123));
/// ```
pub trait LossyFrom<Src> {
/// Performs the conversion.
fn lossy_from(src: Src) -> Self;
}
/// This trait provides infallible conversions that might be lossy.
/// This is the reciprocal of [`LossyFrom`].
///
/// Usually [`LossyFrom`] should be implemented instead of this trait;
/// there is a blanket implementation which provides this trait when
/// [`LossyFrom`] is implemented (similar to [`Into`] and [`From`]).
///
/// # Examples
///
/// ```rust
/// use fixed::traits::LossyInto;
/// use fixed::types::{I12F4, I8F24};
/// // original is 0x12.345678, lossy is 0x012.3
/// let original = I8F24::from_bits(0x1234_5678);
/// let lossy: I12F4 = original.lossy_into();
/// assert_eq!(lossy, I12F4::from_bits(0x0123));
/// ```
///
/// [`From`]: https://doc.rust-lang.org/nightly/core/convert/trait.From.html
/// [`Into`]: https://doc.rust-lang.org/nightly/core/convert/trait.Into.html
/// [`LossyFrom`]: trait.LossyFrom.html
pub trait LossyInto<Dst> {
/// Performs the conversion.
fn lossy_into(self) -> Dst;
}
impl<Src, Dst> LossyInto<Dst> for Src
where
Dst: LossyFrom<Src>,
{
fn lossy_into(self) -> Dst {
Dst::lossy_from(self)
}
}
/// This trait provides checked conversions from fixed-point numbers.
///
/// This trait is implemented for conversions between integer
/// primitives, floating-point primitives and fixed-point numbers.
///
/// # Examples
///
/// ```rust
/// use fixed::traits::FromFixed;
/// use fixed::types::U8F8;
/// // 0x87.65
/// let f = U8F8::from_bits(0x8765);
/// assert_eq!(f32::from_fixed(f), f32::from(0x8765u16) / 256.0);
/// assert_eq!(i32::checked_from_fixed(f), Some(0x87));
/// assert_eq!(u8::saturating_from_fixed(f), 0x87);
/// // no fit
/// assert_eq!(i8::checked_from_fixed(f), None);
/// assert_eq!(i8::saturating_from_fixed(f), i8::MAX);
/// assert_eq!(i8::wrapping_from_fixed(f), 0x87u8 as i8);
/// assert_eq!(i8::overflowing_from_fixed(f), (0x87u8 as i8, true));
/// ```
pub trait FromFixed {
/// Converts from a fixed-point number.
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
///
/// # Panics
///
/// When debug assertions are enabled, panics if the value does
/// not fit. When debug assertions are not enabled, the wrapped
/// value can be returned, but it is not considered a breaking
/// change if in the future it panics; if wrapping is required use
/// [`wrapping_from_fixed`] instead.
///
/// [`wrapping_from_fixed`]: #method.wrapping_from_fixed
fn from_fixed<F: Fixed>(src: F) -> Self;
/// Converts from a fixed-point number if it fits, otherwise returns [`None`].
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
fn checked_from_fixed<F: Fixed>(src: F) -> Option<Self>
where
Self: Sized;
/// Converts from a fixed-point number, saturating if it does not fit.
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
fn saturating_from_fixed<F: Fixed>(src: F) -> Self;
/// Converts from a fixed-point number, wrapping if it does not fit.
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
fn wrapping_from_fixed<F: Fixed>(src: F) -> Self;
/// Converts from a fixed-point number.
///
/// Returns a [tuple] of the value and a [`bool`] indicating whether
/// an overflow has occurred. On overflow, the wrapped value is
/// returned.
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
fn overflowing_from_fixed<F: Fixed>(src: F) -> (Self, bool)
where
Self: Sized;
}
/// This trait provides checked conversions to fixed-point numbers.
///
/// This trait is implemented for conversions between integer
/// primitives, floating-point primitives and fixed-point numbers.
///
/// # Examples
///
/// ```rust
/// use fixed::traits::ToFixed;
/// use fixed::types::{U8F8, U16F16};
/// let f: U8F8 = 13.5f32.to_fixed();
/// assert_eq!(f, U8F8::from_bits((13 << 8) | (1 << 7)));
/// // 0x1234.5678 is too large and can be wrapped to 0x34.56
/// let too_large = U16F16::from_bits(0x1234_5678);
/// let checked: Option<U8F8> = too_large.checked_to_num();
/// assert_eq!(checked, None);
/// let saturating: U8F8 = too_large.saturating_to_num();
/// assert_eq!(saturating, U8F8::MAX);
/// let wrapping: U8F8 = too_large.wrapping_to_num();
/// assert_eq!(wrapping, U8F8::from_bits(0x3456));
/// let overflowing: (U8F8, bool) = too_large.overflowing_to_num();
/// assert_eq!(overflowing, (U8F8::from_bits(0x3456), true));
/// ```
pub trait ToFixed {
/// Converts to a fixed-point number.
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
///
/// # Panics
///
/// Panics if `self` is a floating-point number that is not [finite].
///
/// When debug assertions are enabled, also panics if the value
/// does not fit. When debug assertions are not enabled, the
/// wrapped value can be returned, but it is not considered a
/// breaking change if in the future it panics; if wrapping is
/// required use [`wrapping_to_fixed`] instead.
///
/// [`wrapping_to_fixed`]: #method.wrapping_to_fixed
/// [finite]: https://doc.rust-lang.org/nightly/std/primitive.f64.html#method.is_finite
fn to_fixed<F: Fixed>(self) -> F;
/// Converts to a fixed-point number if it fits, otherwise returns [`None`].
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
fn checked_to_fixed<F: Fixed>(self) -> Option<F>;
/// Converts to a fixed-point number, saturating if it does not fit.
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
///
/// # Panics
///
/// Panics if `self` is a floating-point number that is [NaN].
///
/// [NaN]: https://doc.rust-lang.org/nightly/std/primitive.f64.html#method.is_nan
fn saturating_to_fixed<F: Fixed>(self) -> F;
/// Converts to a fixed-point number, wrapping if it does not fit.
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
///
/// # Panics
///
/// Panics if `self` is a floating-point number that is not [finite].
///
/// [finite]: https://doc.rust-lang.org/nightly/std/primitive.f64.html#method.is_finite
fn wrapping_to_fixed<F: Fixed>(self) -> F;
/// Converts to a fixed-point number.
///
/// Returns a [tuple] of the fixed-point number and a [`bool`]
/// indicating whether an overflow has occurred. On overflow, the
/// wrapped value is returned.
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
///
/// # Panics
///
/// Panics if `self` is a floating-point number that is not [finite].
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [finite]: https://doc.rust-lang.org/nightly/std/primitive.f64.html#method.is_finite
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
fn overflowing_to_fixed<F: Fixed>(self) -> (F, bool);
}
impl ToFixed for bool {
/// Converts a [`bool`] to a fixed-point number.
///
/// # Panics
///
/// When debug assertions are enabled, panics if the value does
/// not fit. When debug assertions are not enabled, the wrapped
/// value can be returned, but it is not considered a breaking
/// change if in the future it panics; if wrapping is required use
/// [`wrapping_to_fixed`] instead.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [`wrapping_to_fixed`]: #method.wrapping_to_fixed
#[inline]
fn to_fixed<F: Fixed>(self) -> F {
ToFixed::to_fixed(self as u8)
}
/// Converts a [`bool`] to a fixed-point number if it fits, otherwise returns [`None`].
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
#[inline]
fn checked_to_fixed<F: Fixed>(self) -> Option<F> {
ToFixed::checked_to_fixed(self as u8)
}
/// Convert a [`bool`] to a fixed-point number, saturating if it does not fit.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
#[inline]
fn saturating_to_fixed<F: Fixed>(self) -> F {
ToFixed::saturating_to_fixed(self as u8)
}
/// Converts a [`bool`] to a fixed-point number, wrapping if it does not fit.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
#[inline]
fn wrapping_to_fixed<F: Fixed>(self) -> F {
ToFixed::wrapping_to_fixed(self as u8)
}
/// Converts a [`bool`] to a fixed-point number.
///
/// Returns a [tuple] of the fixed-point number and a [`bool`]
/// indicating whether an overflow has occurred. On overflow, the
/// wrapped value is returned.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
#[inline]
fn overflowing_to_fixed<F: Fixed>(self) -> (F, bool) {
ToFixed::overflowing_to_fixed(self as u8)
}
}
macro_rules! impl_int {
($Int:ident) => {
impl FromFixed for $Int {
/// Converts a fixed-point number to an integer.
///
/// Any fractional bits are discarded, which rounds towards −∞.
///
/// # Panics
///
/// When debug assertions are enabled, panics if the value
/// does not fit. When debug assertions are not enabled,
/// the wrapped value can be returned, but it is not
/// considered a breaking change if in the future it
/// panics; if wrapping is required use
/// [`wrapping_from_fixed`] instead.
///
/// [`wrapping_from_fixed`]: #method.wrapping_from_fixed
#[inline]
fn from_fixed<F: Fixed>(src: F) -> Self {
$Int::from_repr_fixed(FromFixed::from_fixed(src))
}
/// Converts a fixed-point number to an integer if it fits, otherwise returns [`None`].
///
/// Any fractional bits are discarded, which rounds towards −∞.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
#[inline]
fn checked_from_fixed<F: Fixed>(src: F) -> Option<Self> {
FromFixed::checked_from_fixed(src).map($Int::from_repr_fixed)
}
/// Converts a fixed-point number to an integer, saturating if it does not fit.
///
/// Any fractional bits are discarded, which rounds towards −∞.
#[inline]
fn saturating_from_fixed<F: Fixed>(src: F) -> Self {
$Int::from_repr_fixed(FromFixed::saturating_from_fixed(src))
}
/// Converts a fixed-point number to an integer, wrapping if it does not fit.
///
/// Any fractional bits are discarded, which rounds towards −∞.
#[inline]
fn wrapping_from_fixed<F: Fixed>(src: F) -> Self {
$Int::from_repr_fixed(FromFixed::wrapping_from_fixed(src))
}
/// Converts a fixed-point number to an integer.
///
/// Returns a [tuple] of the value and a [`bool`] indicating whether
/// an overflow has occurred. On overflow, the wrapped value is
/// returned.
///
/// Any fractional bits are discarded, which rounds towards −∞.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
#[inline]
fn overflowing_from_fixed<F: Fixed>(src: F) -> (Self, bool) {
let (repr_fixed, overflow) = FromFixed::overflowing_from_fixed(src);
($Int::from_repr_fixed(repr_fixed), overflow)
}
}
impl ToFixed for $Int {
/// Converts an integer to a fixed-point number.
///
/// # Panics
///
/// When debug assertions are enabled, panics if the value
/// does not fit. When debug assertions are not enabled,
/// the wrapped value can be returned, but it is not
/// considered a breaking change if in the future it
/// panics; if wrapping is required use
/// [`wrapping_to_fixed`] instead.
///
/// [`wrapping_to_fixed`]: #method.wrapping_to_fixed
#[inline]
fn to_fixed<F: Fixed>(self) -> F {
ToFixed::to_fixed(self.to_repr_fixed())
}
/// Converts an integer to a fixed-point number if it fits, otherwise returns [`None`].
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
#[inline]
fn checked_to_fixed<F: Fixed>(self) -> Option<F> {
ToFixed::checked_to_fixed(self.to_repr_fixed())
}
/// Converts an integer to a fixed-point number, saturating if it does not fit.
#[inline]
fn saturating_to_fixed<F: Fixed>(self) -> F {
ToFixed::saturating_to_fixed(self.to_repr_fixed())
}
/// Converts an integer to a fixed-point number, wrapping if it does not fit.
#[inline]
fn wrapping_to_fixed<F: Fixed>(self) -> F {
ToFixed::wrapping_to_fixed(self.to_repr_fixed())
}
/// Converts an integer to a fixed-point number.
///
/// Returns a [tuple] of the fixed-point number and a [`bool`]
/// indicating whether an overflow has occurred. On overflow, the
/// wrapped value is returned.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
#[inline]
fn overflowing_to_fixed<F: Fixed>(self) -> (F, bool) {
ToFixed::overflowing_to_fixed(self.to_repr_fixed())
}
}
};
}
impl_int! { i8 }
impl_int! { i16 }
impl_int! { i32 }
impl_int! { i64 }
impl_int! { i128 }
impl_int! { isize }
impl_int! { u8 }
impl_int! { u16 }
impl_int! { u32 }
impl_int! { u64 }
impl_int! { u128 }
impl_int! { usize }
macro_rules! impl_float {
($Float:ty, $link:expr) => {
impl FromFixed for $Float {
/// Converts a fixed-point number to a floating-point number.
///
/// Rounding is to the nearest, with ties rounded to even.
///
/// # Panics
///
/// When debug assertions are enabled, panics if the value
/// does not fit. When debug assertions are not enabled,
/// the wrapped value can be returned, but it is not
/// considered a breaking change if in the future it
/// panics; if wrapping is required use
/// [`wrapping_from_fixed`] instead.
///
/// [`wrapping_from_fixed`]: #method.wrapping_from_fixed
#[inline]
fn from_fixed<F: Fixed>(src: F) -> Self {
let helper = src.private_to_float_helper();
FloatHelper::from_to_float_helper(helper, F::FRAC_NBITS, F::INT_NBITS)
}
/// Converts a fixed-point number to a floating-point
/// number if it fits, otherwise returns [`None`].
///
/// Rounding is to the nearest, with ties rounded to even.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
#[inline]
fn checked_from_fixed<F: Fixed>(src: F) -> Option<Self> {
Some(FromFixed::from_fixed(src))
}
/// Converts a fixed-point number to a floating-point
/// number, saturating if it does not fit.
///
/// Rounding is to the nearest, with ties rounded to even.
#[inline]
fn saturating_from_fixed<F: Fixed>(src: F) -> Self {
FromFixed::from_fixed(src)
}
/// Converts a fixed-point number to a floating-point
/// number, wrapping if it does not fit.
///
/// Rounding is to the nearest, with ties rounded to even.
#[inline]
fn wrapping_from_fixed<F: Fixed>(src: F) -> Self {
FromFixed::from_fixed(src)
}
/// Converts a fixed-point number to a floating-point number.
///
/// Returns a [tuple] of the value and a [`bool`]
/// indicating whether an overflow has occurred. On
/// overflow, the wrapped value is returned.
///
/// Rounding is to the nearest, with ties rounded to even.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
#[inline]
fn overflowing_from_fixed<F: Fixed>(src: F) -> (Self, bool) {
(FromFixed::from_fixed(src), false)
}
}
impl ToFixed for $Float {
comment! {
"Converts a floating-point number to a fixed-point number.
Rounding is to the nearest, with ties rounded to even.
# Panics
Panics if `self` is not [finite].
When debug assertions are enabled, also panics if the value does not
fit. When debug assertions are not enabled, the wrapped value can be
returned, but it is not considered a breaking change if in the future
it panics; if wrapping is required use [`wrapping_to_fixed`] instead.
[`wrapping_to_fixed`]: #method.wrapping_to_fixed
[finite]: ", $link, "#method.is_finite
";
#[inline]
fn to_fixed<F: Fixed>(self) -> F {
let (wrapped, overflow) = ToFixed::overflowing_to_fixed(self);
debug_assert!(!overflow, "{} overflows", self);
let _ = overflow;
wrapped
}
}
/// Converts a floating-point number to a fixed-point
/// number if it fits, otherwise returns [`None`].
///
/// Rounding is to the nearest, with ties rounded to even.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
#[inline]
fn checked_to_fixed<F: Fixed>(self) -> Option<F> {
let kind = self.to_float_kind(F::FRAC_NBITS, F::INT_NBITS);
match kind {
FloatKind::Finite { .. } => {
let helper = FromFloatHelper { kind };
match F::private_overflowing_from_float_helper(helper) {
(_, true) => None,
(wrapped, false) => Some(wrapped),
}
}
_ => None,
}
}
comment! {
"Converts a floating-point number to a fixed-point
number, saturating if it does not fit.
Rounding is to the nearest, with ties rounded to even.
# Panics
Panics if `self` is [NaN].
[NaN]: ", $link, "#method.is_nan
";
#[inline]
fn saturating_to_fixed<F: Fixed>(self) -> F {
let kind = self.to_float_kind(F::FRAC_NBITS, F::INT_NBITS);
let helper = FromFloatHelper { kind };
F::private_saturating_from_float_helper(helper)
}
}
comment! {
"Converts a floating-point number to a fixed-point
number, wrapping if it does not fit.
Rounding is to the nearest, with ties rounded to even.
# Panics
Panics if `self` is not [finite].
[finite]: ", $link, "#method.is_finite
";
#[inline]
fn wrapping_to_fixed<F: Fixed>(self) -> F {
let (wrapped, _) = ToFixed::overflowing_to_fixed(self);
wrapped
}
}
comment! {
"Converts a floating-point number to a fixed-point number.
Returns a [tuple] of the fixed-point number and a [`bool`] indicating
whether an overflow has occurred. On overflow, the wrapped value is
returned.
Rounding is to the nearest, with ties rounded to even.
# Panics
Panics if `self` is not [finite].
[`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
[finite]: ", $link, "#method.is_finite
[tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
";
#[inline]
fn overflowing_to_fixed<F: Fixed>(self) -> (F, bool) {
let kind = self.to_float_kind(F::FRAC_NBITS, F::INT_NBITS);
let helper = FromFloatHelper { kind };
F::private_overflowing_from_float_helper(helper)
}
}
}
};
}
#[cfg(feature = "f16")]
impl_float! { f16, "https://docs.rs/half/^1/half/struct.f16.html" }
#[cfg(feature = "f16")]
impl_float! { bf16, "https://docs.rs/half/^1/half/struct.bf16.html" }
impl_float! { f32, "https://doc.rust-lang.org/nightly/std/primitive.f32.html" }
impl_float! { f64, "https://doc.rust-lang.org/nightly/std/primitive.f64.html" }
macro_rules! trait_delegate {
(fn $method:ident($($param:ident: $Param:ty),*) -> $Ret:ty) => {
#[inline]
fn $method($($param: $Param),*) -> $Ret {
Self::$method($($param),*)
}
};
(fn $method:ident(self $(, $param:ident: $Param:ty)*) -> $Ret:ty) => {
#[inline]
fn $method(self $(, $param: $Param)*) -> $Ret {
self.$method($($param),*)
}
};
(fn $method:ident<$Gen:ident: $Trait:ident>($($param:ident: $Param:ty),*) -> $Ret:ty) => {
#[inline]
fn $method<$Gen: $Trait>($($param: $Param),*) -> $Ret {
Self::$method($($param),*)
}
};
(fn $method:ident<$Gen:ident: $Trait:ident>(self $(, $param:ident: $Param:ty)*) -> $Ret:ty) => {
#[inline]
fn $method<$Gen: $Trait>(self $(, $param: $Param)*) -> $Ret {
self.$method($($param),*)
}
};
}
macro_rules! impl_fixed {
($Fixed:ident, $LeEqU:ident, $Bits:ident, $Signedness:tt) => {
impl<Frac: $LeEqU> FixedOptionalFeatures for $Fixed<Frac> {}
impl<Frac: $LeEqU> Fixed for $Fixed<Frac> {
type Bits = $Bits;
type Bytes = [u8; mem::size_of::<$Bits>()];
type Frac = Frac;
const MIN: Self = Self::MIN;
const MAX: Self = Self::MAX;
const INT_NBITS: u32 = Self::INT_NBITS;
const FRAC_NBITS: u32 = Self::FRAC_NBITS;
trait_delegate! { fn from_bits(bits: Self::Bits) -> Self }
trait_delegate! { fn to_bits(self) -> Self::Bits }
trait_delegate! { fn from_be_bytes(bits: Self::Bytes) -> Self }
trait_delegate! { fn from_le_bytes(bits: Self::Bytes) -> Self }
trait_delegate! { fn from_ne_bytes(bits: Self::Bytes) -> Self }
trait_delegate! { fn to_be_bytes(self) -> Self::Bytes }
trait_delegate! { fn to_le_bytes(self) -> Self::Bytes }
trait_delegate! { fn to_ne_bytes(self) -> Self::Bytes }
trait_delegate! { fn from_num<Src: ToFixed>(src: Src) -> Self }
trait_delegate! { fn to_num<Dst: FromFixed>(self) -> Dst }
trait_delegate! { fn checked_from_num<Src: ToFixed>(val: Src) -> Option<Self> }
trait_delegate! { fn checked_to_num<Dst: FromFixed>(self) -> Option<Dst> }
trait_delegate! { fn saturating_from_num<Src: ToFixed>(val: Src) -> Self }
trait_delegate! { fn saturating_to_num<Dst: FromFixed>(self) -> Dst }
trait_delegate! { fn wrapping_from_num<Src: ToFixed>(val: Src) -> Self }
trait_delegate! { fn wrapping_to_num<Dst: FromFixed>(self) -> Dst }
trait_delegate! { fn overflowing_from_num<Src: ToFixed>(val: Src) -> (Self, bool) }
trait_delegate! { fn overflowing_to_num<Dst: FromFixed>(self) -> (Dst, bool) }
trait_delegate! { fn from_str_binary(src: &str) -> Result<Self, ParseFixedError> }
trait_delegate! { fn from_str_octal(src: &str) -> Result<Self, ParseFixedError> }
trait_delegate! { fn from_str_hex(src: &str) -> Result<Self, ParseFixedError> }
trait_delegate! {
fn saturating_from_str(src: &str) -> Result<Self, ParseFixedError>
}
trait_delegate! {
fn saturating_from_str_binary(src: &str) -> Result<Self, ParseFixedError>
}
trait_delegate! {
fn saturating_from_str_octal(src: &str) -> Result<Self, ParseFixedError>
}
trait_delegate! {
fn saturating_from_str_hex(src: &str) -> Result<Self, ParseFixedError>
}
trait_delegate! {
fn wrapping_from_str(src: &str) -> Result<Self, ParseFixedError>
}
trait_delegate! {
fn wrapping_from_str_binary(src: &str) -> Result<Self, ParseFixedError>
}
trait_delegate! {
fn wrapping_from_str_octal(src: &str) -> Result<Self, ParseFixedError>
}
trait_delegate! {
fn wrapping_from_str_hex(src: &str) -> Result<Self, ParseFixedError>
}
trait_delegate! {
fn overflowing_from_str(src: &str) -> Result<(Self, bool), ParseFixedError>
}
trait_delegate! {
fn overflowing_from_str_binary(src: &str) -> Result<(Self, bool), ParseFixedError>
}
trait_delegate! {
fn overflowing_from_str_octal(src: &str) -> Result<(Self, bool), ParseFixedError>
}
trait_delegate! {
fn overflowing_from_str_hex(src: &str) -> Result<(Self, bool), ParseFixedError>
}
trait_delegate! { fn int(self) -> Self }
trait_delegate! { fn frac(self) -> Self }
trait_delegate! { fn ceil(self) -> Self }
trait_delegate! { fn floor(self) -> Self }
trait_delegate! { fn round_to_zero(self) -> Self }
trait_delegate! { fn round(self) -> Self }
trait_delegate! { fn round_ties_to_even(self) -> Self }
trait_delegate! { fn checked_ceil(self) -> Option<Self> }
trait_delegate! { fn checked_floor(self) -> Option<Self> }
trait_delegate! { fn checked_round(self) -> Option<Self> }
trait_delegate! { fn checked_round_ties_to_even(self) -> Option<Self> }
trait_delegate! { fn saturating_ceil(self) -> Self }
trait_delegate! { fn saturating_floor(self) -> Self }
trait_delegate! { fn saturating_round(self) -> Self }
trait_delegate! { fn saturating_round_ties_to_even(self) -> Self }
trait_delegate! { fn wrapping_ceil(self) -> Self }
trait_delegate! { fn wrapping_floor(self) -> Self }
trait_delegate! { fn wrapping_round(self) -> Self }
trait_delegate! { fn wrapping_round_ties_to_even(self) -> Self }
trait_delegate! { fn overflowing_ceil(self) -> (Self, bool) }
trait_delegate! { fn overflowing_floor(self) -> (Self, bool) }
trait_delegate! { fn overflowing_round(self) -> (Self, bool) }
trait_delegate! { fn overflowing_round_ties_to_even(self) -> (Self, bool) }
trait_delegate! { fn count_ones(self) -> u32 }
trait_delegate! { fn count_zeros(self) -> u32 }
trait_delegate! { fn leading_ones(self) -> u32 }
trait_delegate! { fn leading_zeros(self) -> u32 }
trait_delegate! { fn trailing_ones(self) -> u32 }
trait_delegate! { fn trailing_zeros(self) -> u32 }
trait_delegate! { fn int_log2(self) -> i32 }
trait_delegate! { fn int_log10(self) -> i32 }
trait_delegate! { fn checked_int_log2(self) -> Option<i32> }
trait_delegate! { fn checked_int_log10(self) -> Option<i32> }
trait_delegate! { fn rotate_left(self, n: u32) -> Self }
trait_delegate! { fn rotate_right(self, n: u32) -> Self }
trait_delegate! { fn div_euclid(self, rhs: Self) -> Self }
trait_delegate! { fn rem_euclid(self, rhs: Self) -> Self }
trait_delegate! { fn div_euclid_int(self, rhs: Self::Bits) -> Self }
trait_delegate! { fn rem_euclid_int(self, rhs: Self::Bits) -> Self }
trait_delegate! { fn checked_neg(self) -> Option<Self> }
trait_delegate! { fn checked_add(self, rhs: Self) -> Option<Self> }
trait_delegate! { fn checked_sub(self, rhs: Self) -> Option<Self> }
trait_delegate! { fn checked_mul(self, rhs: Self) -> Option<Self> }
trait_delegate! { fn checked_div(self, rhs: Self) -> Option<Self> }
trait_delegate! { fn checked_rem(self, rhs: Self) -> Option<Self> }
trait_delegate! { fn checked_div_euclid(self, rhs: Self) -> Option<Self> }
trait_delegate! { fn checked_rem_euclid(self, rhs: Self) -> Option<Self> }
trait_delegate! { fn checked_mul_int(self, rhs: Self::Bits) -> Option<Self> }
trait_delegate! { fn checked_div_int(self, rhs: Self::Bits) -> Option<Self> }
trait_delegate! { fn checked_rem_int(self, rhs: Self::Bits) -> Option<Self> }
trait_delegate! { fn checked_div_euclid_int(self, rhs: Self::Bits) -> Option<Self> }
trait_delegate! { fn checked_rem_euclid_int(self, rhs: Self::Bits) -> Option<Self> }
trait_delegate! { fn checked_shl(self, rhs: u32) -> Option<Self> }
trait_delegate! { fn checked_shr(self, rhs: u32) -> Option<Self> }
trait_delegate! { fn saturating_neg(self) -> Self }
trait_delegate! { fn saturating_add(self, rhs: Self) -> Self }
trait_delegate! { fn saturating_sub(self, rhs: Self) -> Self }
trait_delegate! { fn saturating_mul(self, rhs: Self) -> Self }
trait_delegate! { fn saturating_div(self, rhs: Self) -> Self }
trait_delegate! { fn saturating_div_euclid(self, rhs: Self) -> Self }
trait_delegate! { fn saturating_mul_int(self, rhs: Self::Bits) -> Self }
trait_delegate! { fn wrapping_neg(self) -> Self }
trait_delegate! { fn wrapping_add(self, rhs: Self) -> Self }
trait_delegate! { fn wrapping_sub(self, rhs: Self) -> Self }
trait_delegate! { fn wrapping_mul(self, rhs: Self) -> Self }
trait_delegate! { fn wrapping_div(self, rhs: Self) -> Self }
trait_delegate! { fn wrapping_div_euclid(self, rhs: Self) -> Self }
trait_delegate! { fn wrapping_mul_int(self, rhs: Self::Bits) -> Self }
trait_delegate! { fn wrapping_div_int(self, rhs: Self::Bits) -> Self }
trait_delegate! { fn wrapping_div_euclid_int(self, rhs: Self::Bits) -> Self }
trait_delegate! { fn wrapping_rem_euclid_int(self, rhs: Self::Bits) -> Self }
trait_delegate! { fn wrapping_shl(self, rhs: u32) -> Self }
trait_delegate! { fn wrapping_shr(self, rhs: u32) -> Self }
trait_delegate! { fn overflowing_neg(self) -> (Self, bool) }
trait_delegate! { fn overflowing_add(self, rhs: Self) -> (Self, bool) }
trait_delegate! { fn overflowing_sub(self, rhs: Self) -> (Self, bool) }
trait_delegate! { fn overflowing_mul(self, rhs: Self) -> (Self, bool) }
trait_delegate! { fn overflowing_div(self, rhs: Self) -> (Self, bool) }
trait_delegate! { fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) }
trait_delegate! { fn overflowing_mul_int(self, rhs: Self::Bits) -> (Self, bool) }
trait_delegate! { fn overflowing_div_int(self, rhs: Self::Bits) -> (Self, bool) }
trait_delegate! { fn overflowing_div_euclid_int(self, rhs: Self::Bits) -> (Self, bool) }
trait_delegate! { fn overflowing_rem_euclid_int(self, rhs: Self::Bits) -> (Self, bool) }
trait_delegate! { fn overflowing_shl(self, rhs: u32) -> (Self, bool) }
trait_delegate! { fn overflowing_shr(self, rhs: u32) -> (Self, bool) }
}
impl<Frac: $LeEqU> FromFixed for $Fixed<Frac> {
/// Converts a fixed-point number.
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
#[inline]
fn from_fixed<F: Fixed>(src: F) -> Self {
let (wrapped, overflow) = FromFixed::overflowing_from_fixed(src);
debug_assert!(!overflow, "{} overflows", src);
let _ = overflow;
wrapped
}
/// Converts a fixed-point number if it fits, otherwise returns [`None`].
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
#[inline]
fn checked_from_fixed<F: Fixed>(src: F) -> Option<Self> {
match FromFixed::overflowing_from_fixed(src) {
(_, true) => None,
(wrapped, false) => Some(wrapped),
}
}
/// Converts a fixed-point number, saturating if it does not fit.
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
#[inline]
fn saturating_from_fixed<F: Fixed>(src: F) -> Self {
let conv = src.private_to_fixed_helper(Self::FRAC_NBITS, Self::INT_NBITS);
if conv.overflow {
return if src < 0 { Self::MIN } else { Self::MAX };
}
let bits = if_signed_unsigned! {
$Signedness,
match conv.bits {
Widest::Unsigned(bits) => {
if (bits as $Bits) < 0 {
return Self::MAX;
}
bits as $Bits
}
Widest::Negative(bits) => bits as $Bits,
},
match conv.bits {
Widest::Unsigned(bits) => bits as $Bits,
Widest::Negative(_) => {
return Self::MIN;
}
},
};
Self::from_bits(bits)
}
/// Converts a fixed-point number, wrapping if it does not fit.
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
#[inline]
fn wrapping_from_fixed<F: Fixed>(src: F) -> Self {
let (wrapped, _) = FromFixed::overflowing_from_fixed(src);
wrapped
}
/// Converts a fixed-point number.
///
/// Returns a [tuple] of the value and a [`bool`]
/// indicating whether an overflow has occurred. On
/// overflow, the wrapped value is returned.
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
#[inline]
fn overflowing_from_fixed<F: Fixed>(src: F) -> (Self, bool) {
let conv = src.private_to_fixed_helper(Self::FRAC_NBITS, Self::INT_NBITS);
let mut new_overflow = false;
let bits = if_signed_unsigned! {
$Signedness,
match conv.bits {
Widest::Unsigned(bits) => {
if (bits as $Bits) < 0 {
new_overflow = true;
}
bits as $Bits
}
Widest::Negative(bits) => bits as $Bits,
},
match conv.bits {
Widest::Unsigned(bits) => bits as $Bits,
Widest::Negative(bits) => {
new_overflow = true;
bits as $Bits
}
},
};
(Self::from_bits(bits), conv.overflow || new_overflow)
}
}
impl<Frac: $LeEqU> ToFixed for $Fixed<Frac> {
/// Converts a fixed-point number.
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
#[inline]
fn to_fixed<F: Fixed>(self) -> F {
FromFixed::from_fixed(self)
}
/// Converts a fixed-point number if it fits, otherwise returns [`None`].
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
///
/// [`None`]: https://doc.rust-lang.org/nightly/core/option/enum.Option.html#variant.None
#[inline]
fn checked_to_fixed<F: Fixed>(self) -> Option<F> {
FromFixed::checked_from_fixed(self)
}
/// Converts a fixed-point number, saturating if it does not fit.
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
#[inline]
fn saturating_to_fixed<F: Fixed>(self) -> F {
FromFixed::saturating_from_fixed(self)
}
/// Converts a fixed-point number, wrapping if it does not fit.
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
#[inline]
fn wrapping_to_fixed<F: Fixed>(self) -> F {
FromFixed::wrapping_from_fixed(self)
}
/// Converts a fixed-point number.
///
/// Returns a [tuple] of the value and a [`bool`]
/// indicating whether an overflow has occurred. On
/// overflow, the wrapped value is returned.
///
/// Any extra fractional bits are discarded, which rounds towards −∞.
///
/// [`bool`]: https://doc.rust-lang.org/nightly/std/primitive.bool.html
/// [tuple]: https://doc.rust-lang.org/nightly/std/primitive.tuple.html
#[inline]
fn overflowing_to_fixed<F: Fixed>(self) -> (F, bool) {
FromFixed::overflowing_from_fixed(self)
}
}
if_signed! {
$Signedness;
impl<Frac: $LeEqU> FixedSigned for $Fixed<Frac> {
trait_delegate! { fn abs(self) -> Self }
trait_delegate! { fn signum(self) -> Self }
trait_delegate! { fn checked_abs(self) -> Option<Self> }
trait_delegate! { fn checked_signum(self) -> Option<Self> }
trait_delegate! { fn saturating_abs(self) -> Self }
trait_delegate! { fn saturating_signum(self) -> Self }
trait_delegate! { fn wrapping_abs(self) -> Self }
trait_delegate! { fn wrapping_signum(self) -> Self }
trait_delegate! { fn overflowing_abs(self) -> (Self, bool) }
trait_delegate! { fn overflowing_signum(self) -> (Self, bool) }
trait_delegate! { fn is_positive(self) -> bool }
trait_delegate! { fn is_negative(self) -> bool }
}
}
if_unsigned! {
$Signedness;
impl<Frac: $LeEqU> FixedUnsigned for $Fixed<Frac> {
trait_delegate! { fn is_power_of_two(self) -> bool }
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 }
}
}
};
}
impl_fixed! { FixedI8, LeEqU8, i8, Signed }
impl_fixed! { FixedI16, LeEqU16, i16, Signed }
impl_fixed! { FixedI32, LeEqU32, i32, Signed }
impl_fixed! { FixedI64, LeEqU64, i64, Signed }
impl_fixed! { FixedI128, LeEqU128, i128, Signed }
impl_fixed! { FixedU8, LeEqU8, u8, Unsigned }
impl_fixed! { FixedU16, LeEqU16, u16, Unsigned }
impl_fixed! { FixedU32, LeEqU32, u32, Unsigned }
impl_fixed! { FixedU64, LeEqU64, u64, Unsigned }
impl_fixed! { FixedU128, LeEqU128, u128, Unsigned }