// Copyright © 2018–2025 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 // and // . use crate::from_str::ParseFixedError; use crate::traits::{Fixed, FixedSigned, FixedUnsigned, FromFixed, ToFixed}; use crate::types::extra::{LeEqU8, LeEqU16, LeEqU32, LeEqU64, LeEqU128}; use crate::{ FixedI8, FixedI16, FixedI32, FixedI64, FixedI128, FixedU8, FixedU16, FixedU32, FixedU64, FixedU128, }; use core::fmt::{ Binary, Debug, Display, Formatter, LowerExp, LowerHex, Octal, Result as FmtResult, UpperExp, UpperHex, }; use core::iter::{Product, Sum}; use core::ops::{ Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign, Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign, }; use core::str::FromStr; /// Provides arithmetic operations that panic on overflow even when /// debug assertions are disabled. /// /// The underlying value can be retrieved through the `.0` index. /// /// # Examples /// /// This panics even when debug assertions are disabled. /// /// ```rust,should_panic /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let max = Unwrapped(I16F16::MAX); /// let delta = Unwrapped(I16F16::DELTA); /// let _overflow = max + delta; /// ``` #[repr(transparent)] #[derive(Clone, Copy, Default, Hash, Eq, PartialEq, Ord, PartialOrd)] pub struct Unwrapped(pub F); impl Unwrapped { /// Zero. /// /// See also FixedI32::[ZERO][FixedI32::ZERO] and /// FixedU32::[ZERO][FixedU32::ZERO]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// assert_eq!(Unwrapped::::ZERO, Unwrapped(I16F16::ZERO)); /// ``` pub const ZERO: Unwrapped = Unwrapped(F::ZERO); /// The difference between any two successive representable numbers, Δ. /// /// See also FixedI32::[DELTA][FixedI32::DELTA] and /// FixedU32::[DELTA][FixedU32::DELTA]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// assert_eq!(Unwrapped::::DELTA, Unwrapped(I16F16::DELTA)); /// ``` pub const DELTA: Unwrapped = Unwrapped(F::DELTA); /// The smallest value that can be represented. /// /// See also FixedI32::[MIN][FixedI32::MIN] and /// FixedU32::[MIN][FixedU32::MIN]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// assert_eq!(Unwrapped::::MIN, Unwrapped(I16F16::MIN)); /// ``` pub const MIN: Unwrapped = Unwrapped(F::MIN); /// The largest value that can be represented. /// /// See also FixedI32::[MAX][FixedI32::MAX] and /// FixedU32::[MAX][FixedU32::MAX]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// assert_eq!(Unwrapped::::MAX, Unwrapped(I16F16::MAX)); /// ``` pub const MAX: Unwrapped = Unwrapped(F::MAX); /// [`true`] if the type is signed. /// /// See also FixedI32::[IS\_SIGNED][FixedI32::IS_SIGNED] and /// FixedU32::[IS\_SIGNED][FixedU32::IS_SIGNED]. /// /// # Examples /// /// ```rust /// use fixed::types::{I16F16, U16F16}; /// use fixed::Unwrapped; /// assert!(Unwrapped::::IS_SIGNED); /// assert!(!Unwrapped::::IS_SIGNED); /// ``` pub const IS_SIGNED: bool = F::IS_SIGNED; /// The number of integer bits. /// /// See also FixedI32::[INT\_NBITS][FixedI32::INT_NBITS] and /// FixedU32::[INT\_NBITS][FixedU32::INT_NBITS]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// assert_eq!(Unwrapped::::INT_NBITS, I16F16::INT_NBITS); /// ``` pub const INT_NBITS: u32 = F::INT_NBITS; /// The number of fractional bits. /// /// See also FixedI32::[FRAC\_NBITS][FixedI32::FRAC_NBITS] and /// FixedU32::[FRAC\_NBITS][FixedU32::FRAC_NBITS]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// assert_eq!(Unwrapped::::FRAC_NBITS, I16F16::FRAC_NBITS); /// ``` pub const FRAC_NBITS: u32 = F::FRAC_NBITS; /// Creates a fixed-point number that has a bitwise representation /// identical to the given integer. /// /// See also FixedI32::[from\_bits][FixedI32::from_bits] and /// FixedU32::[from\_bits][FixedU32::from_bits]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// assert_eq!(Unwrapped::::from_bits(0x1C), Unwrapped(I16F16::from_bits(0x1C))); /// ``` #[inline] pub fn from_bits(bits: F::Bits) -> Unwrapped { Unwrapped(F::from_bits(bits)) } /// Creates an integer that has a bitwise representation identical /// to the given fixed-point number. /// /// See also FixedI32::[to\_bits][FixedI32::to_bits] and /// FixedU32::[to\_bits][FixedU32::to_bits]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let w = Unwrapped(I16F16::from_bits(0x1C)); /// assert_eq!(w.to_bits(), 0x1C); /// ``` #[inline] pub fn to_bits(self) -> F::Bits { self.0.to_bits() } /// Converts a fixed-point number from big endian to the target’s /// endianness. /// /// See also FixedI32::[from\_be][FixedI32::from_be] and /// FixedU32::[from\_be][FixedU32::from_be]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let w = Unwrapped(I16F16::from_bits(0x1234_5678)); /// if cfg!(target_endian = "big") { /// assert_eq!(Unwrapped::from_be(w), w); /// } else { /// assert_eq!(Unwrapped::from_be(w), w.swap_bytes()); /// } /// ``` #[inline] pub fn from_be(w: Self) -> Self { Unwrapped(F::from_be(w.0)) } /// Converts a fixed-point number from little endian to the /// target’s endianness. /// /// See also FixedI32::[from\_le][FixedI32::from_le] and /// FixedU32::[from\_le][FixedU32::from_le]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let w = Unwrapped(I16F16::from_bits(0x1234_5678)); /// if cfg!(target_endian = "little") { /// assert_eq!(Unwrapped::from_le(w), w); /// } else { /// assert_eq!(Unwrapped::from_le(w), w.swap_bytes()); /// } /// ``` #[inline] pub fn from_le(w: Self) -> Self { Unwrapped(F::from_le(w.0)) } /// Converts `self` to big endian from the target’s endianness. /// /// See also FixedI32::[to\_be][FixedI32::to_be] and /// FixedU32::[to\_be][FixedU32::to_be]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let w = Unwrapped(I16F16::from_bits(0x1234_5678)); /// if cfg!(target_endian = "big") { /// assert_eq!(w.to_be(), w); /// } else { /// assert_eq!(w.to_be(), w.swap_bytes()); /// } /// ``` #[inline] #[must_use] pub fn to_be(self) -> Self { Unwrapped(self.0.to_be()) } /// Converts `self` to little endian from the target’s endianness. /// /// See also FixedI32::[to\_le][FixedI32::to_le] and /// FixedU32::[to\_le][FixedU32::to_le]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let w = Unwrapped(I16F16::from_bits(0x1234_5678)); /// if cfg!(target_endian = "little") { /// assert_eq!(w.to_le(), w); /// } else { /// assert_eq!(w.to_le(), w.swap_bytes()); /// } /// ``` #[inline] #[must_use] pub fn to_le(self) -> Self { Unwrapped(self.0.to_le()) } /// Reverses the byte order of the fixed-point number. /// /// See also FixedI32::[swap\_bytes][FixedI32::swap_bytes] and /// FixedU32::[swap\_bytes][FixedU32::swap_bytes]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let w = Unwrapped(I16F16::from_bits(0x1234_5678)); /// let swapped = Unwrapped(I16F16::from_bits(0x7856_3412)); /// assert_eq!(w.swap_bytes(), swapped); /// ``` #[inline] #[must_use] pub fn swap_bytes(self) -> Self { Unwrapped(self.0.swap_bytes()) } /// Creates a fixed-point number from its representation /// as a byte array in big endian. /// /// See also /// FixedI32::[from\_be\_bytes][FixedI32::from_be_bytes] and /// FixedU32::[from\_be\_bytes][FixedU32::from_be_bytes]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let bytes = [0x12, 0x34, 0x56, 0x78]; /// assert_eq!( /// Unwrapped::::from_be_bytes(bytes), /// Unwrapped::::from_bits(0x1234_5678) /// ); /// ``` #[inline] pub fn from_be_bytes(bytes: F::Bytes) -> Self { Unwrapped(F::from_be_bytes(bytes)) } /// Creates a fixed-point number from its representation /// as a byte array in little endian. /// /// See also /// FixedI32::[from\_le\_bytes][FixedI32::from_le_bytes] and /// FixedU32::[from\_le\_bytes][FixedU32::from_le_bytes]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let bytes = [0x78, 0x56, 0x34, 0x12]; /// assert_eq!( /// Unwrapped::::from_le_bytes(bytes), /// Unwrapped::::from_bits(0x1234_5678) /// ); /// ``` #[inline] pub fn from_le_bytes(bytes: F::Bytes) -> Self { Unwrapped(F::from_le_bytes(bytes)) } /// Creates a fixed-point number from its representation /// as a byte array in native endian. /// /// See also /// FixedI32::[from\_ne\_bytes][FixedI32::from_ne_bytes] and /// FixedU32::[from\_ne\_bytes][FixedU32::from_ne_bytes]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let bytes = if cfg!(target_endian = "big") { /// [0x12, 0x34, 0x56, 0x78] /// } else { /// [0x78, 0x56, 0x34, 0x12] /// }; /// assert_eq!( /// Unwrapped::::from_ne_bytes(bytes), /// Unwrapped::::from_bits(0x1234_5678) /// ); /// ``` #[inline] pub fn from_ne_bytes(bytes: F::Bytes) -> Self { Unwrapped(F::from_ne_bytes(bytes)) } /// Returns the memory representation of this fixed-point /// number as a byte array in big-endian byte order. /// /// See also FixedI32::[to\_be\_bytes][FixedI32::to_be_bytes] /// and FixedU32::[to\_be\_bytes][FixedU32::to_be_bytes]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// assert_eq!( /// Unwrapped::::from_bits(0x1234_5678).to_be_bytes(), /// [0x12, 0x34, 0x56, 0x78] /// ); /// ``` #[inline] pub fn to_be_bytes(self) -> F::Bytes { self.0.to_be_bytes() } /// Returns the memory representation of this fixed-point /// number as a byte array in little-endian byte order. /// /// See also FixedI32::[to\_le\_bytes][FixedI32::to_le_bytes] /// and FixedU32::[to\_le\_bytes][FixedU32::to_le_bytes]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// assert_eq!( /// Unwrapped::::from_bits(0x1234_5678).to_le_bytes(), /// [0x78, 0x56, 0x34, 0x12] /// ); /// ``` #[inline] pub fn to_le_bytes(self) -> F::Bytes { self.0.to_le_bytes() } /// Returns the memory representation of this fixed-point /// number as a byte array in native-endian byte order. /// /// See also FixedI32::[to\_ne\_bytes][FixedI32::to_ne_bytes] /// and FixedU32::[to\_ne\_bytes][FixedU32::to_ne_bytes]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let bytes = if cfg!(target_endian = "big") { /// [0x12, 0x34, 0x56, 0x78] /// } else { /// [0x78, 0x56, 0x34, 0x12] /// }; /// assert_eq!( /// Unwrapped::::from_bits(0x1234_5678).to_ne_bytes(), /// bytes /// ); /// ``` #[inline] pub fn to_ne_bytes(self) -> F::Bytes { self.0.to_ne_bytes() } /// Unwrapped conversion from another number. /// /// The other number can be: /// /// * A fixed-point number. Any extra fractional bits are /// discarded, which rounds towards −∞. /// * An integer of type [`i8`], [`i16`], [`i32`], [`i64`], [`i128`], /// [`isize`], [`u8`], [`u16`], [`u32`], [`u64`], [`u128`], or /// [`usize`]. /// * A floating-point number of type /// [half]::[f16][half::f16], /// [half]::[bf16][half::bf16], [`f32`], [`f64`] or /// [`F128`]. For this conversion, the method rounds to the nearest, /// with ties rounding to even. /// * Any other number `src` for which [`ToFixed`] is /// implemented, in which case this method returns /// [Unwrapped]\(src.[unwrapped\_to\_fixed][ToFixed::unwrapped_to_fixed]\()). /// /// See also /// FixedI32::[unwrapped\_from\_num][FixedI32::unwrapped_from_num] /// and /// FixedU32::[unwrapped\_from\_num][FixedU32::unwrapped_from_num]. /// /// # Panics /// /// Panics if the value does not fit. /// /// For floating-point numbers, also panics if the value is not [finite]. /// /// # Examples /// /// ```rust /// use fixed::types::{I4F4, I16F16}; /// use fixed::Unwrapped; /// let src = I16F16::from_num(1.75); /// let dst = Unwrapped::::from_num(src); /// assert_eq!(dst, Unwrapped(I4F4::from_num(1.75))); /// ``` /// /// The following panics even when debug assertions are disabled. /// /// ```should_panic /// use fixed::types::{I4F4, I16F16}; /// use fixed::Unwrapped; /// let src = I16F16::from_bits(0x1234_5678); /// let _overflow = Unwrapped::::from_num(src); /// ``` /// /// [`F128`]: crate::F128 /// [finite]: f64::is_finite #[inline] #[track_caller] pub fn from_num(src: Src) -> Unwrapped { Unwrapped(src.unwrapped_to_fixed()) } /// Converts a fixed-point number to another number, panicking on /// overflow. /// /// The other number can be: /// /// * Another fixed-point number. Any extra fractional bits are /// discarded, which rounds towards −∞. /// * An integer of type [`i8`], [`i16`], [`i32`], [`i64`], [`i128`], /// [`isize`], [`u8`], [`u16`], [`u32`], [`u64`], [`u128`], or /// [`usize`]. Any fractional bits are discarded, which rounds /// towards −∞. /// * A floating-point number of type /// [half]::[f16][half::f16], /// [half]::[bf16][half::bf16], [`f32`], [`f64`] or /// [`F128`]. For this conversion, the method rounds to the nearest, /// with ties rounding to even. /// * Any other type `Dst` for which [`FromFixed`] is /// implemented, in which case this method returns /// Dst::[unwrapped\_from\_fixed][FromFixed::unwrapped_from_fixed]\(self.0). /// /// See also /// FixedI32::[unwrapped\_to\_num][FixedI32::unwrapped_to_num] /// and /// FixedU32::[unwrapped\_to\_num][FixedU32::unwrapped_to_num]. /// /// # Examples /// /// ```rust /// use fixed::types::{I16F16, I4F4}; /// use fixed::Unwrapped; /// let src = Unwrapped(I4F4::from_num(1.75)); /// assert_eq!(src.to_num::(), I16F16::from_num(1.75)); /// ``` /// /// The following panics even when debug assertions are disabled. /// /// ```should_panic /// use fixed::types::{I2F6, I4F4}; /// use fixed::Unwrapped; /// let src = Unwrapped(I4F4::MAX); /// let _overflow = src.to_num::(); /// ``` /// /// [`F128`]: crate::F128 #[inline] #[track_caller] pub fn to_num(self) -> Dst { Dst::unwrapped_from_fixed(self.0) } /// Parses a string slice containing decimal digits to return a fixed-point number. /// /// Rounding is to the nearest, with ties rounded to even. /// /// See also /// FixedI32::[unwrapped\_from\_str][FixedI32::unwrapped_from_str] /// and /// FixedU32::[unwrapped\_from\_str][FixedU32::unwrapped_from_str]. /// /// # Panics /// /// Panics if the value does not fit or if there is a parsing error. /// /// # Examples /// /// ```rust /// use fixed::types::I8F8; /// use fixed::Unwrapped; /// // 16 + 3/4 = 16.75 /// let check = Unwrapped(I8F8::from_bits((16 << 8) + (3 << 8) / 4)); /// assert_eq!(Unwrapped::::from_str_dec("16.75"), check); /// ``` /// /// The following panics because of a parsing error. /// /// ```rust,should_panic /// use fixed::types::I8F8; /// use fixed::Unwrapped; /// let _error = Unwrapped::::from_str_dec("1.2."); /// ``` #[inline] #[track_caller] #[must_use] pub fn from_str_dec(src: &str) -> Unwrapped { Unwrapped(F::unwrapped_from_str(src)) } /// Parses a string slice containing binary digits to return a fixed-point number. /// /// Rounding is to the nearest, with ties rounded to even. /// /// See also /// FixedI32::[unwrapped\_from\_str\_binary][FixedI32::unwrapped_from_str_binary] /// and /// FixedU32::[unwrapped\_from\_str\_binary][FixedU32::unwrapped_from_str_binary]. /// /// # Panics /// /// Panics if the value does not fit or if there is a parsing error. /// /// # Examples /// /// ```rust /// use fixed::types::I8F8; /// use fixed::Unwrapped; /// let check = Unwrapped(I8F8::from_bits(0b1110001 << (8 - 1))); /// assert_eq!(Unwrapped::::from_str_binary("111000.1"), Ok(check)); /// ``` /// /// The following panics because of a parsing error. /// /// ```rust,should_panic /// use fixed::types::I8F8; /// use fixed::Unwrapped; /// let _error = Unwrapped::::from_str_binary("1.2"); /// ``` /// /// # Compatibility note /// /// This method either returns [`Ok`] or panics, and never returns [`Err`]. /// In version 2, this method will not return a [`Result`], but will return /// the fixed-point number directly similarly to [`from_str_dec`]. /// /// [`from_str_dec`]: Self::from_str_dec #[inline] #[track_caller] pub fn from_str_binary(src: &str) -> Result, ParseFixedError> { Ok(Unwrapped(F::unwrapped_from_str_binary(src))) } /// Parses a string slice containing octal digits to return a fixed-point number. /// /// Rounding is to the nearest, with ties rounded to even. /// /// See also /// FixedI32::[unwrapped\_from\_str\_octal][FixedI32::unwrapped_from_str_octal] /// and /// FixedU32::[unwrapped\_from\_str\_octal][FixedU32::unwrapped_from_str_octal]. /// /// # Panics /// /// Panics if the value does not fit or if there is a parsing error. /// /// # Examples /// /// ```rust /// use fixed::types::I8F8; /// use fixed::Unwrapped; /// let check = Unwrapped(I8F8::from_bits(0o1654 << (8 - 3))); /// assert_eq!(Unwrapped::::from_str_octal("165.4"), Ok(check)); /// ``` /// /// The following panics because of a parsing error. /// /// ```rust,should_panic /// use fixed::types::I8F8; /// use fixed::Unwrapped; /// let _error = Unwrapped::::from_str_octal("1.8"); /// ``` /// /// # Compatibility note /// /// This method either returns [`Ok`] or panics, and never returns [`Err`]. /// In version 2, this method will not return a [`Result`], but will return /// the fixed-point number directly similarly to [`from_str_dec`]. /// /// [`from_str_dec`]: Self::from_str_dec #[inline] #[track_caller] pub fn from_str_octal(src: &str) -> Result, ParseFixedError> { Ok(Unwrapped(F::unwrapped_from_str_octal(src))) } /// Parses a string slice containing hexadecimal digits to return a fixed-point number. /// /// Rounding is to the nearest, with ties rounded to even. /// /// See also /// FixedI32::[unwrapped\_from\_str\_hex][FixedI32::unwrapped_from_str_hex] /// and /// FixedU32::[unwrapped\_from\_str\_hex][FixedU32::unwrapped_from_str_hex]. /// /// # Panics /// /// Panics if the value does not fit or if there is a parsing error. /// /// # Examples /// /// ```rust /// use fixed::types::I8F8; /// use fixed::Unwrapped; /// let check = Unwrapped(I8F8::from_bits(0xFFE)); /// assert_eq!(Unwrapped::::from_str_hex("F.FE"), Ok(check)); /// ``` /// /// The following panics because of a parsing error. /// /// ```rust,should_panic /// use fixed::types::I8F8; /// use fixed::Unwrapped; /// let _error = Unwrapped::::from_str_hex("1.G"); /// ``` /// /// # Compatibility note /// /// This method either returns [`Ok`] or panics, and never returns [`Err`]. /// In version 2, this method will not return a [`Result`], but will return /// the fixed-point number directly similarly to [`from_str_dec`]. /// /// [`from_str_dec`]: Self::from_str_dec #[inline] #[track_caller] pub fn from_str_hex(src: &str) -> Result, ParseFixedError> { Ok(Unwrapped(F::unwrapped_from_str_hex(src))) } /// Parses an ASCII-byte slice containing decimal digits to return a fixed-point number. /// /// Rounding is to the nearest, with ties rounded to even. /// /// See also /// FixedI32::[unwrapped\_from\_ascii][FixedI32::unwrapped_from_ascii] /// and /// FixedU32::[unwrapped\_from\_ascii][FixedU32::unwrapped_from_ascii]. /// /// # Panics /// /// Panics if the value does not fit or if there is a parsing error. /// /// # Examples /// /// ```rust /// use fixed::types::I8F8; /// use fixed::Unwrapped; /// // 16 + 3/4 = 16.75 /// let check = Unwrapped(I8F8::from_bits((16 << 8) + (3 << 8) / 4)); /// assert_eq!(Unwrapped::::from_ascii(b"16.75"), check); /// ``` /// /// The following panics because of a parsing error. /// /// ```rust,should_panic /// use fixed::types::I8F8; /// use fixed::Unwrapped; /// let _error = Unwrapped::::from_ascii(b"1.2."); /// ``` #[inline] #[track_caller] #[must_use] pub fn from_ascii(src: &[u8]) -> Unwrapped { Unwrapped(F::unwrapped_from_ascii(src)) } /// Parses an ASCII-byte slice containing binary digits to return a fixed-point number. /// /// Rounding is to the nearest, with ties rounded to even. /// /// See also /// FixedI32::[unwrapped\_from\_ascii\_binary][FixedI32::unwrapped_from_ascii_binary] /// and /// FixedU32::[unwrapped\_from\_ascii\_binary][FixedU32::unwrapped_from_ascii_binary]. /// /// # Panics /// /// Panics if the value does not fit or if there is a parsing error. /// /// # Examples /// /// ```rust /// use fixed::types::I8F8; /// use fixed::Unwrapped; /// let check = Unwrapped(I8F8::from_bits(0b1110001 << (8 - 1))); /// assert_eq!(Unwrapped::::from_ascii_binary(b"111000.1"), check); /// ``` /// /// The following panics because of a parsing error. /// /// ```rust,should_panic /// use fixed::types::I8F8; /// use fixed::Unwrapped; /// let _error = Unwrapped::::from_ascii_binary(b"1.2"); /// ``` #[inline] #[track_caller] pub fn from_ascii_binary(src: &[u8]) -> Unwrapped { Unwrapped(F::unwrapped_from_ascii_binary(src)) } /// Parses an ASCII-byte slice containing octal digits to return a fixed-point number. /// /// Rounding is to the nearest, with ties rounded to even. /// /// See also /// FixedI32::[unwrapped\_from\_ascii\_octal][FixedI32::unwrapped_from_ascii_octal] /// and /// FixedU32::[unwrapped\_from\_ascii\_octal][FixedU32::unwrapped_from_ascii_octal]. /// /// # Panics /// /// Panics if the value does not fit or if there is a parsing error. /// /// # Examples /// /// ```rust /// use fixed::types::I8F8; /// use fixed::Unwrapped; /// let check = Unwrapped(I8F8::from_bits(0o1654 << (8 - 3))); /// assert_eq!(Unwrapped::::from_ascii_octal(b"165.4"), check); /// ``` /// /// The following panics because of a parsing error. /// /// ```rust,should_panic /// use fixed::types::I8F8; /// use fixed::Unwrapped; /// let _error = Unwrapped::::from_ascii_octal(b"1.8"); /// ``` #[inline] #[track_caller] pub fn from_ascii_octal(src: &[u8]) -> Unwrapped { Unwrapped(F::unwrapped_from_ascii_octal(src)) } /// Parses an ASCII-byte slice containing hexadecimal digits to return a fixed-point number. /// /// Rounding is to the nearest, with ties rounded to even. /// /// See also /// FixedI32::[unwrapped\_from\_ascii\_hex][FixedI32::unwrapped_from_ascii_hex] /// and /// FixedU32::[unwrapped\_from\_ascii\_hex][FixedU32::unwrapped_from_ascii_hex]. /// /// # Panics /// /// Panics if the value does not fit or if there is a parsing error. /// /// # Examples /// /// ```rust /// use fixed::types::I8F8; /// use fixed::Unwrapped; /// let check = Unwrapped(I8F8::from_bits(0xFFE)); /// assert_eq!(Unwrapped::::from_ascii_hex(b"F.FE"), check); /// ``` /// /// The following panics because of a parsing error. /// /// ```rust,should_panic /// use fixed::types::I8F8; /// use fixed::Unwrapped; /// let _error = Unwrapped::::from_ascii_hex(b"1.G"); /// ``` #[inline] #[track_caller] pub fn from_ascii_hex(src: &[u8]) -> Unwrapped { Unwrapped(F::unwrapped_from_ascii_hex(src)) } /// Returns the integer part. /// /// Note that since the numbers are stored in two’s complement, /// negative numbers with non-zero fractional parts will be /// rounded towards −∞, except in the case where there are no /// integer bits, for example for the type /// [Unwrapped]<[I0F16]>, where the return /// value is always zero. /// /// See also FixedI32::[int][FixedI32::int] and /// FixedU32::[int][FixedU32::int]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// assert_eq!(Unwrapped(I16F16::from_num(12.25)).int(), Unwrapped(I16F16::from_num(12))); /// assert_eq!(Unwrapped(I16F16::from_num(-12.25)).int(), Unwrapped(I16F16::from_num(-13))); /// ``` /// /// [I0F16]: crate::types::I0F16 #[inline] #[must_use] pub fn int(self) -> Unwrapped { Unwrapped(self.0.int()) } /// Returns the fractional part. /// /// Note that since the numbers are stored in two’s complement, /// the returned fraction will be non-negative for negative /// numbers, except in the case where there are no integer bits, /// for example for the type /// [Unwrapped]<[I0F16]>, where the return /// value is always equal to `self`. /// /// See also FixedI32::[frac][FixedI32::frac] and /// FixedU32::[frac][FixedU32::frac]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// assert_eq!(Unwrapped(I16F16::from_num(12.25)).frac(), Unwrapped(I16F16::from_num(0.25))); /// assert_eq!(Unwrapped(I16F16::from_num(-12.25)).frac(), Unwrapped(I16F16::from_num(0.75))); /// ``` /// /// [I0F16]: crate::types::I0F16 #[inline] #[must_use] pub fn frac(self) -> Unwrapped { Unwrapped(self.0.frac()) } /// Rounds to the next integer towards 0. /// /// See also /// FixedI32::[round\_to\_zero][FixedI32::round_to_zero] and /// FixedU32::[round\_to\_zero][FixedU32::round_to_zero]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let three = Unwrapped(I16F16::from_num(3)); /// assert_eq!(Unwrapped(I16F16::from_num(3.9)).round_to_zero(), three); /// assert_eq!(Unwrapped(I16F16::from_num(-3.9)).round_to_zero(), -three); /// ``` #[inline] #[must_use] pub fn round_to_zero(self) -> Unwrapped { Unwrapped(self.0.round_to_zero()) } /// Unwrapped ceil. Rounds to the next integer towards +∞, panicking /// on overflow. /// /// See also /// FixedI32::[unwrapped\_ceil][FixedI32::unwrapped_ceil] and /// FixedU32::[unwrapped\_ceil][FixedU32::unwrapped_ceil]. /// /// # Panics /// /// Panics if the result does not fit. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let two_half = Unwrapped(I16F16::from_num(5) / 2); /// assert_eq!(two_half.ceil(), Unwrapped(I16F16::from_num(3))); /// ``` /// /// The following panics because of overflow. /// /// ```should_panic /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let _overflow = Unwrapped(I16F16::MAX).ceil(); /// ``` #[inline] #[track_caller] #[must_use] pub fn ceil(self) -> Unwrapped { Unwrapped(self.0.unwrapped_ceil()) } /// Unwrapped floor. Rounds to the next integer towards −∞, /// panicking on overflow. /// /// Overflow can only occur for signed numbers with zero integer /// bits. /// /// See also /// FixedI32::[unwrapped\_floor][FixedI32::unwrapped_floor] and /// FixedU32::[unwrapped\_floor][FixedU32::unwrapped_floor]. /// /// # Panics /// /// Panics if the result does not fit. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let two_half = Unwrapped(I16F16::from_num(5) / 2); /// assert_eq!(two_half.floor(), Unwrapped(I16F16::from_num(2))); /// ``` /// /// The following panics because of overflow. /// /// ```should_panic /// use fixed::types::I0F32; /// use fixed::Unwrapped; /// let _overflow = Unwrapped(I0F32::MIN).floor(); /// ``` #[inline] #[track_caller] #[must_use] pub fn floor(self) -> Unwrapped { Unwrapped(self.0.unwrapped_floor()) } /// Unwrapped round. Rounds to the next integer to the nearest, /// with ties rounded away from zero, and panics on overflow. /// /// See also /// FixedI32::[unwrapped\_round][FixedI32::unwrapped_round] and /// FixedU32::[unwrapped\_round][FixedU32::unwrapped_round]. /// /// # Panics /// /// Panics if the result does not fit. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let two_half = Unwrapped(I16F16::from_num(5) / 2); /// assert_eq!(two_half.round(), Unwrapped(I16F16::from_num(3))); /// assert_eq!((-two_half).round(), Unwrapped(I16F16::from_num(-3))); /// ``` /// /// The following panics because of overflow. /// /// ```should_panic /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let _overflow = Unwrapped(I16F16::MAX).round(); /// ``` #[inline] #[track_caller] #[must_use] pub fn round(self) -> Unwrapped { Unwrapped(self.0.unwrapped_round()) } /// Unwrapped round. Rounds to the next integer to the nearest, with ties /// rounded to even, and panics on overflow. /// /// See also /// FixedI32::[unwrapped\_round\_ties\_even][FixedI32::unwrapped_round_ties_even] /// and /// FixedU32::[unwrapped\_round\_ties\_even][FixedU32::unwrapped_round_ties_even]. /// /// # Panics /// /// Panics if the result does not fit. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let two_half = Unwrapped(I16F16::from_num(2.5)); /// assert_eq!(two_half.round_ties_even(), Unwrapped(I16F16::from_num(2))); /// let three_half = Unwrapped(I16F16::from_num(3.5)); /// assert_eq!(three_half.round_ties_even(), Unwrapped(I16F16::from_num(4))); /// ``` /// /// The following panics because of overflow. /// /// ```should_panic /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let max = Unwrapped(I16F16::MAX); /// let _overflow = max.round_ties_even(); /// ``` #[inline] #[track_caller] #[must_use] pub fn round_ties_even(self) -> Unwrapped { Unwrapped(self.0.unwrapped_round_ties_even()) } /// Returns the number of ones in the binary representation. /// /// See also FixedI32::[count\_ones][FixedI32::count_ones] and /// FixedU32::[count\_ones][FixedU32::count_ones]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let w = Unwrapped(I16F16::from_bits(0x00FF_FF00)); /// assert_eq!(w.count_ones(), w.0.count_ones()); /// ``` #[inline] #[doc(alias("popcount", "popcnt"))] pub fn count_ones(self) -> u32 { self.0.count_ones() } /// Returns the number of zeros in the binary representation. /// /// See also FixedI32::[count\_zeros][FixedI32::count_zeros] /// and FixedU32::[count\_zeros][FixedU32::count_zeros]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let w = Unwrapped(I16F16::from_bits(0x00FF_FF00)); /// assert_eq!(w.count_zeros(), w.0.count_zeros()); /// ``` #[inline] pub fn count_zeros(self) -> u32 { self.0.count_zeros() } /// Returns the number of leading ones in the binary representation. /// /// See also FixedI32::[leading\_ones][FixedI32::leading_ones] /// and FixedU32::[leading\_ones][FixedU32::leading_ones]. /// /// # Examples /// /// ```rust /// use fixed::types::U16F16; /// use fixed::Unwrapped; /// let w = Unwrapped(U16F16::from_bits(0xFF00_00FF)); /// assert_eq!(w.leading_ones(), w.0.leading_ones()); /// ``` #[inline] pub fn leading_ones(self) -> u32 { self.0.leading_ones() } /// Returns the number of leading zeros in the binary representation. /// /// See also /// FixedI32::[leading\_zeros][FixedI32::leading_zeros] and /// FixedU32::[leading\_zeros][FixedU32::leading_zeros]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let w = Unwrapped(I16F16::from_bits(0x00FF_FF00)); /// assert_eq!(w.leading_zeros(), w.0.leading_zeros()); /// ``` #[inline] pub fn leading_zeros(self) -> u32 { self.0.leading_zeros() } /// Returns the number of trailing ones in the binary representation. /// /// See also /// FixedI32::[trailing\_ones][FixedI32::trailing_ones] and /// FixedU32::[trailing\_ones][FixedU32::trailing_ones]. /// /// # Examples /// /// ```rust /// use fixed::types::U16F16; /// use fixed::Unwrapped; /// let w = Unwrapped(U16F16::from_bits(0xFF00_00FF)); /// assert_eq!(w.trailing_ones(), w.0.trailing_ones()); /// ``` #[inline] pub fn trailing_ones(self) -> u32 { self.0.trailing_ones() } /// Returns the number of trailing zeros in the binary representation. /// /// See also /// FixedI32::[trailing\_zeros][FixedI32::trailing_zeros] and /// FixedU32::[trailing\_zeros][FixedU32::trailing_zeros]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let w = Unwrapped(I16F16::from_bits(0x00FF_FF00)); /// assert_eq!(w.trailing_zeros(), w.0.trailing_zeros()); /// ``` #[inline] pub fn trailing_zeros(self) -> u32 { self.0.trailing_zeros() } /// Returns the square root. /// /// See also /// FixedI32::[unwrapped\_sqrt][FixedI32::unwrapped_sqrt] and /// FixedU32::[unwrapped\_sqrt][FixedU32::unwrapped_sqrt]. /// /// # Panics /// /// Panics if the number is negative, or on overflow. /// /// # Examples /// /// ```rust /// use fixed::types::I0F32; /// use fixed::Unwrapped; /// assert_eq!(Unwrapped(I0F32::lit("0b0.0001")).sqrt().0, I0F32::lit("0b0.01")); /// ``` /// /// The following panics because the input value is negative. /// /// ```should_panic /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let neg = Unwrapped(I16F16::from_num(-1)); /// let _sqrt_neg = neg.sqrt(); /// ``` /// /// The following panics because of overflow. /// /// ```should_panic /// use fixed::types::I0F32; /// use fixed::Unwrapped; /// let u = Unwrapped(I0F32::from_num(0.25)); /// let _overflow = u.sqrt(); /// ``` #[inline] #[track_caller] pub fn sqrt(self) -> Self { Unwrapped(self.0.unwrapped_sqrt()) } /// Integer base-2 logarithm, rounded down. /// /// See also FixedI32::[int\_log2][FixedI32::int_log2] and /// FixedU32::[int\_log2][FixedU32::int_log2]. /// /// # Panics /// /// Panics if the fixed-point number is ≤ 0. #[inline] #[track_caller] #[doc(alias("ilog2"))] pub fn int_log2(self) -> i32 { self.0.int_log2() } /// Integer base-10 logarithm, rounded down. /// /// See also FixedI32::[int\_log10][FixedI32::int_log10] and /// FixedU32::[int\_log10][FixedU32::int_log10]. /// /// # Panics /// /// Panics if the fixed-point number is ≤ 0. #[inline] #[track_caller] #[doc(alias("ilog10"))] pub fn int_log10(self) -> i32 { self.0.int_log10() } /// Integer logarithm to the specified base, rounded down. /// /// See also FixedI32::[int\_log][FixedI32::int_log] and /// FixedU32::[int\_log][FixedU32::int_log]. /// /// # Panics /// /// Panics if the fixed-point number is ≤ 0 or if the base is < 2. #[inline] #[track_caller] #[doc(alias("ilog"))] pub fn int_log(self, base: u32) -> i32 { self.0.int_log(base) } /// Reverses the order of the bits of the fixed-point number. /// /// See also FixedI32::[reverse\_bits][FixedI32::reverse_bits] /// and FixedU32::[reverse\_bits][FixedU32::reverse_bits]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let i = I16F16::from_bits(0x1234_5678); /// assert_eq!(Unwrapped(i).reverse_bits(), Unwrapped(i.reverse_bits())); /// ``` #[inline] #[must_use = "this returns the result of the operation, without modifying the original"] pub fn reverse_bits(self) -> Unwrapped { Unwrapped(self.0.reverse_bits()) } /// Shifts to the left by `n` bits, unwrapped the truncated bits to the right end. /// /// See also FixedI32::[rotate\_left][FixedI32::rotate_left] /// and FixedU32::[rotate\_left][FixedU32::rotate_left]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let i = I16F16::from_bits(0x00FF_FF00); /// assert_eq!(Unwrapped(i).rotate_left(12), Unwrapped(i.rotate_left(12))); /// ``` #[inline] #[must_use = "this returns the result of the operation, without modifying the original"] pub fn rotate_left(self, n: u32) -> Unwrapped { Unwrapped(self.0.rotate_left(n)) } /// Shifts to the right by `n` bits, unwrapped the truncated bits to the left end. /// /// See also FixedI32::[rotate\_right][FixedI32::rotate_right] /// and FixedU32::[rotate\_right][FixedU32::rotate_right]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let i = I16F16::from_bits(0x00FF_FF00); /// assert_eq!(Unwrapped(i).rotate_right(12), Unwrapped(i.rotate_right(12))); /// ``` #[inline] #[must_use = "this returns the result of the operation, without modifying the original"] pub fn rotate_right(self, n: u32) -> Unwrapped { Unwrapped(self.0.rotate_right(n)) } /// Returns [`true`] if the number is zero. /// /// See also FixedI32::[is\_zero][FixedI32::is_zero] and /// FixedU32::[is\_zero][FixedU32::is_zero]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// assert!(Unwrapped(I16F16::ZERO).is_zero()); /// assert!(!Unwrapped(I16F16::from_num(4.3)).is_zero()); /// ``` #[inline] pub fn is_zero(self) -> bool { self.0.is_zero() } /// Returns the distance from `self` to `other`. /// /// See also /// FixedI32::[unwrapped\_dist][FixedI32::unwrapped_dist] and /// FixedU32::[unwrapped\_dist][FixedU32::unwrapped_dist]. /// /// # Panics /// /// Panics on overflow. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// type Unwr = Unwrapped; /// assert_eq!(Unwr::from_num(-1).dist(Unwr::from_num(4)), Unwr::from_num(5)); /// ``` /// /// The following panics because of overflow. /// /// ```should_panic /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// type Unwr = Unwrapped; /// let _overflow = Unwr::MIN.dist(Unwr::ZERO); /// ``` #[inline] #[track_caller] #[must_use = "this returns the result of the operation, without modifying the original"] pub fn dist(self, other: Unwrapped) -> Unwrapped { Unwrapped(self.0.unwrapped_dist(other.0)) } /// Returns the mean of `self` and `other`. /// /// See also FixedI32::[mean][FixedI32::mean] and /// FixedU32::[mean][FixedU32::mean]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let three = Unwrapped(I16F16::from_num(3)); /// let four = Unwrapped(I16F16::from_num(4)); /// assert_eq!(three.mean(four), Unwrapped(I16F16::from_num(3.5))); /// assert_eq!(three.mean(-four), Unwrapped(I16F16::from_num(-0.5))); /// ``` #[inline] #[must_use = "this returns the result of the operation, without modifying the original"] pub fn mean(self, other: Unwrapped) -> Unwrapped { Unwrapped(self.0.mean(other.0)) } /// Compute the hypotenuse of a right triange. /// /// See also /// FixedI32::[unwrapped\_hypot][FixedI32::unwrapped_hypot] and /// FixedU32::[unwrapped\_hypot][FixedU32::unwrapped_hypot]. /// /// # Examples /// /// ```rust /// use fixed::types::I8F8; /// use fixed::Unwrapped; /// type Unwr = Unwrapped; /// // hypot(3, 4) == 5 /// assert_eq!(Unwr::from_num(3).hypot(Unwr::from_num(4)), Unwr::from_num(5)); /// ``` /// /// The following panics because of overflow. /// /// ```should_panic /// use fixed::types::I8F8; /// use fixed::Unwrapped; /// type Unwr = Unwrapped; /// // hypot(88, 105) == 137, which does not fit /// let _overflow = Unwr::from_num(88).hypot(Unwr::from_num(105)); /// ``` #[inline] #[must_use = "this returns the result of the operation, without modifying the original"] pub fn hypot(self, other: Unwrapped) -> Unwrapped { Unwrapped(self.0.unwrapped_hypot(other.0)) } /// Returns the reciprocal (inverse), 1/`self`. /// /// See also /// FixedI32::[unwrapped\_recip][FixedI32::unwrapped_recip] and /// FixedU32::[unwrapped\_recip][FixedU32::unwrapped_recip]. /// /// # Panics /// /// Panics if `self` is zero or on overflow. /// /// # Examples /// /// ```rust /// use fixed::types::I8F24; /// use fixed::Unwrapped; /// let quarter = Unwrapped(I8F24::from_num(0.25)); /// assert_eq!(quarter.recip(), Unwrapped(I8F24::from_num(4))); /// ``` /// /// The following panics because of overflow. /// /// ```should_panic /// use fixed::types::I8F24; /// use fixed::Unwrapped; /// let frac_1_512 = Unwrapped(I8F24::ONE / 512); /// let _overflow = frac_1_512.recip(); /// ``` #[inline] #[track_caller] #[must_use] pub fn recip(self) -> Unwrapped { Unwrapped(self.0.unwrapped_recip()) } /// Returns the next multiple of `other`. /// /// See also /// FixedI32::[unwrapped\_next\_multiple\_of][FixedI32::unwrapped_next_multiple_of] /// and /// FixedU32::[unwrapped\_next\_multiple\_of][FixedU32::unwrapped_next_multiple_of]. /// /// # Panics /// /// Panics if `other` is zero or on overflow. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let one_point_5 = Unwrapped::::from_num(1.5); /// let four = Unwrapped::::from_num(4); /// let four_point_5 = Unwrapped::::from_num(4.5); /// assert_eq!(four.next_multiple_of(one_point_5), four_point_5); /// ``` /// /// The following panics because of overflow. /// /// ```rust,should_panic /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let two = Unwrapped::::from_num(2); /// let max = Unwrapped::::MAX; /// let _overflow = max.next_multiple_of(two); /// ``` #[inline] #[track_caller] #[must_use] pub fn next_multiple_of(self, other: Unwrapped) -> Unwrapped { Unwrapped(self.0.unwrapped_next_multiple_of(other.0)) } /// Multiply and add. Returns `self` × `mul` + `add`. /// /// See also /// FixedI32::[unwrapped\_mul\_add][FixedI32::unwrapped_mul_add] /// and /// FixedU32::[unwrapped\_mul\_add][FixedU32::unwrapped_mul_add]. /// /// # Panics /// /// Panics if the result does not fit. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let half = Unwrapped(I16F16::from_num(0.5)); /// let three = Unwrapped(I16F16::from_num(3)); /// let four = Unwrapped(I16F16::from_num(4)); /// assert_eq!(three.mul_add(half, four), Unwrapped(I16F16::from_num(5.5))); /// // max × 1.5 - max = max / 2, which does not overflow /// let max = Unwrapped(I16F16::MAX); /// assert_eq!(max.mul_add(Unwrapped(I16F16::from_num(1.5)), -max), max / 2); /// ``` /// /// The following panics because of overflow. /// /// ```should_panic /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let one = Unwrapped(I16F16::ONE); /// let max = Unwrapped(I16F16::MAX); /// let _overflow = max.mul_add(one, one); /// ``` #[inline] #[track_caller] #[must_use = "this returns the result of the operation, without modifying the original"] pub fn mul_add(self, mul: Unwrapped, add: Unwrapped) -> Unwrapped { Unwrapped(self.0.unwrapped_mul_add(mul.0, add.0)) } /// Adds `self` to the product `a` × `b`. /// /// See also /// FixedI32::[unwrapped\_add\_prod][FixedI32::unwrapped_add_prod] /// and /// FixedU32::[unwrapped\_add\_prod][FixedU32::unwrapped_add_prod]. /// /// # Panics /// /// Panics if the result does not fit. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let half = Unwrapped(I16F16::from_num(0.5)); /// let three = Unwrapped(I16F16::from_num(3)); /// let four = Unwrapped(I16F16::from_num(4)); /// assert_eq!(three.add_prod(four, half), Unwrapped(I16F16::from_num(5))); /// ``` /// /// The following panics because of overflow. /// /// ```should_panic /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let max = Unwrapped(I16F16::MAX); /// let _overflow = max.add_prod(max, Unwrapped(I16F16::from_num(3))); /// ``` #[inline] #[track_caller] #[must_use] pub fn add_prod(self, a: Unwrapped, b: Unwrapped) -> Unwrapped { Unwrapped(self.0.unwrapped_add_prod(a.0, b.0)) } /// Multiply and accumulate. Adds (`a` × `b`) to `self`. /// /// See also /// FixedI32::[unwrapped\_mul\_acc][FixedI32::unwrapped_mul_acc] /// and /// FixedU32::[unwrapped\_mul\_acc][FixedU32::unwrapped_mul_acc]. /// /// # Panics /// /// Panics if the result does not fit. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let mut acc = Unwrapped(I16F16::from_num(3)); /// acc.mul_acc(Unwrapped(I16F16::from_num(4)), Unwrapped(I16F16::from_num(0.5))); /// assert_eq!(acc, Unwrapped(I16F16::from_num(5))); /// ``` /// /// The following panics because of overflow. /// /// ```should_panic /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let mut acc = Unwrapped(I16F16::MAX); /// acc.mul_acc(Unwrapped(I16F16::MAX), Unwrapped(I16F16::from_num(3))); /// ``` #[inline] #[track_caller] pub fn mul_acc(&mut self, a: Unwrapped, b: Unwrapped) { self.0.unwrapped_mul_acc(a.0, b.0); } /// Euclidean division. /// /// See also /// FixedI32::[unwrapped\_div\_euclid][FixedI32::unwrapped_div_euclid] /// and /// FixedU32::[unwrapped\_div\_euclid][FixedU32::unwrapped_div_euclid]. /// /// # Panics /// /// Panics if the divisor is zero, or if the division results in overflow. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let num = Unwrapped(I16F16::from_num(7.5)); /// let den = Unwrapped(I16F16::from_num(2)); /// assert_eq!(num.div_euclid(den), Unwrapped(I16F16::from_num(3))); /// ``` /// /// The following panics because of overflow. /// /// ```should_panic /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let quarter = Unwrapped(I16F16::from_num(0.25)); /// let _overflow = Unwrapped(I16F16::MAX).div_euclid(quarter); /// ``` #[inline] #[track_caller] #[must_use = "this returns the result of the operation, without modifying the original"] pub fn div_euclid(self, divisor: Unwrapped) -> Unwrapped { Unwrapped(self.0.unwrapped_div_euclid(divisor.0)) } /// Remainder for Euclidean division. /// /// See also /// FixedI32::[unwrapped\_rem\_euclid][FixedI32::unwrapped_rem_euclid] /// and /// FixedU32::[unwrapped\_rem\_euclid][FixedU32::unwrapped_rem_euclid]. /// /// # Panics /// /// Panics if the divisor is zero. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let num = Unwrapped(I16F16::from_num(7.5)); /// let den = Unwrapped(I16F16::from_num(2)); /// assert_eq!(num.rem_euclid(den), Unwrapped(I16F16::from_num(1.5))); /// assert_eq!((-num).rem_euclid(den), Unwrapped(I16F16::from_num(0.5))); /// ``` #[inline] #[track_caller] #[must_use = "this returns the result of the operation, without modifying the original"] pub fn rem_euclid(self, divisor: Unwrapped) -> Unwrapped { Unwrapped(self.0.unwrapped_rem_euclid(divisor.0)) } /// Euclidean division by an integer. /// /// See also /// FixedI32::[unwrapped\_div\_euclid\_int][FixedI32::unwrapped_div_euclid_int] /// and /// FixedU32::[unwrapped\_div\_euclid\_int][FixedU32::unwrapped_div_euclid_int]. /// /// # Panics /// /// Panics if the divisor is zero or if the division results in overflow. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let num = Unwrapped(I16F16::from_num(7.5)); /// assert_eq!(num.div_euclid_int(2), Unwrapped(I16F16::from_num(3))); /// ``` /// /// The following panics because of overflow. /// /// ```should_panic /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let min = Unwrapped(I16F16::MIN); /// let _overflow = min.div_euclid_int(-1); /// ``` #[inline] #[track_caller] #[must_use = "this returns the result of the operation, without modifying the original"] pub fn div_euclid_int(self, divisor: F::Bits) -> Unwrapped { Unwrapped(self.0.unwrapped_div_euclid_int(divisor)) } /// Remainder for Euclidean division. /// /// See also /// FixedI32::[unwrapped\_rem\_euclid\_int][FixedI32::unwrapped_rem_euclid_int] /// and /// FixedU32::[unwrapped\_rem\_euclid\_int][FixedU32::unwrapped_rem_euclid_int]. /// /// # Panics /// /// Panics if the divisor is zero. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let num = Unwrapped(I16F16::from_num(7.5)); /// assert_eq!(num.rem_euclid_int(2), Unwrapped(I16F16::from_num(1.5))); /// assert_eq!((-num).rem_euclid_int(2), Unwrapped(I16F16::from_num(0.5))); /// ``` /// /// The following panics because of overflow. /// /// ```should_panic /// use fixed::types::I8F8; /// use fixed::Unwrapped; /// let num = Unwrapped(I8F8::from_num(-7.5)); /// // -128 ≤ Fix < 128, so the answer 192.5 overflows /// let _overflow = num.rem_euclid_int(200); /// ``` #[inline] #[track_caller] #[must_use = "this returns the result of the operation, without modifying the original"] pub fn rem_euclid_int(self, divisor: F::Bits) -> Unwrapped { Unwrapped(self.0.unwrapped_rem_euclid_int(divisor)) } /// Unbounded shift left. Computes `self << rhs`, without bounding the value /// of `rhs`. /// /// See also /// FixedI32::[unbounded\_shl][FixedI32::unbounded_shl] and /// FixedU32::[unbounded\_shl][FixedU32::unbounded_shl]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// type Unwr = Unwrapped; /// let num = Unwrapped(I16F16::from_num(1.5)); /// assert_eq!(num.unbounded_shl(5), num << 5); /// assert_eq!(num.unbounded_shl(32), Unwr::ZERO); /// ``` #[must_use = "this returns the result of the operation, without modifying the original"] #[inline] pub fn unbounded_shl(self, rhs: u32) -> Unwrapped { Unwrapped(self.0.unbounded_shl(rhs)) } /// Unbounded shift right. Computes `self >> rhs`, without bounding the /// value of `rhs`. /// /// See also /// FixedI32::[unbounded\_shr][FixedI32::unbounded_shr] and /// FixedU32::[unbounded\_shr][FixedU32::unbounded_shr]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// type Unwr = Unwrapped; /// let num = Unwrapped(I16F16::from_num(1.5)); /// assert_eq!(num.unbounded_shr(5), num >> 5); /// assert_eq!(num.unbounded_shr(32), Unwr::ZERO); /// assert_eq!((-num).unbounded_shr(5), (-num) >> 5); /// assert_eq!((-num).unbounded_shr(32), -Unwr::DELTA); /// ``` #[must_use = "this returns the result of the operation, without modifying the original"] #[inline] pub fn unbounded_shr(self, rhs: u32) -> Unwrapped { Unwrapped(self.0.unbounded_shr(rhs)) } /// Linear interpolation between `start` and `end`. /// /// See also /// FixedI32::[unwrapped\_lerp][FixedI32::unwrapped_lerp] and /// FixedU32::[unwrapped\_lerp][FixedU32::unwrapped_lerp]. /// /// # Panics /// /// Panics on overflow. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// type Unwr = Unwrapped; /// assert_eq!(Unwr::from_num(0.5).lerp(Unwr::ZERO, Unwr::MAX), Unwr::MAX / 2); /// ``` /// /// The following panics because of overflow. /// /// ```should_panic /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// type Unwr = Unwrapped; /// let _overflow = Unwr::from_num(1.5).lerp(Unwr::ZERO, Unwr::MAX); /// ``` #[inline] #[track_caller] #[must_use = "this returns the result of the operation, without modifying the original"] pub fn lerp(self, start: Unwrapped, end: Unwrapped) -> Unwrapped { Unwrapped(self.0.unwrapped_lerp(start.0, end.0)) } /// Inverse linear interpolation between `start` and `end`. /// /// See also /// FixedI32::[unwrapped\_inv\_lerp][FixedI32::unwrapped_inv_lerp] and /// FixedU32::[unwrapped\_inv\_lerp][FixedU32::unwrapped_inv_lerp]. /// /// # Panics /// /// Panics when `start` = `end` or when the results overflows. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// type Unwr = Unwrapped; /// assert_eq!( /// Unwr::from_num(25).inv_lerp(Unwr::from_num(20), Unwr::from_num(40)), /// Unwr::from_num(0.25) /// ); /// ``` /// /// The following panics because `start` = `end`. /// /// ```should_panic /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// type Unwr = Unwrapped; /// let two = Unwr::from_num(2); /// let _zero_range = two.inv_lerp(two, two); /// ``` /// /// The following panics because of overflow. /// /// ```should_panic /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// type Unwr = Unwrapped; /// let _overflow = Unwr::MAX.inv_lerp(Unwr::ZERO, Unwr::from_num(0.5)); /// ``` #[inline] #[track_caller] #[must_use] pub fn inv_lerp(self, start: Unwrapped, end: Unwrapped) -> Unwrapped { Unwrapped(self.0.unwrapped_inv_lerp(start.0, end.0)) } /// Unwrapped round. Rounds to the next integer to the nearest, with ties /// rounded to even, and panics on overflow. /// /// # Panics /// /// Panics if the result does not fit. #[inline] #[track_caller] #[must_use] #[deprecated(since = "1.28.0", note = "renamed to `round_ties_even`")] pub fn round_ties_to_even(self) -> Unwrapped { self.round_ties_even() } } impl Unwrapped { /// Returns the bit pattern of `self` reinterpreted as an unsigned /// fixed-point number of the same size. /// /// See also FixedI32::[cast\_unsigned][FixedU32::cast_unsigned]. /// /// # Examples /// /// ```rust /// use fixed::types::{I16F16, U16F16}; /// use fixed::Unwrapped; /// /// let n = Unwrapped(-I16F16::DELTA); /// assert_eq!(n.cast_unsigned(), Unwrapped(U16F16::MAX)); /// ``` #[must_use] #[inline] pub fn cast_unsigned(self) -> Unwrapped { Unwrapped(self.0.cast_unsigned()) } /// Returns the number of bits required to represent the value. /// /// The number of bits required includes an initial one for /// negative numbers, and an initial zero for non-negative /// numbers. /// /// See also FixedI32::[signed\_bits][FixedI32::signed_bits]. /// /// # Examples /// /// ```rust /// use fixed::types::I4F4; /// use fixed::Unwrapped; /// assert_eq!(Unwrapped(I4F4::from_num(-3)).signed_bits(), 7); // “_101.0000” /// assert_eq!(Unwrapped(I4F4::from_num(-1)).signed_bits(), 5); // “___1.0000” /// assert_eq!(Unwrapped(I4F4::from_num(-0.0625)).signed_bits(), 1); // “____.___1” /// assert_eq!(Unwrapped(I4F4::from_num(0)).signed_bits(), 1); // “____.___0” /// assert_eq!(Unwrapped(I4F4::from_num(0.0625)).signed_bits(), 2); // “____.__01” /// assert_eq!(Unwrapped(I4F4::from_num(1)).signed_bits(), 6); // “__01.0000” /// assert_eq!(Unwrapped(I4F4::from_num(3)).signed_bits(), 7); // “_011.0000” /// ``` #[inline] pub fn signed_bits(self) -> u32 { self.0.signed_bits() } /// Returns [`true`] if the number is > 0. /// /// See also FixedI32::[is\_positive][FixedI32::is_positive]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// assert!(Unwrapped(I16F16::from_num(4.3)).is_positive()); /// assert!(!Unwrapped(I16F16::ZERO).is_positive()); /// assert!(!Unwrapped(I16F16::from_num(-4.3)).is_positive()); /// ``` #[inline] pub fn is_positive(self) -> bool { self.0.is_positive() } /// Returns [`true`] if the number is < 0. /// /// See also FixedI32::[is\_negative][FixedI32::is_negative]. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// assert!(!Unwrapped(I16F16::from_num(4.3)).is_negative()); /// assert!(!Unwrapped(I16F16::ZERO).is_negative()); /// assert!(Unwrapped(I16F16::from_num(-4.3)).is_negative()); /// ``` #[inline] pub fn is_negative(self) -> bool { self.0.is_negative() } /// Unwrapped absolute value. Returns the absolute value, panicking /// on overflow. /// /// Overflow can only occur when trying to find the absolute value /// of the minimum value. /// /// See also /// FixedI32::[unwrapped\_abs][FixedI32::unwrapped_abs]. /// /// # Panics /// /// Panics if the result does not fit. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// assert_eq!(Unwrapped(I16F16::from_num(-5)).abs(), Unwrapped(I16F16::from_num(5))); /// ``` /// /// The following panics because of overflow. /// /// ```should_panic /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// let _overflow = Unwrapped(I16F16::MIN).abs(); /// ``` #[inline] #[track_caller] #[must_use] pub fn abs(self) -> Unwrapped { Unwrapped(self.0.unwrapped_abs()) } /// Returns a number representing the sign of `self`. /// /// See also /// FixedI32::[unwrapped\_signum][FixedI32::unwrapped_signum]. /// /// # Panics /// /// 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. /// /// # Examples /// /// ```rust /// use fixed::types::I16F16; /// use fixed::Unwrapped; /// assert_eq!(Unwrapped(::from_num(-3.9)).signum(), Unwrapped(I16F16::NEG_ONE)); /// assert_eq!(Unwrapped(::ZERO).signum(), Unwrapped(I16F16::ZERO)); /// assert_eq!(Unwrapped(::from_num(3.9)).signum(), Unwrapped(I16F16::ONE)); /// ``` /// /// The following panics because of overflow. /// /// ```should_panic /// use fixed::types::I1F31; /// use fixed::Unwrapped; /// let _overflow = Unwrapped(::from_num(0.5)).signum(); /// ``` #[inline] #[track_caller] #[must_use] pub fn signum(self) -> Unwrapped { Unwrapped(self.0.unwrapped_signum()) } /// Addition with an unsigned fixed-point number. /// /// See also /// FixedI32::[unwrapped\_add\_unsigned][FixedI32::unwrapped_add_unsigned]. /// /// # Panics /// /// Panics if the result does not fit. /// /// # Examples /// /// ```rust /// use fixed::types::{I16F16, U16F16}; /// use fixed::Unwrapped; /// assert_eq!( /// Unwrapped::::from_num(-5).add_unsigned(U16F16::from_num(3)), /// Unwrapped::::from_num(-2) /// ); /// ``` /// /// The following panics because of overflow. /// /// ```rust,should_panic /// use fixed::types::{I16F16, U16F16}; /// use fixed::Unwrapped; /// let _overflow = Unwrapped::::ZERO.add_unsigned(U16F16::MAX); /// ``` #[inline] #[track_caller] #[must_use] pub fn add_unsigned(self, rhs: F::Unsigned) -> Unwrapped { Unwrapped(self.0.unwrapped_add_unsigned(rhs)) } /// Subtraction with an unsigned fixed-point number. /// /// See also /// FixedI32::[unwrapped\_sub\_unsigned][FixedI32::unwrapped_sub_unsigned]. /// /// # Panics /// /// Panics if the result does not fit. /// /// # Examples /// /// ```rust /// use fixed::types::{I16F16, U16F16}; /// use fixed::Unwrapped; /// assert_eq!( /// Unwrapped::::from_num(3).sub_unsigned(U16F16::from_num(5)), /// Unwrapped::::from_num(-2) /// ); /// ``` /// /// The following panics because of overflow. /// /// ```rust,should_panic /// use fixed::types::{I16F16, U16F16}; /// use fixed::Unwrapped; /// let _overflow = Unwrapped::::ZERO.sub_unsigned(U16F16::MAX); /// ``` #[inline] #[track_caller] #[must_use] pub fn sub_unsigned(self, rhs: F::Unsigned) -> Unwrapped { Unwrapped(self.0.unwrapped_sub_unsigned(rhs)) } } impl Unwrapped { /// Returns the bit pattern of `self` reinterpreted as a signed fixed-point /// number of the same size. /// /// See also FixedU32::[cast\_signed][FixedU32::cast_signed]. /// /// # Examples /// /// ```rust /// use fixed::types::{I16F16, U16F16}; /// use fixed::Unwrapped; /// /// let n = Unwrapped(U16F16::MAX); /// assert_eq!(n.cast_signed(), Unwrapped(-I16F16::DELTA)); /// ``` #[must_use] #[inline] pub fn cast_signed(self) -> Unwrapped { Unwrapped(self.0.cast_signed()) } /// Returns the number of bits required to represent the value. /// /// See also /// FixedU32::[significant\_bits][FixedU32::significant_bits]. /// /// # Examples /// /// ```rust /// use fixed::types::U4F4; /// use fixed::Unwrapped; /// assert_eq!(Unwrapped(U4F4::from_num(0)).significant_bits(), 0); // “____.____” /// assert_eq!(Unwrapped(U4F4::from_num(0.0625)).significant_bits(), 1); // “____.___1” /// assert_eq!(Unwrapped(U4F4::from_num(1)).significant_bits(), 5); // “___1.0000” /// assert_eq!(Unwrapped(U4F4::from_num(3)).significant_bits(), 6); // “__11.0000” /// ``` #[inline] pub fn significant_bits(self) -> u32 { self.0.significant_bits() } /// Returns [`true`] if the fixed-point number is /// 2k for some integer k. /// /// See also /// FixedU32::[is\_power\_of\_two][FixedU32::is_power_of_two]. /// /// # Examples /// /// ```rust /// use fixed::types::U16F16; /// use fixed::Unwrapped; /// assert!(Unwrapped(U16F16::from_num(0.5)).is_power_of_two()); /// assert!(Unwrapped(U16F16::from_num(4)).is_power_of_two()); /// assert!(!Unwrapped(U16F16::from_num(5)).is_power_of_two()); /// ``` #[inline] pub fn is_power_of_two(self) -> bool { self.0.is_power_of_two() } /// Returns the highest one in the binary representation, or zero /// if `self` is zero. /// /// If `self` > 0, the highest one is equal to the largest power /// of two that is ≤ `self`. /// /// See also FixedU32::[highest\_one][FixedU32::highest_one]. /// /// # Examples /// /// ```rust /// use fixed::types::U16F16; /// use fixed::Unwrapped; /// type T = Unwrapped; /// assert_eq!(T::from_bits(0b11_0010).highest_one(), T::from_bits(0b10_0000)); /// assert_eq!(T::from_num(0.3).highest_one(), T::from_num(0.25)); /// assert_eq!(T::from_num(4).highest_one(), T::from_num(4)); /// assert_eq!(T::from_num(6.5).highest_one(), T::from_num(4)); /// assert_eq!(T::ZERO.highest_one(), T::ZERO); /// ``` #[inline] #[must_use] pub fn highest_one(self) -> Unwrapped { Unwrapped(self.0.highest_one()) } /// Returns the smallest power of two that is ≥ `self`. /// /// See also /// FixedU32::[unwrapped\_next\_power\_of\_two][FixedU32::unwrapped_next_power_of_two]. /// /// # Panics /// /// Panics if the next power of two is too large to fit. /// /// # Examples /// /// ```rust /// use fixed::types::U16F16; /// use fixed::Unwrapped; /// type T = Unwrapped; /// assert_eq!(T::from_bits(0b11_0010).next_power_of_two(), T::from_bits(0b100_0000)); /// assert_eq!(T::from_num(0.3).next_power_of_two(), T::from_num(0.5)); /// assert_eq!(T::from_num(4).next_power_of_two(), T::from_num(4)); /// assert_eq!(T::from_num(6.5).next_power_of_two(), T::from_num(8)); /// ``` /// /// The following panics because of overflow. /// /// ```should_panic /// use fixed::types::U16F16; /// use fixed::Unwrapped; /// let _overflow = Unwrapped(U16F16::MAX).next_power_of_two(); /// ``` #[inline] #[track_caller] #[must_use] pub fn next_power_of_two(self) -> Unwrapped { Unwrapped(self.0.unwrapped_next_power_of_two()) } /// Addition with an signed fixed-point number. /// /// See also /// FixedU32::[unwrapped\_add\_signed][FixedU32::unwrapped_add_signed]. /// /// # Panics /// /// Panics if the result does not fit. /// /// # Examples /// /// ```rust /// use fixed::types::{I16F16, U16F16}; /// use fixed::Unwrapped; /// assert_eq!( /// Unwrapped::::from_num(5).add_signed(I16F16::from_num(-3)), /// Unwrapped::::from_num(2) /// ); /// ``` /// /// The following panics because of overflow. /// /// ```rust,should_panic /// use fixed::types::{I16F16, U16F16}; /// use fixed::Unwrapped; /// let _overflow = Unwrapped::::ZERO.add_signed(-I16F16::DELTA); /// ``` #[inline] #[track_caller] #[must_use] pub fn add_signed(self, rhs: F::Signed) -> Unwrapped { Unwrapped(self.0.unwrapped_add_signed(rhs)) } /// Subtraction with an signed fixed-point number. /// /// See also /// FixedU32::[unwrapped\_sub\_signed][FixedU32::unwrapped_sub_signed]. /// /// # Panics /// /// Panics if the result does not fit. /// /// # Examples /// /// ```rust /// use fixed::types::{I16F16, U16F16}; /// use fixed::Unwrapped; /// assert_eq!( /// Unwrapped::::from_num(5).sub_signed(I16F16::from_num(-3)), /// Unwrapped::::from_num(8) /// ); /// ``` /// /// The following panics because of overflow. /// /// ```rust,should_panic /// use fixed::types::{I16F16, U16F16}; /// use fixed::Unwrapped; /// let _overflow = Unwrapped::::ZERO.sub_signed(I16F16::DELTA); /// ``` #[inline] #[track_caller] #[must_use] pub fn sub_signed(self, rhs: F::Signed) -> Unwrapped { Unwrapped(self.0.unwrapped_sub_signed(rhs)) } } impl Display for Unwrapped { #[inline] fn fmt(&self, f: &mut Formatter) -> FmtResult { Display::fmt(&self.0, f) } } impl Debug for Unwrapped { #[inline] fn fmt(&self, f: &mut Formatter) -> FmtResult { Debug::fmt(&self.0, f) } } impl Binary for Unwrapped { #[inline] fn fmt(&self, f: &mut Formatter) -> FmtResult { Binary::fmt(&self.0, f) } } impl Octal for Unwrapped { #[inline] fn fmt(&self, f: &mut Formatter) -> FmtResult { Octal::fmt(&self.0, f) } } impl LowerHex for Unwrapped { #[inline] fn fmt(&self, f: &mut Formatter) -> FmtResult { LowerHex::fmt(&self.0, f) } } impl UpperHex for Unwrapped { #[inline] fn fmt(&self, f: &mut Formatter) -> FmtResult { UpperHex::fmt(&self.0, f) } } impl LowerExp for Unwrapped { #[inline] fn fmt(&self, f: &mut Formatter) -> FmtResult { LowerExp::fmt(&self.0, f) } } impl UpperExp for Unwrapped { #[inline] fn fmt(&self, f: &mut Formatter) -> FmtResult { UpperExp::fmt(&self.0, f) } } impl From for Unwrapped { /// Wraps a fixed-point number. #[inline] fn from(src: F) -> Unwrapped { Unwrapped(src) } } impl FromStr for Unwrapped { type Err = ParseFixedError; /// Parses a string slice containing decimal digits to return a fixed-point number. /// /// Rounding is to the nearest, with ties rounded to even. /// /// This method either returns [`Ok`] or panics, and never returns [`Err`]. /// The inherent method /// [Unwrapped]<F>::[from\_str\_dec][Unwrapped::from_str_dec] /// returns the value directly instead of a [`Result`]. /// /// # Panics /// /// Panics if the value does not fit or if there is a parsing error. #[inline] #[track_caller] fn from_str(s: &str) -> Result { Ok(Unwrapped(F::unwrapped_from_str(s))) } } macro_rules! op { ($unwrapped:ident, $Op:ident $op:ident, $OpAssign:ident $op_assign:ident) => { impl $Op> for Unwrapped { type Output = Unwrapped; #[inline] #[track_caller] fn $op(self, other: Unwrapped) -> Unwrapped { Unwrapped((self.0).$unwrapped(other.0)) } } impl $Op> for &Unwrapped { type Output = Unwrapped; #[inline] #[track_caller] fn $op(self, other: Unwrapped) -> Unwrapped { Unwrapped((self.0).$unwrapped(other.0)) } } impl $Op<&Unwrapped> for Unwrapped { type Output = Unwrapped; #[inline] #[track_caller] fn $op(self, other: &Unwrapped) -> Unwrapped { Unwrapped((self.0).$unwrapped(other.0)) } } impl $Op<&Unwrapped> for &Unwrapped { type Output = Unwrapped; #[inline] #[track_caller] fn $op(self, other: &Unwrapped) -> Unwrapped { Unwrapped((self.0).$unwrapped(other.0)) } } impl $OpAssign> for Unwrapped { #[inline] #[track_caller] fn $op_assign(&mut self, other: Unwrapped) { self.0 = (self.0).$unwrapped(other.0); } } impl $OpAssign<&Unwrapped> for Unwrapped { #[inline] #[track_caller] fn $op_assign(&mut self, other: &Unwrapped) { self.0 = (self.0).$unwrapped(other.0); } } impl $OpAssign for Unwrapped { #[inline] #[track_caller] fn $op_assign(&mut self, other: F) { self.0 = (self.0).$unwrapped(other); } } impl $OpAssign<&F> for Unwrapped { #[inline] #[track_caller] fn $op_assign(&mut self, other: &F) { self.0 = (self.0).$unwrapped(*other); } } }; } macro_rules! op_bitwise { ($Op:ident $op:ident, $OpAssign:ident $op_assign:ident) => { impl $Op> for Unwrapped where F: $Op, { type Output = Unwrapped; #[inline] fn $op(self, other: Unwrapped) -> Unwrapped { Unwrapped((self.0).$op(other.0)) } } impl $Op> for &Unwrapped where for<'a> &'a F: $Op, { type Output = Unwrapped; #[inline] fn $op(self, other: Unwrapped) -> Unwrapped { Unwrapped((self.0).$op(other.0)) } } impl $Op<&Unwrapped> for Unwrapped where for<'a> F: $Op<&'a F, Output = F>, { type Output = Unwrapped; #[inline] fn $op(self, other: &Unwrapped) -> Unwrapped { Unwrapped((self.0).$op(&other.0)) } } impl $Op<&Unwrapped> for &Unwrapped where for<'a, 'b> &'a F: $Op<&'b F, Output = F>, { type Output = Unwrapped; #[inline] fn $op(self, other: &Unwrapped) -> Unwrapped { Unwrapped((self.0).$op(&other.0)) } } impl $OpAssign> for Unwrapped where F: $OpAssign, { #[inline] fn $op_assign(&mut self, other: Unwrapped) { (self.0).$op_assign(other.0); } } impl $OpAssign<&Unwrapped> for Unwrapped where for<'a> F: $OpAssign<&'a F>, { #[inline] fn $op_assign(&mut self, other: &Unwrapped) { (self.0).$op_assign(&other.0); } } impl $OpAssign for Unwrapped where F: $OpAssign, { #[inline] fn $op_assign(&mut self, other: F) { (self.0).$op_assign(other); } } impl $OpAssign<&F> for Unwrapped where for<'a> F: $OpAssign<&'a F>, { #[inline] fn $op_assign(&mut self, other: &F) { (self.0).$op_assign(other); } } }; } macro_rules! op_shift { ( $Op:ident $op:ident, $OpAssign:ident $op_assign:ident; $($Rhs:ident),* ) => { $( impl $Op<$Rhs> for Unwrapped where F: $Op, { type Output = Unwrapped; #[inline] #[track_caller] fn $op(self, other: $Rhs) -> Unwrapped { let nbits = size_of::() as u32 * 8; let checked = other as u32 % nbits; assert!(checked as $Rhs == other, "overflow"); Unwrapped((self.0).$op(checked)) } } impl $Op<$Rhs> for &Unwrapped where for<'a> &'a F: $Op, { type Output = Unwrapped; #[inline] #[track_caller] fn $op(self, other: $Rhs) -> Unwrapped { let nbits = size_of::() as u32 * 8; let checked = other as u32 % nbits; assert!(checked as $Rhs == other, "overflow"); Unwrapped((self.0).$op(checked)) } } impl $Op<&$Rhs> for Unwrapped where F: $Op, { type Output = Unwrapped; #[inline] #[track_caller] fn $op(self, other: &$Rhs) -> Unwrapped { let nbits = size_of::() as u32 * 8; let checked = *other as u32 % nbits; assert!(checked as $Rhs == *other, "overflow"); Unwrapped((self.0).$op(checked)) } } impl $Op<&$Rhs> for &Unwrapped where for<'a> &'a F: $Op, { type Output = Unwrapped; #[inline] #[track_caller] fn $op(self, other: &$Rhs) -> Unwrapped { let nbits = size_of::() as u32 * 8; let checked = *other as u32 % nbits; assert!(checked as $Rhs == *other, "overflow"); Unwrapped((self.0).$op(checked)) } } impl $OpAssign<$Rhs> for Unwrapped where F: $OpAssign, { #[inline] #[track_caller] fn $op_assign(&mut self, other: $Rhs) { let nbits = size_of::() as u32 * 8; let checked = other as u32 % nbits; assert!(checked as $Rhs == other, "overflow"); (self.0).$op_assign(checked); } } impl $OpAssign<&$Rhs> for Unwrapped where F: $OpAssign, { #[inline] #[track_caller] fn $op_assign(&mut self, other: &$Rhs) { let nbits = size_of::() as u32 * 8; let checked = *other as u32 % nbits; assert!(checked as $Rhs == *other, "overflow"); (self.0).$op_assign(checked); } } )* }; } impl Neg for Unwrapped { type Output = Unwrapped; #[inline] #[track_caller] fn neg(self) -> Unwrapped { Unwrapped((self.0).unwrapped_neg()) } } impl Neg for &Unwrapped { type Output = Unwrapped; #[inline] #[track_caller] fn neg(self) -> Unwrapped { Unwrapped((self.0).unwrapped_neg()) } } op! { unwrapped_add, Add add, AddAssign add_assign } op! { unwrapped_sub, Sub sub, SubAssign sub_assign } op! { unwrapped_mul, Mul mul, MulAssign mul_assign } op! { unwrapped_div, Div div, DivAssign div_assign } op! { unwrapped_rem, Rem rem, RemAssign rem_assign } impl Not for Unwrapped where F: Not, { type Output = Unwrapped; #[inline] fn not(self) -> Unwrapped { Unwrapped((self.0).not()) } } impl Not for &Unwrapped where for<'a> &'a F: Not, { type Output = Unwrapped; #[inline] fn not(self) -> Unwrapped { Unwrapped((self.0).not()) } } op_bitwise! { BitAnd bitand, BitAndAssign bitand_assign } op_bitwise! { BitOr bitor, BitOrAssign bitor_assign } op_bitwise! { BitXor bitxor, BitXorAssign bitxor_assign } op_shift! { Shl shl, ShlAssign shl_assign; i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize } op_shift! { Shr shr, ShrAssign shr_assign; i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize } impl Sum> for Unwrapped { #[track_caller] fn sum(iter: I) -> Unwrapped where I: Iterator>, { iter.fold(Unwrapped(F::ZERO), Add::add) } } impl<'a, F: 'a + Fixed> Sum<&'a Unwrapped> for Unwrapped { #[track_caller] fn sum(iter: I) -> Unwrapped where I: Iterator>, { iter.fold(Unwrapped(F::ZERO), Add::add) } } impl Product> for Unwrapped { #[track_caller] fn product(mut iter: I) -> Unwrapped where I: Iterator>, { match iter.next() { None => match 1.overflowing_to_fixed() { (_, true) => panic!("overflow"), (ans, false) => Unwrapped(ans), }, Some(first) => iter.fold(first, Mul::mul), } } } impl<'a, F: 'a + Fixed> Product<&'a Unwrapped> for Unwrapped { #[track_caller] fn product(mut iter: I) -> Unwrapped where I: Iterator>, { match iter.next() { None => match 1.overflowing_to_fixed() { (_, true) => panic!("overflow"), (ans, false) => Unwrapped(ans), }, Some(first) => iter.fold(*first, Mul::mul), } } } // The following cannot be implemented for Unwrapped where F: Fixed, // otherwise there will be a conflicting implementation error. For // example we cannot implement both these without triggering E0119: // // impl Op for Unwrapped { /* ... */ } // impl Op<&F::Bits> for Unwrapped { /* ... */ } // // To work around this, we provide implementations like this: // // impl Op for Unwrapped> { /* ... */ } // impl Op<&i8> for Unwrapped> { /* ... */ } // impl Op for Unwrapped> { /* ... */ } // impl Op<&i16> for Unwrapped> { /* ... */ } // ... macro_rules! op_bits { ( $Fixed:ident($Bits:ident $(, $LeEqU:ident)*)::$unwrapped:ident, $Op:ident $op:ident, $OpAssign:ident $op_assign:ident ) => { impl $Op<$Bits> for Unwrapped<$Fixed> { type Output = Unwrapped<$Fixed>; #[inline] #[track_caller] fn $op(self, other: $Bits) -> Unwrapped<$Fixed> { Unwrapped((self.0).$unwrapped(other)) } } impl $Op<$Bits> for &Unwrapped<$Fixed> { type Output = Unwrapped<$Fixed>; #[inline] #[track_caller] fn $op(self, other: $Bits) -> Unwrapped<$Fixed> { Unwrapped((self.0).$unwrapped(other)) } } impl $Op<&$Bits> for Unwrapped<$Fixed> { type Output = Unwrapped<$Fixed>; #[inline] #[track_caller] fn $op(self, other: &$Bits) -> Unwrapped<$Fixed> { Unwrapped((self.0).$unwrapped(*other)) } } impl $Op<&$Bits> for &Unwrapped<$Fixed> { type Output = Unwrapped<$Fixed>; #[inline] #[track_caller] fn $op(self, other: &$Bits) -> Unwrapped<$Fixed> { Unwrapped((self.0).$unwrapped(*other)) } } impl $OpAssign<$Bits> for Unwrapped<$Fixed> { #[inline] #[track_caller] fn $op_assign(&mut self, other: $Bits) { self.0 = (self.0).$unwrapped(other); } } impl $OpAssign<&$Bits> for Unwrapped<$Fixed> { #[inline] #[track_caller] fn $op_assign(&mut self, other: &$Bits) { self.0 = (self.0).$unwrapped(*other); } } }; } macro_rules! ops { ($Fixed:ident($Bits:ident, $LeEqU:ident)) => { op_bits! { $Fixed($Bits)::unwrapped_mul_int, Mul mul, MulAssign mul_assign } op_bits! { $Fixed($Bits)::unwrapped_div_int, Div div, DivAssign div_assign } op_bits! { $Fixed($Bits, $LeEqU)::unwrapped_rem_int, Rem rem, RemAssign rem_assign } }; } ops! { FixedI8(i8, LeEqU8) } ops! { FixedI16(i16, LeEqU16) } ops! { FixedI32(i32, LeEqU32) } ops! { FixedI64(i64, LeEqU64) } ops! { FixedI128(i128, LeEqU128) } ops! { FixedU8(u8, LeEqU8) } ops! { FixedU16(u16, LeEqU16) } ops! { FixedU32(u32, LeEqU32) } ops! { FixedU64(u64, LeEqU64) } ops! { FixedU128(u128, LeEqU128) }