#[repr(transparent)]
pub struct ExtAwi { /* private fields */ }
Expand description

An arbitrary width integer with manually controlled bitwidth. Most arithmetic is wrapping like Rust’s integers. All reallocations are explicit.

#![feature(const_mut_refs)]
use awint::{bw, inlawi, Bits, ExtAwi, InlAwi};

const fn example(x0: &mut Bits, x1: &Bits) {
    // when dealing with `Bits` with different bitwidths, use the
    // `_resize_assign` functions or the concatenations of components
    // macros with unbounded fillers from `awint_macros`
    x0.sign_resize_assign(x1);
    // multiply in place by 2 for an example
    x0.short_cin_mul(0, 2);
}

// using `bw` function for quick `NonZeroUsize` construction from a literal
let mut awi0 = ExtAwi::zero(bw(100));
// constructing an `ExtAwi` from an `InlAwi`
let awi1 = ExtAwi::from(inlawi!(-123i16));
// `ExtAwi` implements `DerefMut`, but a mutable `Bits` reference can also
// be acquired like this.
let x0: &mut Bits = awi0.const_as_mut();
assert!(x0.is_zero());
example(x0, awi1.const_as_ref());
assert_eq!(x0, inlawi!(-246i100).const_as_ref());
// you can freely mix references originating from both `ExtAwi` and `InlAwi`
example(x0, inlawi!(0x10u16).const_as_ref());
assert_eq!(awi0, ExtAwi::from(inlawi!(0x20u100)));

Implementations

Returns a reference to self in the form of &Bits

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

Returns the bitwidth of this ExtAwi as a NonZeroUsize

Returns the bitwidth of this ExtAwi as a usize

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

Creates an ExtAwi from copying a Bits reference. The same functionality is provided by an From<&Bits> implementation for ExtAwi.

Zero-value construction with bitwidth bw

Unsigned-maximum-value construction with bitwidth bw

Signed-maximum-value construction with bitwidth bw

Signed-minimum-value construction with bitwidth bw

Unsigned-one-value construction with bitwidth bw

Creates a Vec<u8> representing bits (sign indicators, prefixes, and postfixes not included). This function performs allocation. This is a wrapper around awint_core::Bits::to_bytes_radix that truncates leading zeros. An additional min_chars specifies the minimum number of characters that should exist. min_chars specifies the minimum number of chars in the integer part, inserting leading ’0’s if there are not enough chars, just like Rust’s built in {:0d} formatting. Note that an empty vector will be returned if min_chars == 0 && bits.is_zero().

Errors

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

Creates a string representing bits. This function performs allocation. This does the same thing as ExtAwi::bits_to_vec_radix but with a String.

Creates an ExtAwi representing the given arguments. This function performs allocation. This is a wrapper around awint_core::Bits::bytes_radix_assign that zero or sign resizes the result to match bw.

Errors

See the error conditions of Bits::bytes_radix_assign. Note that - is an invalid character even though to_vec_radix can return -. This is because we need to handle both unsigned and signed integer inputs, specified only by sign. If the input is a negative signed integer representation with - appended to the front, the subslice src[1..] can be taken and sign can be set to Some(true).

Creates an ExtAwi representing the given arguments. This does the same thing as ExtAwi::from_bytes_radix but with an &str.

Creates an ExtAwi representing the given arguments. This function performs allocation. In addition to the arguments and semantics from ExtAwi::from_bytes_radix, this function includes the ability to deal with general fixed point integer deserialization. src is now split into separate integer and fraction parts. An exponent exp further multiplies the numerical value by radix^exp. fp is the location of the fixed point in the output representation of the numerical value (e.x. for a plain integer fp == 0). fp can be negative or greater than the bitwidth.

This function uses a single rigorous round-to-even that occurs after the exponent and fixed point multiplier are applied and before any numerical information is lost.

See crate::FP::to_vec_general for the inverse of this function.

Errors

See the error conditions of ExtAwi::from_bytes_radix. The precision can now be arbitrarily large (any overflow in the low numerical significance direction will be rounded), but overflow can still happen in the more significant direction. Empty strings are interpreted as a zero value.

Creates an ExtAwi representing the given arguments. This does the same thing as ExtAwi::from_bytes_general but with &strs.

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

Converts this type into a mutable reference of the (usually inferred) input type.

Converts this type into a shared reference of the (usually inferred) input type.

Forwards to the corresponding impl for Bits

Formats the value using the given formatter.

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

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

Executes the destructor for this type. Read more

Creates an ExtAwi from copying a Bits reference

Converts to this type from the input type.

Creates an ExtAwi from copying an InlAwi

Converts to this type from the input type.

Creates an ExtAwi with one bit set to this bool

Converts to this type from the input type.

Creates an ExtAwi with the same bitwidth and bits as the integer

Converts to this type from the input type.

Creates an ExtAwi with the same bitwidth and bits as the integer

Converts to this type from the input type.

Creates an ExtAwi with the same bitwidth and bits as the integer

Converts to this type from the input type.

Creates an ExtAwi with the same bitwidth and bits as the integer

Converts to this type from the input type.

Creates an ExtAwi with the same bitwidth and bits as the integer

Converts to this type from the input type.

Creates an ExtAwi with the same bitwidth and bits as the integer

Converts to this type from the input type.

Creates an ExtAwi with the same bitwidth and bits as the integer

Converts to this type from the input type.

Creates an ExtAwi with the same bitwidth and bits as the integer

Converts to this type from the input type.

Creates an ExtAwi with the same bitwidth and bits as the integer

Converts to this type from the input type.

Creates an ExtAwi with the same bitwidth and bits as the integer

Converts to this type from the input type.

Creates an ExtAwi with the same bitwidth and bits as the integer

Converts to this type from the input type.

Creates an ExtAwi with the same bitwidth and bits as the integer

Converts to this type from the input type.

Creates an ExtAwi described by s. There are two modes of operation which use ExtAwi::from_str_radix differently.

In general mode, the bitwidth must be specified after a ‘u’ (unsigned) or ‘i’ (signed) suffix. A prefix of “0b” specifies a binary radix, “0o” specifies an octal radix, “0x” specifies hexadecimal, else decimal. For some examples, “42u10” entered into this function creates an ExtAwi with bitwidth 10 and unsigned value 42. “-42i10” results in bitwidth 10 and signed value of -42. “0xffff_ffffu32” results in bitwidth 32 and an unsigned value of 0xffffffff (also 4294967295 in decimal and u32::MAX). “0x1_0000_0000u32” results in an error with SerdeError::Overflow, because it exceeds the maximum unsigned value for a 32 bit integer. “123” results in SerdeError::InvalidChar, because no bitwidth suffix has been supplied and this function has assumed binary mode, in which ‘2’ and ‘3’ are invalid chars.

If no ‘u’ or ‘i’ chars are present, this function will use binary mode and assume the input is a radix 2 string with only the chars ‘0’ and ‘1’. In this mode, the bitwidth will be equal to the number of chars, including leading zeros. For some examples, 42 in binary is 101010. If “101010” is entered into this function, it will return an ExtAwi with bitwidth 6 and unsigned value 42. “0000101010” results in bitwidth 10 and unsigned value 42. “1111_1111” results in bitwidth 8 and signed value -128 or equivalently unsigned value 255.

A missing significand or suffix will result in SerdeError::Empty. Even if the value is zero, there must be at least one ‘0’ char in the significand (e.x. 0x0u8 not 0xu8), otherwise SerdeError::Empty is returned.

The associated error which can be returned from parsing.

Feeds this value into the given Hasher. Read more

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

A quick way of getting an &Bits reference

The returned type after indexing.

Performs the indexing (container[index]) operation. Read more

A quick way of getting an &mut Bits reference

Performs the mutable indexing (container[index]) operation. 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.

If self and other have unmatching bit widths, false will be returned.

This method tests for self and other values to be equal, and is used by ==. Read more

This method tests for !=.

Forwards to the corresponding impl for Bits

Formats the value using the given formatter.

If self and other have unmatching bit widths, false will be returned.

ExtAwi is safe to send between threads since it does not own aliasing memory and has no reference counting mechanism like Rc.

ExtAwi is safe to share between threads since it does not own aliasing memory and has no mutable internal state like Cell or RefCell.

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.