pub struct Posit<const N: u32, const ES: u32, Int: Int>(/* private fields */);Expand description
A posit floating point number with N bits and ES exponent bits, using Int as its
underlying type.
If Int = iX, then N must be in the range 3 ..= X, and ES must be in the range 0 .. N. If this is not the case, a compile-time error will be raised.
Type aliases are provided at the crate root for the posit types defined in the standard.
§Example
// A 32-bit posit with 2-bit exponent field, represented in a 32-bit machine type.
type Foo = Posit<32, 2, i32>;
// A 6-bit posit with 1-bit exponent field, represented in an 8-bit machine type.
type Bar = Posit<6, 1, i8>;The standard p8, p16, p32, and
p64 types are simply type aliases for Posit<X, 2, iX>.
Note that Posit will have the same size (and alignment) as its Int parameter, so it’s
currently not possible to create e.g. a 4-bit posit that only takes 4 bits in memory.
If the combination of parameters is invalid, the code will not compile.
type Foo = Posit<40, 2, i32>; // N=40 too large for i32type Bar = Posit<1, 0, i8>; // N=1 can't be ≤ 2type Baz = Posit<32, 33, i32>; // ES=33 too big for N=32Implementations§
Source§impl<const N: u32, const ES: u32, Int: Int> Posit<N, ES, Int>
impl<const N: u32, const ES: u32, Int: Int> Posit<N, ES, Int>
Sourcepub const BITS: u32
pub const BITS: u32
The size of this Posit type in bits (i.e. parameter N).
Note: this is the logical size, not necessarily the size of the underlying type.
§Example
assert_eq!(p16::BITS, 16); // Standard posit
assert_eq!(Posit::<20, 1, i32>::BITS, 20); // Non-standard positSourcepub const ES: u32
pub const ES: u32
The number of exponent bits (i.e. parameter ES).
§Example
assert_eq!(p16::ES, 2); // Standard posit
assert_eq!(Posit::<20, 1, i32>::ES, 1); // Non-standard positSourcepub const fn to_bits(self) -> Int
pub const fn to_bits(self) -> Int
Return the underlying bit representation of self as a machine int. Bits higher
(more significant) than the lowest N bits, if any, are set as equal to the N-1th bit
(i.e. sign-extended).
§Example
assert_eq!(0b00000000, p8::ZERO.to_bits());
assert_eq!(0b01000000, p8::ONE.to_bits());
assert_eq!(0b01111111, p8::MAX.to_bits());
assert_eq!(0b00000001, p8::MIN_POSITIVE.to_bits());
assert_eq!(0b11000000, p8::MINUS_ONE.to_bits());
assert_eq!(0b10000001, p8::MIN.to_bits());
assert_eq!(0b11111111, p8::MAX_NEGATIVE.to_bits());
assert_eq!(0b10000000, p8::NAR.to_bits());Sourcepub fn from_bits(bits: Int) -> Self
pub fn from_bits(bits: Int) -> Self
Construct a posit from its raw bit representation. Bits higher (more significant) than the
lowest N bits, if any, are ignored.
§Example
assert_eq!(p8::from_bits(0), p8::ZERO);
assert_eq!(p8::from_bits(1), p8::MIN_POSITIVE);
assert_eq!(p8::from_bits(i8::MAX), p8::MAX);
assert_eq!(p8::from_bits(0b0_10_01_011), 2.75.round_into());
assert_eq!(p8::from_bits(0b1_110_00_01), (-0.0546875).round_into());Sourcepub const unsafe fn from_bits_unchecked(bits: Int) -> Self
pub const unsafe fn from_bits_unchecked(bits: Int) -> Self
As Self::from_bits, but does not check that bits is a valid bit pattern for Self.
§Safety
bits has to be a result of a Self::to_bits call, i.e. it has to be in the range
-1 << (N-1) ..= 1 << (N-1) - 1, or calling this function is undefined behaviour. Note
that if Int::BITS == Self::BITS this always holds.
§Example
type Posit4 = Posit<4, 1, i8>;
assert_eq!(Posit4::from_bits(0b0000_0100), Posit4::ONE);
assert_eq!(Posit4::from_bits(0b1111_1000), Posit4::NAR);but the following would not be valid as the bits are not in a valid range (i.e. not sign-extended past 4 bits).
Posit4::from_bits(0b0110_0100); // Undefined behaviour!Source§impl<const N: u32, const ES: u32, Int: Int> Posit<N, ES, Int>
impl<const N: u32, const ES: u32, Int: Int> Posit<N, ES, Int>
Sourcepub const MIN: Self
pub const MIN: Self
Smallest representable value, equal to -MAX.
Not to be confused with the smallest absolute value, i.e. Self::MIN_POSITIVE.
Sourcepub const MIN_POSITIVE: Self
pub const MIN_POSITIVE: Self
Smallest positive value, equal to -MAX_NEGATIVE.
Sourcepub const MAX_NEGATIVE: Self
pub const MAX_NEGATIVE: Self
Largest negative value, equal to -MIN_POSITIVE.
Sourcepub const MIN_EXP: Int
pub const MIN_EXP: Int
The minimum exponent; Self::MIN_POSITIVE = 2 Self::MIN_EXP.
Sourcepub const MAX_EXP: Int
pub const MAX_EXP: Int
The maximum exponent; Self::MAX_NEGATIVE = 2 Self::MAX_EXP.
Source§impl<const N: u32, const ES: u32, Int: Int> Posit<N, ES, Int>
impl<const N: u32, const ES: u32, Int: Int> Posit<N, ES, Int>
Sourcepub fn next(self) -> Self
pub fn next(self) -> Self
Returns the posit value of the lexicographic successor of self’s representation.
Note that, unlike every other function of a posit, next and prior do not produce a
NaR output on a NaR input.
Standard: “next”.
§Example
assert_eq!(p8::round_from(1.).next(), p8::round_from(1.125));
assert_eq!(p8::round_from(128.).next(), p8::round_from(160.));
assert_eq!(p8::MAX.next(), p8::NAR);
assert_eq!(p8::NAR.next(), p8::MIN);Sourcepub fn prior(self) -> Self
pub fn prior(self) -> Self
Returns the posit value of the lexicographic predecessor of self’s representation.
Note that, unlike every other function of a posit, next and prior do not produce a
NaR output on a NaR input.
Standard: “prior”.
§Example
assert_eq!(p8::round_from(1.).prior(), p8::round_from(0.9375));
assert_eq!(p8::round_from(128.).prior(), p8::round_from(112.));
assert_eq!(p8::MIN.prior(), p8::NAR);
assert_eq!(p8::NAR.prior(), p8::MAX);Source§impl<const N: u32, const ES: u32, Int: Int> Posit<N, ES, Int>
impl<const N: u32, const ES: u32, Int: Int> Posit<N, ES, Int>
Sourcepub fn sign(self) -> Self
pub fn sign(self) -> Self
Return 1 if self > 0, -1 if self < 0, 0 if
self == 0, and NaR if self == NaR.
Standard: “sign”.
§Example
assert_eq!(p16::round_from(2).sign(), p16::round_from(1));
assert_eq!(p16::round_from(-3).sign(), p16::round_from(-1));
assert_eq!(p16::round_from(0).sign(), p16::round_from(0));
assert_eq!(p16::NAR.sign(), p16::NAR);Source§impl<const N: u32, const ES: u32, Int: Int> Posit<N, ES, Int>
impl<const N: u32, const ES: u32, Int: Int> Posit<N, ES, Int>
Sourcepub fn nearest_int(self) -> Self
pub fn nearest_int(self) -> Self
Returns the integer-valued posit nearest to self, and the nearest even integer-valued posit
if two integers are equally near.
Standard: “nearestInt”.
§Example
assert_eq!(p32::round_from(3.1).nearest_int(), p32::round_from(3));
assert_eq!(p32::round_from(3.5).nearest_int(), p32::round_from(4));
assert_eq!(p32::round_from(3.9).nearest_int(), p32::round_from(4));Source§impl<const N: u32, const ES: u32, Int: Int> Posit<N, ES, Int>
impl<const N: u32, const ES: u32, Int: Int> Posit<N, ES, Int>
Sourcepub fn convert<const N2: u32, const ES2: u32, Int2: Int>(
self,
) -> Posit<N2, ES2, Int2>
pub fn convert<const N2: u32, const ES2: u32, Int2: Int>( self, ) -> Posit<N2, ES2, Int2>
Convert a posit into a different one, rounding according to the standard.
If the source and target types have the same ES (i.e. ES == ES2), such as is the case with
the standard types, this is especially fast. This enables easy and seamless mixed-precision
arithmetic.
§Examples
let pi: p64 = core::f64::consts::PI.round_into();
let two: p8 = 2.round_into();
let tau: p64 = pi * two.convert();
assert_eq!(tau, core::f64::consts::TAU.round_into())Trait Implementations§
Source§impl<const N: u32, const ES: u32, Int: Int> AddAssign<&Posit<N, ES, Int>> for Posit<N, ES, Int>
impl<const N: u32, const ES: u32, Int: Int> AddAssign<&Posit<N, ES, Int>> for Posit<N, ES, Int>
Source§fn add_assign(&mut self, rhs: &Posit<N, ES, Int>)
fn add_assign(&mut self, rhs: &Posit<N, ES, Int>)
+= operation. Read moreSource§impl<const N: u32, const ES: u32, Int: Int, const SIZE: usize> AddAssign<&Posit<N, ES, Int>> for Quire<N, ES, SIZE>
impl<const N: u32, const ES: u32, Int: Int, const SIZE: usize> AddAssign<&Posit<N, ES, Int>> for Quire<N, ES, SIZE>
Source§impl<const N: u32, const ES: u32, Int: Int, const SIZE: usize> AddAssign<Posit<N, ES, Int>> for Quire<N, ES, SIZE>
impl<const N: u32, const ES: u32, Int: Int, const SIZE: usize> AddAssign<Posit<N, ES, Int>> for Quire<N, ES, SIZE>
Source§impl<const N: u32, const ES: u32, Int: Int> AddAssign for Posit<N, ES, Int>
impl<const N: u32, const ES: u32, Int: Int> AddAssign for Posit<N, ES, Int>
Source§fn add_assign(&mut self, rhs: Posit<N, ES, Int>)
fn add_assign(&mut self, rhs: Posit<N, ES, Int>)
+= operation. Read moreSource§impl<const N: u32, const ES: u32, Int: Int> DivAssign<&Posit<N, ES, Int>> for Posit<N, ES, Int>
impl<const N: u32, const ES: u32, Int: Int> DivAssign<&Posit<N, ES, Int>> for Posit<N, ES, Int>
Source§fn div_assign(&mut self, rhs: &Posit<N, ES, Int>)
fn div_assign(&mut self, rhs: &Posit<N, ES, Int>)
/= operation. Read moreSource§impl<const N: u32, const ES: u32, Int: Int> DivAssign for Posit<N, ES, Int>
impl<const N: u32, const ES: u32, Int: Int> DivAssign for Posit<N, ES, Int>
Source§fn div_assign(&mut self, rhs: Posit<N, ES, Int>)
fn div_assign(&mut self, rhs: Posit<N, ES, Int>)
/= operation. Read moreSource§impl<const N: u32, const ES: u32, Int: Int, const SIZE: usize> From<Posit<N, ES, Int>> for Quire<N, ES, SIZE>
impl<const N: u32, const ES: u32, Int: Int, const SIZE: usize> From<Posit<N, ES, Int>> for Quire<N, ES, SIZE>
Source§impl<const N: u32, const ES: u32, Int: Int> MulAssign<&Posit<N, ES, Int>> for Posit<N, ES, Int>
impl<const N: u32, const ES: u32, Int: Int> MulAssign<&Posit<N, ES, Int>> for Posit<N, ES, Int>
Source§fn mul_assign(&mut self, rhs: &Posit<N, ES, Int>)
fn mul_assign(&mut self, rhs: &Posit<N, ES, Int>)
*= operation. Read moreSource§impl<const N: u32, const ES: u32, Int: Int> MulAssign for Posit<N, ES, Int>
impl<const N: u32, const ES: u32, Int: Int> MulAssign for Posit<N, ES, Int>
Source§fn mul_assign(&mut self, rhs: Posit<N, ES, Int>)
fn mul_assign(&mut self, rhs: Posit<N, ES, Int>)
*= operation. Read moreSource§impl<const N: u32, const ES: u32, Int: Int> Ord for Posit<N, ES, Int>
impl<const N: u32, const ES: u32, Int: Int> Ord for Posit<N, ES, Int>
Source§impl<const N: u32, const ES: u32, Int: Int> PartialEq for Posit<N, ES, Int>
Note that, unlike IEEE floats, NaR is equal to itself (and different from any
other value).
impl<const N: u32, const ES: u32, Int: Int> PartialEq for Posit<N, ES, Int>
Note that, unlike IEEE floats, NaR is equal to itself (and different from any other value).
§Example
assert!(p32::NAR == p32::NAR);
assert!(f32::NAN != f32::NAN);
assert!(p32::NAR != 3.round_into());
assert!(f32::NAN != 3.);Source§impl<const N: u32, const ES: u32, Int: Int> PartialOrd for Posit<N, ES, Int>
impl<const N: u32, const ES: u32, Int: Int> PartialOrd for Posit<N, ES, Int>
§Example
assert_eq!(p32::NAR.partial_cmp(&p32::NAR), Some(Ordering::Equal));
assert_eq!(f32::NAN.partial_cmp(&f32::NAN), None);
assert!(p32::NAR < p32::round_from(-3));
assert!(!(f32::NAN < -3.) && !(f32::NAN >= -3.));Source§impl<const N: u32, const ES: u32, Int: Int, const SIZE: usize> RoundFrom<&Quire<N, ES, SIZE>> for Posit<N, ES, Int>
impl<const N: u32, const ES: u32, Int: Int, const SIZE: usize> RoundFrom<&Quire<N, ES, SIZE>> for Posit<N, ES, Int>
Source§fn round_from(value: &Quire<N, ES, SIZE>) -> Self
fn round_from(value: &Quire<N, ES, SIZE>) -> Self
Round a quire back to a posit. This is the final step to do after a series of calculations in the quire, and the only step that actually rounds.
Standard: “qToP”.
§Example
let mut quire = q16::from(p16::MAX);
quire += p16::round_from(0.1);
quire -= p16::MAX;
let result: p16 = (&quire).round_into();
assert_eq!(result, p16::round_from(0.1))Source§impl<const N: u32, const ES: u32, Int: Int> RoundFrom<Posit<N, ES, Int>> for f32
impl<const N: u32, const ES: u32, Int: Int> RoundFrom<Posit<N, ES, Int>> for f32
Source§fn round_from(value: Posit<N, ES, Int>) -> Self
fn round_from(value: Posit<N, ES, Int>) -> Self
Convert a Posit into an f32, rounding according to the standard:
- If the value is 0, the result is
+0.0. - If the value is NaR, the result is a quiet NaN.
- Otherwise, the posit value is rounded to a float (if necessary) using the “roundTiesToEven” rule in the IEEE 754 standard (in short: underflow to ±0, overflow to ±∞, otherwise round to nearest, in case of a tie round to nearest even bit pattern).
Source§impl<const N: u32, const ES: u32, Int: Int> RoundFrom<Posit<N, ES, Int>> for f64
impl<const N: u32, const ES: u32, Int: Int> RoundFrom<Posit<N, ES, Int>> for f64
Source§fn round_from(value: Posit<N, ES, Int>) -> Self
fn round_from(value: Posit<N, ES, Int>) -> Self
Convert a Posit into an f64, rounding according to the standard:
- If the value is 0, the result is
+0.0. - If the value is NaR, the result is a quiet NaN.
- Otherwise, the posit value is rounded to a float (if necessary) using the “roundTiesToEven” rule in the IEEE 754 standard (in short: underflow to ±0, overflow to ±∞, otherwise round to nearest, in case of a tie round to nearest even bit pattern).
Source§impl<const N: u32, const ES: u32, Int: Int> RoundFrom<Posit<N, ES, Int>> for i128
impl<const N: u32, const ES: u32, Int: Int> RoundFrom<Posit<N, ES, Int>> for i128
Source§fn round_from(value: Posit<N, ES, Int>) -> Self
fn round_from(value: Posit<N, ES, Int>) -> Self
Convert a Posit into an i128, rounding according to the standard:
Source§impl<const N: u32, const ES: u32, Int: Int> RoundFrom<Posit<N, ES, Int>> for i16
impl<const N: u32, const ES: u32, Int: Int> RoundFrom<Posit<N, ES, Int>> for i16
Source§fn round_from(value: Posit<N, ES, Int>) -> Self
fn round_from(value: Posit<N, ES, Int>) -> Self
Convert a Posit into an i16, rounding according to the standard:
Source§impl<const N: u32, const ES: u32, Int: Int> RoundFrom<Posit<N, ES, Int>> for i32
impl<const N: u32, const ES: u32, Int: Int> RoundFrom<Posit<N, ES, Int>> for i32
Source§fn round_from(value: Posit<N, ES, Int>) -> Self
fn round_from(value: Posit<N, ES, Int>) -> Self
Convert a Posit into an i32, rounding according to the standard:
Source§impl<const N: u32, const ES: u32, Int: Int> RoundFrom<Posit<N, ES, Int>> for i64
impl<const N: u32, const ES: u32, Int: Int> RoundFrom<Posit<N, ES, Int>> for i64
Source§fn round_from(value: Posit<N, ES, Int>) -> Self
fn round_from(value: Posit<N, ES, Int>) -> Self
Convert a Posit into an i64, rounding according to the standard:
Source§impl<const N: u32, const ES: u32, Int: Int> RoundFrom<Posit<N, ES, Int>> for i8
impl<const N: u32, const ES: u32, Int: Int> RoundFrom<Posit<N, ES, Int>> for i8
Source§fn round_from(value: Posit<N, ES, Int>) -> Self
fn round_from(value: Posit<N, ES, Int>) -> Self
Convert a Posit into an i8, rounding according to the standard:
Source§impl<const N: u32, const ES: u32, Int: Int> RoundFrom<f32> for Posit<N, ES, Int>
impl<const N: u32, const ES: u32, Int: Int> RoundFrom<f32> for Posit<N, ES, Int>
Source§fn round_from(value: f32) -> Self
fn round_from(value: f32) -> Self
Convert an f32 into a Posit, rounding according to the standard:
- If the value is any infinity or any NaN, it converts to NaR.
- Otherwise, the float value is rounded (if necessary).
Source§impl<const N: u32, const ES: u32, Int: Int> RoundFrom<f64> for Posit<N, ES, Int>
impl<const N: u32, const ES: u32, Int: Int> RoundFrom<f64> for Posit<N, ES, Int>
Source§fn round_from(value: f64) -> Self
fn round_from(value: f64) -> Self
Convert an f64 into a Posit, rounding according to the standard:
- If the value is any infinity or any NaN, it converts to NaR.
- Otherwise, the float value is rounded (if necessary).
Source§impl<const N: u32, const ES: u32, Int: Int> RoundFrom<i128> for Posit<N, ES, Int>
impl<const N: u32, const ES: u32, Int: Int> RoundFrom<i128> for Posit<N, ES, Int>
Source§fn round_from(value: i128) -> Self
fn round_from(value: i128) -> Self
Convert an i128 into a Posit, rounding according to the standard:
Source§impl<const N: u32, const ES: u32, Int: Int> RoundFrom<i16> for Posit<N, ES, Int>
impl<const N: u32, const ES: u32, Int: Int> RoundFrom<i16> for Posit<N, ES, Int>
Source§fn round_from(value: i16) -> Self
fn round_from(value: i16) -> Self
Convert an i16 into a Posit, rounding according to the standard:
Source§impl<const N: u32, const ES: u32, Int: Int> RoundFrom<i32> for Posit<N, ES, Int>
impl<const N: u32, const ES: u32, Int: Int> RoundFrom<i32> for Posit<N, ES, Int>
Source§fn round_from(value: i32) -> Self
fn round_from(value: i32) -> Self
Convert an i32 into a Posit, rounding according to the standard:
Source§impl<const N: u32, const ES: u32, Int: Int> RoundFrom<i64> for Posit<N, ES, Int>
impl<const N: u32, const ES: u32, Int: Int> RoundFrom<i64> for Posit<N, ES, Int>
Source§fn round_from(value: i64) -> Self
fn round_from(value: i64) -> Self
Convert an i64 into a Posit, rounding according to the standard:
Source§impl<const N: u32, const ES: u32, Int: Int> RoundFrom<i8> for Posit<N, ES, Int>
impl<const N: u32, const ES: u32, Int: Int> RoundFrom<i8> for Posit<N, ES, Int>
Source§fn round_from(value: i8) -> Self
fn round_from(value: i8) -> Self
Convert an i8 into a Posit, rounding according to the standard:
Source§impl<const N: u32, const ES: u32, Int: Int> SubAssign<&Posit<N, ES, Int>> for Posit<N, ES, Int>
impl<const N: u32, const ES: u32, Int: Int> SubAssign<&Posit<N, ES, Int>> for Posit<N, ES, Int>
Source§fn sub_assign(&mut self, rhs: &Posit<N, ES, Int>)
fn sub_assign(&mut self, rhs: &Posit<N, ES, Int>)
-= operation. Read moreSource§impl<const N: u32, const ES: u32, Int: Int, const SIZE: usize> SubAssign<&Posit<N, ES, Int>> for Quire<N, ES, SIZE>
impl<const N: u32, const ES: u32, Int: Int, const SIZE: usize> SubAssign<&Posit<N, ES, Int>> for Quire<N, ES, SIZE>
Source§impl<const N: u32, const ES: u32, Int: Int, const SIZE: usize> SubAssign<Posit<N, ES, Int>> for Quire<N, ES, SIZE>
impl<const N: u32, const ES: u32, Int: Int, const SIZE: usize> SubAssign<Posit<N, ES, Int>> for Quire<N, ES, SIZE>
Source§impl<const N: u32, const ES: u32, Int: Int> SubAssign for Posit<N, ES, Int>
impl<const N: u32, const ES: u32, Int: Int> SubAssign for Posit<N, ES, Int>
Source§fn sub_assign(&mut self, rhs: Posit<N, ES, Int>)
fn sub_assign(&mut self, rhs: Posit<N, ES, Int>)
-= operation. Read more