Struct awint::FP

source · []
pub struct FP<B> where
    B: BorrowMut<Bits>, 
{ /* private fields */ }
Expand description

Fixed-Point generic struct for B that implement Borrow<Bits> and BorrowMut<Bits>. Adds on signedness and fixed-point information. Implements many traits if B also implements them.

In order to make many operations infallible, self.fp().unsigned_abs() and self.bw() follow an invariant that they are never greater than usize::MAX >> 2.

NOTE: B should not change the bitwidth of the underlying Bits during the lifetime of the FP struct unless the invariants are upheld. Otherwise, panics and arithmetic errors can occur. Preferably, into_b and FP::new should be used to create a fresh struct.

Implementations

Creates a fixed-point generic FP<B> from a specified signedness signed, wrapped value B, and fixed point fp. This returns None if bits.bw() or fp.unsigned_abs() are greater than usize::MAX >> 2.

Consumes this, returning the inner B

Returns a reference to the B in self

Returns a mutable reference to the B in self

Returns a reference to self in the form of &Bits

Returns a reference to self in the form of &mut Bits

Returns the signedness of self

Returns the sign of self, returning Some(self.const_as_ref().msb()) if self.signed(), and None otherwise.

Returns if self.signed() && self.const_as_ref().msb()

Returns the bitwidth of self as a NonZeroUsize

Returns the bitwidth of self as a usize

Returns the bitwidth of self as an isize

Returns the fixed point of self

Returns the FPType of self. Because FPType impls PartialEq, this is useful for quickly determining if two different FPs have the same fixed point type.

These functions are associated to avoid name clashes.

Note: Adding new functions to FP is a WIP

One-assigns this. Returns None if a positive one value is not representable.

Relative significant bit positions, determines the bit positions (inclusive) of the least and most significant bits relative to the fixed point

Note: because the msb position is one less than the bitwidth, the bitwidth is equal to the difference in the bounds plus one

The same as FP::truncate_assign except it always intreprets arguments as unsigned

Truncate-assigns rhs to this. For the unsigned case, logically what this does is make this and rhs into concatenations with infinite zeros on both ends, aligns the fixed points, and copies from rhs to this. For the case of rhs.signed(), the absolute value of rhs is used for truncation to this followed by this.neg_assign(rhs.msb() && this.signed()).

The same as FP::otruncate_assign except it always intreprets arguments as unsigned

Overflow-truncate-assigns rhs to this. The same as FP::truncate_assign, except that a tuple of booleans is returned. The first indicates if the least significant numerical bit was truncated, and the second indicates if the most significant numerical bit was truncated. Additionally, if this.is_negative() != rhs.is_negative(), the second overflow is set.

What this means is that if transitive truncations return no overflow, then numerical value is preserved. If only FP::otruncate_assign(...).0 is true, then less significant numerical values were changed and only some kind of truncation rounding has occured to the numerical value. If FP::otruncate_assign(...).1 is true, then the numerical value could be dramatically changed.

Creates a tuple of Vec<u8>s representing the integer and fraction parts this (sign indicators, prefixes, points, and postfixes not included). This function performs allocation. This is the inverse of ExtAwi::from_bytes_general and extends the abilities of ExtAwi::bits_to_vec_radix. Signedness and fixed point position information is taken from this. min_integer_chars specifies the minimum number of chars in the integer part, inserting leading ’0’s if there are not enough chars. min_fraction_chars works likewise for the fraction part, inserting trailing ’0’s.

use awint::prelude::*;
// note: a user may want to define their own helper functions to do
// this in one step and combine the output into one string using
// the notation they prefer.

// This creates a fixed point value of -42.1234_i32f16
// (`ExtAwi::from_str` will be able to parse this format in the future
// after more changes to `awint` are made).
let awi = ExtAwi::from_str_general(Some(true), "42", "1234", 0, 10, bw(32), 16).unwrap();
let fp_awi = FP::new(true, awi, 16).unwrap();
assert_eq!(
    // note: in many situations users will want at least 1 zero for
    // both parts so that zero parts result in "0" strings and not "",
    // so `min_..._chars` will be 1. See also
    // `FPType::unique_min_fraction_digits`.
    FP::to_str_general(&fp_awi, 10, false, 1, 1),
    Ok(("42".to_owned(), "1234".to_owned()))
);
Errors

This can only return an error if radix is not in the range 2..=36 or if resource exhaustion occurs.

Creates a tuple of Strings representing the integer and fraction parts of this. This does the same thing as [FP::to_vec_general] but with Strings.

Methods from Deref<Target = Bits>

Returns the bitwidth as a NonZeroUsize

Returns the bitwidth as a usize

Returns the exact number of usize digits needed to store all bits.

Clears the unused bits.

Assigns the bits of buf to self. Any bits beyond self.bw() are ignored. This function is portable across target architecture pointer sizes and endianness.

Assigns the bits of self to buf. Any corresponding bits beyond self.bw() are zeroed. This function is portable across target architecture pointer sizes and endianness.

Zero-assigns. Same as the Unsigned-minimum-value. All bits are set to 0.

Unsigned-maximum-value-assigns. All bits are set to 1.

Signed-maximum-value-assigns. All bits are set to 1, except for the most significant bit.

Signed-minimum-value-assigns. Only the most significant bit is set.

Unsigned-one-assigns. Only the least significant bit is set. The unsigned distinction is important, because a positive one value does not exist for signed integers with a bitwidth of 1.

Not-assigns self

Copy-assigns the bits of rhs to self

Or-assigns rhs to self

And-assigns rhs to self

Xor-assigns rhs to self

And-assigns a range of ones to self. Useful for masking. An empty or reversed range zeroes self. None is returned if range.start > self.bw() or range.end > self.bw().

Or-assigns rhs to self at a position shl. Set bits of rhs that are shifted beyond the bitwidth of self are truncated.

Resize-copy-assigns rhs to self. If self.bw() >= rhs.bw(), the copied value of rhs will be extended with bits set to extension. If self.bw() < rhs.bw(), the copied value of rhs will be truncated.

Zero-resize-copy-assigns rhs to self and returns overflow. This is the same as lhs.resize_assign(rhs, false), but returns true if the unsigned meaning of the integer is changed.

Sign-resize-copy-assigns rhs to self and returns overflow. This is the same as lhs.resize_assign(rhs, rhs.msb()), but returns true if the signed meaning of the integer is changed.

If self is zero

If self is unsigned-maximum

If self is signed-maximum

If self is signed-minimum

If self is unsigned-one

Equality comparison, self == rhs

Not-equal comparison, self != rhs

Unsigned-less-than comparison, self < rhs

Unsigned-less-than-or-equal comparison, self <= rhs

Unsigned-greater-than comparison, self > rhs

Unsigned-greater-than-or-equal comparison, self >= rhs

Signed-less-than comparison, self < rhs

Signed-less-than-or-equal comparison, self <= rhs

Signed-greater-than comparison, self > rhs

Signed-greater-than-or-equal comparison, self >= rhs

Assigns to self the integer value represented by src in the given radix. If src should be interpreted as unsigned, sign should be None, otherwise it should be set to the sign. In order for this function to be const, two scratchpads pad0 and pad1 with the same bitwidth as self must be supplied, which can be mutated by the function in arbitrary ways.

Errors

self is not mutated if an error occurs. See crate::SerdeError for error conditions. The characters 0..=9, a..=z, and A..=Z are allowed depending on the radix. The char _ is ignored, and all other chars result in an error. src cannot be empty. The value of the string must be representable in the bitwidth of self with the specified sign, otherwise an overflow error is returned.

Assigns the [u8] representation of self to dst (sign indicators, prefixes, and postfixes not included). signed specifies if self should be interpreted as signed. radix specifies the radix, and upper specifies if letters should be uppercase. In order for this function to be const, a scratchpad pad with the same bitwidth as self must be supplied. Note that if dst.len() is more than what is needed to store the representation, the leading bytes will all be set to b’0’.

Errors

Note: If an error is returned, dst may be set to anything

This function can fail from NonEqualWidths, InvalidRadix, and Overflow (if dst cannot represent the value of self). See crate::SerdeError.

Unsigned-divides self by div, sets self to the quotient, and returns the remainder. Returns None if div == 0.

Returns the least significant bit

Returns the most significant bit

Returns the number of leading zero bits

Returns the number of trailing zero bits

Returns the number of set ones

“Fielding” bitfields with targeted copy assigns. The bitwidths of self and rhs do not have to be equal, but the inputs must collectively obey width <= self.bw() && width <= rhs.bw() && to <= (self.bw() - width) && from <= (rhs.bw() - width) or else None is returned. width can be zero, in which case this function just checks the input correctness and does not mutate self.

This function works by copying a bw sized bitfield from rhs at bitposition from and overwriting bw bits at bitposition to in self. Only the width bits in self are mutated, any bits before and after the bitfield are left unchanged.

use awint::{Bits, inlawi, InlAwi};
// As an example, two hexadecimal digits will be overwritten
// starting with the 12th digit in `y` using a bitfield with
// value 0x42u8 extracted from `x`.
let x = inlawi!(0x11142111u50);
// the underscores are just for emphasis
let mut y = inlawi!(0xfd_ec_ba9876543210u100);
// from `x` digit place 3, we copy 2 digits to `y` digit place 12.
y.field(12 * 4, &x, 3 * 4, 2 * 4);
assert_eq!(y, inlawi!(0xfd_42_ba9876543210u100));

Copy entry from lookup table. Copies a self.bw() sized bitfield from lut at bit position inx.to_usize() * self.bw(). If lut.bw() != (self.bw() * (2^inx.bw())), None will be returned.

use awint::{Bits, inlawi, InlAwi};
let mut out = inlawi!(0u10);
// lookup table consisting of 4 10-bit entries
let lut = inlawi!(4u10, 3u10, 2u10, 1u10);
// the indexer has to have a bitwidth of 2 to index 2^2 = 4 entries
let mut inx = inlawi!(0u2);

// get the third entry (this is using zero indexing)
inx.usize_assign(2);
out.lut(&lut, &inx).unwrap();
assert_eq!(out, inlawi!(3u10));

Set entry in lookup table. The inverse of Bits::lut, this uses entry as a bitfield to overwrite part of self at bit position inx.to_usize() * entry.bw(). If self.bw() != (entry.bw() * (2^inx.bw())), None will be returned.

Assigns cin + (self * rhs) to self and returns the overflow

Add-assigns lhs * rhs to self and returns if overflow happened

Multiplies lhs by rhs and add-assigns the product to self. Three operands eliminates the need for an allocating temporary.

Multiply-assigns self by rhs. pad is a scratchpad that will be mutated arbitrarily.

Arbitrarily-unsigned-multiplies lhs by rhs and add-assigns the product to self. This function is equivalent to:

use awint::prelude::*;

fn arb_umul_assign(add: &mut Bits, lhs: &Bits, rhs: &Bits) {
    let mut resized_lhs = ExtAwi::zero(add.nzbw());
    // Note that this function is specified as unsigned,
    // because we use `zero_resize_assign`
    resized_lhs.zero_resize_assign(lhs);
    let mut resized_rhs = ExtAwi::zero(add.nzbw());
    resized_rhs.zero_resize_assign(rhs);
    add.mul_add_assign(&resized_lhs, &resized_rhs).unwrap();
}

except that it avoids allocation and is more efficient overall

Arbitrarily-signed-multiplies lhs by rhs and add-assigns the product to self. duo and div are marked mutable but their values are not changed by this function.

Left-shifts-assigns by s bits. If s >= self.bw(), then None is returned and the Bits are left unchanged.

Left shifts can act as a very fast multiplication by a power of two for both the signed and unsigned interpretation of Bits.

Logically-right-shift-assigns by s bits. If s >= self.bw(), then None is returned and the Bits are left unchanged.

Logical right shifts do not copy the sign bit, and thus can act as a very fast floored division by a power of two for the unsigned interpretation of Bits.

Arithmetically-right-shift-assigns by s bits. If s >= self.bw(), then None is returned and the Bits are left unchanged.

Arithmetic right shifts copy the sign bit, and thus can act as a very fast floored division by a power of two for the signed interpretation of Bits.

Left-rotate-assigns by s bits. If s >= self.bw(), then None is returned and the Bits are left unchanged.

This function is equivalent to the following:

use awint::{extawi, inlawi, Bits, ExtAwi, InlAwi};
let mut input = inlawi!(0x4321u16);
let mut output = inlawi!(0u16);
// rotate left by 4 bits or one hexadecimal digit
let shift = 4;

output.copy_assign(&input).unwrap();
// temporary clone of the input
let mut tmp = ExtAwi::from(input);
if shift != 0 {
    if shift >= input.bw() {
        panic!();
    }
    output.shl_assign(shift).unwrap();
    tmp.lshr_assign(input.bw() - shift).unwrap();
    output.or_assign(&tmp);
};

assert_eq!(output, inlawi!(0x3214u16));
let mut using_rotate = ExtAwi::from(input);
using_rotate.rotl_assign(shift).unwrap();
assert_eq!(using_rotate, extawi!(0x3214u16));

// Note that slices are typed in a little-endian order opposite of
// how integers are typed, but they still visually rotate in the
// same way. This means `Rust`s built in slice rotation is in the
// opposite direction to integers and `Bits`
let mut array = [4, 3, 2, 1];
array.rotate_left(1);
assert_eq!(array, [3, 2, 1, 4]);
assert_eq!(0x4321u16.rotate_left(4), 0x3214);
let mut x = inlawi!(0x4321u16);
x.rotl_assign(4);
// `Bits` has the preferred endianness
assert_eq!(x, inlawi!(0x3214u16));

Unlike the example above which needs cloning, this function avoids any allocation and has many optimized branches for different input sizes and shifts.

Right-rotate-assigns by s bits. If s >= self.bw(), then None is returned and the Bits are left unchanged.

See Bits::rotl_assign for more details.

Reverse-bit-order-assigns self. The least significant bit becomes the most significant bit, the second least significant bit becomes the second most significant bit, etc.

Funnel shift with power-of-two bitwidths. Returns None if 2*self.bw() != rhs.bw() || 2^s.bw() != self.bw(). A self.bw() sized field is assigned to self from rhs starting from the bit position s. The shift cannot overflow because of the restriction on the bitwidth of s.

Increment-assigns self with a carry-in cin and returns the carry-out bit. If cin == true then one is added to self, otherwise nothing happens. false is always returned unless self.is_umax().

Decrement-assigns self with a carry-in cin and returns the carry-out bit. If cin == false then one is subtracted from self, otherwise nothing happens. true is always returned unless self.is_zero().

Negate-assigns self if neg is true. Note that signed minimum values will overflow.

Absolute-value-assigns self. Note that signed minimum values will overflow, unless self is interpreted as unsigned after a call to this function.

Add-assigns by rhs

Subtract-assigns by rhs

Reverse-subtract-assigns by rhs. Sets self to (-self) + rhs.

Negate-add-assigns by rhs. Negates conditionally on neg.

A general summation with carry-in cin and two inputs lhs and rhs. self is set to the sum. The unsigned overflow (equivalent to the carry-out bit) and the signed overflow is returned as a tuple. None is returned if any bitwidths do not match. If subtraction is desired, one of the operands can be negated.

Trait Implementations

Forwards to the corresponding impl for Bits

Formats the value using the given formatter.

Returns a copy of the value. Read more

Performs copy-assignment from source. Read more

Forwards to the corresponding impl for Bits

Formats the value using the given formatter. Read more

The resulting type after dereferencing.

Dereferences the value.

Mutably dereferences the value.

Forwards to the corresponding impl for Bits

Formats the value using the given formatter. Read more

Uses the hash of self.signed(), self.fp(), and the Hash implementation on FP::into_inner(self) (not self.const_as_ref())

Feeds a slice of this type into the given Hasher. Read more

Forwards to the corresponding impl for Bits

Formats the value using the given formatter.

Forwards to the corresponding impl for Bits

Formats the value using the given formatter.

The signedness, fixed point, and PartialEq implementation on FP::into_inner(self) must all be true in order for this to return true

This method tests for !=.

Forwards to the corresponding impl for Bits

Formats the value using the given formatter.

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The resulting type after obtaining ownership.

Creates owned data from borrowed data, usually by cloning. Read more

🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

Converts the given value to a String. Read more

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.