diff --git a/.rustfmt.toml b/.rustfmt.toml index bfc63d9..3801e12 100644 --- a/.rustfmt.toml +++ b/.rustfmt.toml @@ -1,67 +1,68 @@ -max_width = 90 # changed -hard_tabs = false -tab_spaces = 4 -newline_style = "Auto" -use_small_heuristics = "Default" -indent_style = "Block" -wrap_comments = false -format_code_in_doc_comments = false -comment_width = 80 -normalize_comments = true # changed -normalize_doc_attributes = false -# license_template_path = "LICENSE_TEMPLATE" # changed -format_strings = false -format_macro_matchers = false -format_macro_bodies = true +# `rustfmt` internal settings +# +# emit_mode = "Files" +# make_backup = false + +binop_separator = "Front" +blank_lines_lower_bound = 0 +blank_lines_upper_bound = 1 +brace_style = "SameLineWhere" +color = "Auto" +combine_control_expr = false # better all around in our opinions +comment_width = 80 # changed +condense_wildcard_suffixes = true # changed +control_brace_style = "AlwaysSameLine" +disable_all_formatting = false +edition = "2018" # changed empty_item_single_line = true -struct_lit_single_line = true +enum_discrim_align_threshold = 0 +error_on_line_overflow = true # be more strict +error_on_unformatted = true # be more strict +fn_args_layout = "Tall" fn_single_line = false -where_single_line = false +force_explicit_abi = true +force_multiline_blocks = true # changed +format_code_in_doc_comments = true # changed +format_macro_bodies = true # changed +format_macro_matchers = true # changed +format_strings = true # changed +hard_tabs = false +hide_parse_errors = false +ignore = [] imports_indent = "Block" -imports_layout = "Vertical" # changed +imports_layout = "Vertical" # makes editing quicker +inline_attribute_width = 0 # unchanged, for ease of editing +# license_template_path = "LICENSE_TEMPLATE" # changed +match_arm_blocks = true +match_block_trailing_comma = false +max_width = 90 # changed +merge_derives = true merge_imports = true # changed +newline_style = "Unix" # changed, prevents `\r\n` being accidentally introduced +normalize_comments = true # no /* */ comments should be in master +normalize_doc_attributes = true # changed +overflow_delimited_expr = false +remove_nested_parens = true +reorder_impl_items = true # changed reorder_imports = true reorder_modules = true -reorder_impl_items = false -type_punctuation_density = "Wide" -space_before_colon = false +report_fixme = "Always" # changed +report_todo = "Always" # changed +# required_version = "CARGO_PKG_VERSION" +skip_children = false space_after_colon = true +space_before_colon = false spaces_around_ranges = false -binop_separator = "Front" -remove_nested_parens = true -combine_control_expr = false # changed -overflow_delimited_expr = false struct_field_align_threshold = 0 -enum_discrim_align_threshold = 0 -match_arm_blocks = true -force_multiline_blocks = true # changed -fn_args_layout = "Tall" -brace_style = "SameLineWhere" -control_brace_style = "AlwaysSameLine" -trailing_semicolon = false # changed +struct_lit_single_line = true +tab_spaces = 4 trailing_comma = "Vertical" -match_block_trailing_comma = false -blank_lines_upper_bound = 1 -blank_lines_lower_bound = 0 -edition = "2018" # changed -version = "One" -merge_derives = true -use_try_shorthand = true # changed -use_field_init_shorthand = true # changed -force_explicit_abi = true -condense_wildcard_suffixes = false -color = "Auto" +trailing_semicolon = false # changed +type_punctuation_density = "Wide" unstable_features = true # changed -disable_all_formatting = false -skip_children = false -hide_parse_errors = false -error_on_line_overflow = false -error_on_unformatted = false -report_todo = "Always" -report_fixme = "Always" -ignore = [] - -# Below are `rustfmt` internal settings -# -# emit_mode = "Files" -# make_backup = false +use_field_init_shorthand = true # changed +use_small_heuristics = "Default" +use_try_shorthand = true # changed +version = "Two" # changed +where_single_line = false # unchanged, for ease of editing +wrap_comments = true # fits comments to the line diff --git a/src/apint/arithmetic.rs b/src/apint/arithmetic.rs index 0cef1dd..6ff5206 100644 --- a/src/apint/arithmetic.rs +++ b/src/apint/arithmetic.rs @@ -45,7 +45,10 @@ use core::ops::{ /// **Note**: unless otherwise noted in the function specific documentation, /// /// - The functions do **not** allocate memory. -/// - The function works for both signed and unsigned interpretations of an `ApInt`. In other words, in the low-level bit-wise representation there is no difference between a signed and unsigned operation by a certain function on fixed bit-width integers. (Cite: LLVM) +/// - The function works for both signed and unsigned interpretations of an +/// `ApInt`. In other words, in the low-level bit-wise representation there is +/// no difference between a signed and unsigned operation by a certain +/// function on fixed bit-width integers. (Cite: LLVM) impl ApInt { /// Increments this `ApInt` by one inplace. pub fn wrapping_inc(&mut self) { @@ -61,7 +64,8 @@ impl ApInt { break } (v, true) => { - // if the ApInt was relatively random this should rarely happen + // if the ApInt was relatively random this should rarely + // happen x[i] = v; } } @@ -90,7 +94,8 @@ impl ApInt { break } (v, true) => { - // if the ApInt was relatively random this should rarely happen + // if the ApInt was relatively random this should rarely + // happen x[i] = v; } } @@ -153,8 +158,9 @@ impl ApInt { try_forward_bin_mut_impl(self, rhs, ApInt::wrapping_add_assign) } - /// Add-assigns `rhs` to `self` inplace, and returns a boolean indicating if overflow occured, - /// according to the **unsigned** interpretation of overflow. + /// Add-assigns `rhs` to `self` inplace, and returns a boolean indicating if + /// overflow occured, according to the **unsigned** interpretation of + /// overflow. /// /// # Errors /// @@ -219,8 +225,9 @@ impl ApInt { } } - /// Add-assigns `rhs` to `self` inplace, and returns a boolean indicating if overflow occured, - /// according to the **signed** interpretation of overflow. + /// Add-assigns `rhs` to `self` inplace, and returns a boolean indicating if + /// overflow occured, according to the **signed** interpretation of + /// overflow. /// /// # Errors /// @@ -274,7 +281,8 @@ impl ApInt { try_forward_bin_mut_impl(self, rhs, ApInt::wrapping_sub_assign) } - /// Multiply-assigns `rhs` to `self` inplace. This function **may** allocate memory. + /// Multiply-assigns `rhs` to `self` inplace. This function **may** allocate + /// memory. /// /// # Errors /// @@ -282,31 +290,34 @@ impl ApInt { /// /// # Performance /// - /// If the function detects a large number of leading zeros in front of the most significant - /// 1 bit, it will apply optimizations so that wasted multiplications and additions of zero are - /// avoided. This function is designed to efficiently handle 5 common kinds of multiplication. - /// Small here means both small ApInt `BitWidth` and/or small **unsigned** numerical - /// significance. (Signed multiplication works, but two's complement negative numbers may have a - /// large number of leading ones, leading to potential inefficiency.) + /// If the function detects a large number of leading zeros in front of the + /// most significant 1 bit, it will apply optimizations so that wasted + /// multiplications and additions of zero are avoided. This function is + /// designed to efficiently handle 5 common kinds of multiplication. + /// Small here means both small ApInt `BitWidth` and/or small **unsigned** + /// numerical significance. (Signed multiplication works, but two's + /// complement negative numbers may have a large number of leading ones, + /// leading to potential inefficiency.) /// /// - multiplication of zero by any size integer (no allocation) /// - multiplication of small (<= 1 `Digit`) integers (no allocation) /// - wrapping multiplication of medium size (<= 512 bits) integers /// - multiplication of medium size integers that will not overflow - /// - multiplication of small integers by large integers (or large integers multiplied by small - /// integers) (no allocation) + /// - multiplication of small integers by large integers (or large integers + /// multiplied by small integers) (no allocation) /// - /// Currently, Karatsuba multiplication is not implemented, so large integer multiplication - /// may be very slow compared to other algorithms. According to Wikipedia, Karatsuba algorithms - /// outperform 𝒪(n^2) algorithms, starting around 320-640 bits. + /// Currently, Karatsuba multiplication is not implemented, so large integer + /// multiplication may be very slow compared to other algorithms. + /// According to Wikipedia, Karatsuba algorithms outperform 𝒪(n^2) + /// algorithms, starting around 320-640 bits. pub fn wrapping_mul_assign(&mut self, rhs: &ApInt) -> Result<()> { match self.zip_access_data_mut_self(rhs)? { Inl(lhs, rhs) => { *lhs = lhs.wrapping_mul(rhs); } Ext(lhs, rhs) => { - // finds the most significant nonzero digit (for later optimizations) and handles - // early return of multiplication by zero. + // finds the most significant nonzero digit (for later optimizations) and + // handles early return of multiplication by zero. let rhs_sig_nonzero: usize = match rhs.iter().rposition(|x| x != &Digit::zero()) { Some(x) => x, @@ -327,12 +338,14 @@ impl ApInt { return Ok(()) } }; - // for several routines below there was a nested loop that had its first and last - // iterations unrolled (and the unrolled loops had their first and last iterations - // unrolled), and then some if statements are added for digit overflow checks. - // This is done because the compiler probably cannot properly unroll the carry - // system, overflow system, and figure out that only `Digit` multiplications were - // needed instead of `DoubleDigit` multiplications in some places. + // for several routines below there was a nested loop that had its first + // and last iterations unrolled (and the unrolled loops + // had their first and last iterations unrolled), and then + // some if statements are added for digit overflow checks. + // This is done because the compiler probably cannot properly unroll the + // carry system, overflow system, and figure out that only + // `Digit` multiplications were needed instead of + // `DoubleDigit` multiplications in some places. match (lhs_sig_nonzero == 0, rhs_sig_nonzero == 0) { (false, false) => { let lhs_sig_bits = (lhs_sig_nonzero * digit::BITS) @@ -343,15 +356,16 @@ impl ApInt { - (rhs[rhs_sig_nonzero].leading_zeros() as usize)); let tot_sig_bits = lhs_sig_bits + rhs_sig_bits; if tot_sig_bits <= (lhs.len() * digit::BITS) { - // No possibility of `Digit` wise overflow. Note that end bits still - // have to be trimmed for `ApInt`s with a width that is not a multiple of + // No possibility of `Digit` wise overflow. Note that end bits + // still have to be trimmed for + // `ApInt`s with a width that is not a multiple of //`Digit`s. // first digit of first row let mult = lhs[0]; let temp = mult.carrying_mul(rhs[0]); // middle digits of first row - // the goal here with `sum` is to allocate and initialize it only once - // here. + // the goal here with `sum` is to allocate and initialize it + // only once here. let mut sum = Vec::with_capacity(lhs_sig_nonzero + rhs_sig_nonzero + 2); sum.push(temp.0); @@ -437,8 +451,8 @@ impl ApInt { let sig_nonzero = lhs.len() - 1; // first digit done and carry let temp = lhs[0].carrying_mul(rhs[0]); - // the goal here with `sum` is to allocate and initialize it only once - // here. + // the goal here with `sum` is to allocate and initialize it + // only once here. // first row let mut sum = Vec::with_capacity(lhs.len()); sum.push(temp.0); @@ -461,7 +475,8 @@ impl ApInt { // sum[lhs_i] does not need to be used again sum[lhs_i] = temp1.0; let mut add_carry = temp1.1; - // as we get to the higher lhs digits, the higher rhs digits do not + // as we get to the higher lhs digits, the higher rhs + // digits do not // need to be considered let rhs_i_upper = sig_nonzero.wrapping_sub(lhs_i); // middle digits of this row @@ -548,8 +563,9 @@ impl ApInt { Ok(()) } - /// Multiplies `rhs` with `self` and returns the result. This function **may** allocate memory. - /// Note: see `wrapping_mul_assign` for more information. + /// Multiplies `rhs` with `self` and returns the result. This function + /// **may** allocate memory. Note: see `wrapping_mul_assign` for more + /// information. /// /// # Errors /// @@ -564,59 +580,69 @@ impl ApInt { /// **Note**: unless otherwise noted in the function specific documentation, /// /// - The functions do **not** allocate memory. -/// - The function works for both signed and unsigned interpretations of an `ApInt`. In other words, -/// in the low-level bit-wise representation there is no difference between a signed and -/// unsigned operation by the function on fixed bit-width integers. (Cite: LLVM) +/// - The function works for both signed and unsigned interpretations of an +/// `ApInt`. In other words, in the low-level bit-wise representation there is +/// no difference between a signed and unsigned operation by the function on +/// fixed bit-width integers. (Cite: LLVM) /// -/// In almost all integer division algorithms where "just" the quotient is calculated, the remainder -/// is also produced and actually exists in memory (or at least is only one O(n) operation away) -/// prior to being dropped or overwritten, and vice versa for remainder only calculations. Note here -/// that functions with `div` in their names (e.g. `wrapping_div`) should really be called `quo` -/// (quotient) functions, because the division process produces both the quotient and remainder. -/// However, to stay with Rust's naming scheme we have kept `div` naming. The instruction for -/// division on many CPUs sets registers to both results of the division process, and compilers will -/// detect if code uses both results and only use one division instruction. There is no such -/// detection for `ApInt`s, and thus the `divrem` and `remdiv` type instructions exist to explicitly -/// use just one division function for both results. +/// In almost all integer division algorithms where "just" the quotient is +/// calculated, the remainder is also produced and actually exists in memory (or +/// at least is only one O(n) operation away) prior to being dropped or +/// overwritten, and vice versa for remainder only calculations. Note here +/// that functions with `div` in their names (e.g. `wrapping_div`) should really +/// be called `quo` (quotient) functions, because the division process produces +/// both the quotient and remainder. However, to stay with Rust's naming scheme +/// we have kept `div` naming. The instruction for division on many CPUs sets +/// registers to both results of the division process, and compilers will detect +/// if code uses both results and only use one division instruction. There is no +/// such detection for `ApInt`s, and thus the `divrem` and `remdiv` type +/// instructions exist to explicitly use just one division function for both +/// results. /// /// ## Performance /// -/// All of the division functions in this `impl` quickly check for various edge cases and use an -/// efficient algorithm for these cases. -/// Small here means both small ApInt `BitWidth` and/or small **unsigned** numerical significance. -/// (Signed division works, but two's complement negative numbers may have a large number of -/// leading ones, leading to potential inefficiency.) +/// All of the division functions in this `impl` quickly check for various edge +/// cases and use an efficient algorithm for these cases. +/// Small here means both small ApInt `BitWidth` and/or small **unsigned** +/// numerical significance. (Signed division works, but two's complement +/// negative numbers may have a large number of leading ones, leading to +/// potential inefficiency.) /// /// - division of zero by any size integer (no allocation) /// - division of small (1 `Digit`) integers (no allocation) -/// - any division that will lead to the quotient being zero or one (no allocation) -/// - division of any integer by small (1 `Digit`) very small (0.5 `Digit`) integers (no allocation) -/// - division where the number of leading zeros of both arguments are within one `Digit` (less -/// allocation than what long division normally requires) -/// - during long division, the algorithm may encounter a case from above and will use that instead +/// - any division that will lead to the quotient being zero or one (no +/// allocation) +/// - division of any integer by small (1 `Digit`) very small (0.5 `Digit`) +/// integers (no allocation) +/// - division where the number of leading zeros of both arguments are within +/// one `Digit` (less allocation than what long division normally requires) +/// - during long division, the algorithm may encounter a case from above and +/// will use that instead /// - division of medium size (<= 512 bits) integers /// -/// Currently, algorithms faster than 𝒪(n^2) are not implemented, so large integer division may be -/// very slow compared to other algorithms. +/// Currently, algorithms faster than 𝒪(n^2) are not implemented, so large +/// integer division may be very slow compared to other algorithms. impl ApInt { - // Note: the invariant of `ApInt`s where unused bits beyond the bit width must be all zero is - // used heavily here, so that no `clear_unused_bits` needs to be used. - - /// This function is intended to be inlined into all of the unsigned quotient and remainder - /// functions for optimal assembly. - /// `duo` is divided by `div`, and the quotient is assigned to `duo` and remainder assigned - /// to `div` - /// `false` is returned if division by zero happened. Nothing is modified in the case of - /// division by zero. + // Note: the invariant of `ApInt`s where unused bits beyond the bit width must + // be all zero is used heavily here, so that no `clear_unused_bits` needs to + // be used. + + /// This function is intended to be inlined into all of the unsigned + /// quotient and remainder functions for optimal assembly. + /// `duo` is divided by `div`, and the quotient is assigned to `duo` and + /// remainder assigned to `div` + /// `false` is returned if division by zero happened. Nothing is modified in + /// the case of division by zero. #[inline] pub(crate) fn aarons_algorithm_divrem(duo: &mut [Digit], div: &mut [Digit]) -> bool { - // Some parts were put into their own functions and macros because indentation levels were - // getting too high, even for me. + // Some parts were put into their own functions and macros because indentation + // levels were getting too high, even for me. // The algorithm here is just like the algorithm in // https://github.com/AaronKutch/specialized-div-rem, - // except that there are more branches and preconditions. There are comments in this function - // such as `//quotient is 0 or 1 check` which correspond to comments in that function. + // except that there are more branches and preconditions. There are comments in + // this function such as `//quotient is 0 or 1 check` which correspond + // to comments in that function. // assumptions: // *ini_duo_sd > 0 @@ -686,8 +712,8 @@ impl ApInt { div[0] = Digit(u64::from(rem_lo)); } - // modifies the `$array` to be the two's complement of itself, all the way up to a `$len` - // number of digits. + // modifies the `$array` to be the two's complement of itself, all the way up to + // a `$len` number of digits. macro_rules! twos_complement { ($len:expr, $array:ident) => { for i0 in 0..$len { @@ -709,15 +735,18 @@ impl ApInt { } // uge stands for "unsigned greater or equal to" - // This checks for `$lhs >= $rhs` (checking only up to $lhs_len and $rhs_len respectively), - // and runs `$ge_branch` if true and `$ln_branch` otherwise + // This checks for `$lhs >= $rhs` (checking only up to $lhs_len and $rhs_len + // respectively), and runs `$ge_branch` if true and `$ln_branch` + // otherwise macro_rules! uge { - ($lhs_len:expr, - $lhs:ident, - $rhs_len:expr, - $rhs:ident, - $ge_branch:block, - $ln_branch:block) => { + ( + $lhs_len:expr, + $lhs:ident, + $rhs_len:expr, + $rhs:ident, + $ge_branch:block, + $ln_branch:block + ) => { let mut b0 = false; // allows lhs.len() to be smaller than rhs.len() for i in ($lhs_len..$rhs_len).rev() { @@ -748,15 +777,18 @@ impl ApInt { } // ugt stands for "unsigned greater than" - // This checks for `$lhs > $rhs` (checking only up to $lhs_len and $rhs_len respectively), - // and runs `$gt_branch` if true and `$le_branch` otherwise + // This checks for `$lhs > $rhs` (checking only up to $lhs_len and $rhs_len + // respectively), and runs `$gt_branch` if true and `$le_branch` + // otherwise macro_rules! ugt { - ($lhs_len:expr, - $lhs:ident, - $rhs_len:expr, - $rhs:ident, - $gt_branch:block, - $le_branch:block) => { + ( + $lhs_len:expr, + $lhs:ident, + $rhs_len:expr, + $rhs:ident, + $gt_branch:block, + $le_branch:block + ) => { let mut b0 = false; // allows lhs.len() to be smaller than rhs.len() for i in ($lhs_len..$rhs_len).rev() { @@ -789,7 +821,7 @@ impl ApInt { // assigns `$sum + $sub` to `$target`, // and zeros out `$sum` except for it sets `$sum[0]` to `$val` macro_rules! special0 { - ($len:expr,$sum:ident,$sub:ident,$target:ident,$val:expr) => {{ + ($len:expr, $sum:ident, $sub:ident, $target:ident, $val:expr) => {{ // subtraction (`sub` is the two's complement of some value) let (sum, mut carry) = $sum[0].carrying_add($sub[0]); $target[0] = sum; @@ -813,19 +845,19 @@ impl ApInt { // assigns `$sum + $sub` to `$target`, // and assigns `$val + $add` to `$sum` macro_rules! special1 { - ($len:expr,$sum:ident,$sub:ident,$target:ident,$val:expr,$add:ident) => {{ + ($len:expr, $sum:ident, $sub:ident, $targ:ident, $val:expr, $add:ident) => {{ // subtraction (`sub` is the two's complement of some value) let (temp, mut carry) = $sum[0].carrying_add($sub[0]); - $target[0] = temp; + $targ[0] = temp; for i in 1..($len - 1) { let temp = $sum[i] .dd() .wrapping_add($sub[i].dd()) .wrapping_add(carry.dd()); - $target[i] = temp.lo(); + $targ[i] = temp.lo(); carry = temp.hi(); } - $target[$len - 1] = $sum[$len - 1] + $targ[$len - 1] = $sum[$len - 1] .wrapping_add($sub[$len - 1]) .wrapping_add(carry); let (temp, mut carry) = $add[0].carrying_add($val); @@ -846,7 +878,7 @@ impl ApInt { // assigns `$sum + $add` to `$sum` macro_rules! add { - ($len:expr,$sum:ident,$add:ident) => {{ + ($len:expr, $sum:ident, $add:ident) => {{ let (sum, mut carry) = $sum[0].carrying_add($add[0]); $sum[0] = sum; for i in 1..($len - 1) { @@ -938,7 +970,8 @@ impl ApInt { ) }; let mul = duo_sig_dd.wrapping_div(div_sig_dd).lo(); - // Allocation could be avoided but it would involve more long division to recover + // Allocation could be avoided but it would involve more long division to + // recover //`div`. // this will become `-(div * mul)` let mut sub: Vec = Vec::with_capacity(len); @@ -952,7 +985,8 @@ impl ApInt { sub.push(temp.0); carry = temp.1; } - // final digit, test for `div * mul > duo`, and then form the two's complement + // final digit, test for `div * mul > duo`, and then form the two's + // complement if div_sd == len - 1 { let temp = mul.carrying_mul_add(div[div_sd], carry); sub.push(temp.0); @@ -978,7 +1012,8 @@ impl ApInt { return }, { - // the quotient is `mult` and remainder is `duo - (div * mult)` + // the quotient is `mult` and remainder is `duo - (div * + // mult)` twos_complement!(len, sub); special0!(len, duo, sub, div, mul); return @@ -1004,7 +1039,8 @@ impl ApInt { return }, { - // the quotient is `mult` and remainder is `duo - (div * mult)` + // the quotient is `mult` and remainder is `duo - (div * + // mult)` twos_complement!(len, sub); special0!(len, duo, sub, div, mul); return @@ -1044,19 +1080,22 @@ impl ApInt { }; if duo_lesser_bits >= div_lesser_bits { let bits = duo_lesser_bits - div_lesser_bits; - // bits_ll is the number of lesser bits in the digit that contains lesser and - // greater bits + // bits_ll is the number of lesser bits in the digit that contains + // lesser and greater bits let (digits, bits_ll) = (bits / digit::BITS, bits % digit::BITS); - // Unfortunately, `mul` here can be up to (2^2n - 1)/(2^(n-1)), where `n` - // is the number of bits in a `Digit`. This means that an `n+1` bit - // integer is needed to store mul. Because only one extra higher bit is involved, - // the algebraic simplification `(mul + 2^n)*div` to `mul*div + div*2^n` can be - // used when that highest bit is set. This just requires faster and simpler - // addition inlining hell instead of long multiplication inlining hell. + // Unfortunately, `mul` here can be up to (2^2n - 1)/(2^(n-1)), where + // `n` is the number of bits in a `Digit`. This + // means that an `n+1` bit integer is needed to + // store mul. Because only one extra higher bit is involved, + // the algebraic simplification `(mul + 2^n)*div` to `mul*div + + // div*2^n` can be used when that highest bit is + // set. This just requires faster and simpler + // addition inlining hell instead of long multiplication inlining + // hell. let mul = duo_sig_dd.wrapping_div(div_sig_d_add1); // add `mul << bits` to `quo` - // no inlining hell here because `bits_ll < n` and it takes a shift of `n` - // to overflow + // no inlining hell here because `bits_ll < n` and it takes a shift of + // `n` to overflow let split_mul = mul << bits_ll; let (temp, mut carry) = split_mul.lo().carrying_add(quo[digits]); quo[digits] = temp; @@ -1076,13 +1115,15 @@ impl ApInt { carry = temp.1; } // special long division algorithm core. - // Note that nearly all branches before this are not just wanted for performance - // reasons but are actually required in order to not break this. - // these blocks subtract `(mul * div) << bits` from `duo` - // check for highest bit set + // Note that nearly all branches before this are not just wanted for + // performance reasons but are actually required + // in order to not break this. these blocks + // subtract `(mul * div) << bits` from `duo` check + // for highest bit set if mul.hi() == Digit::zero() { let mul = mul.lo(); - // carry for bits that wrap across digit boundaries when `<< bits_ll` applied + // carry for bits that wrap across digit boundaries when `<< + // bits_ll` applied let (temp0, mut wrap_carry) = (div[0].dd() << bits_ll).lo_hi(); // the regular multiplication carry let (temp1, mut mul_carry) = @@ -1126,14 +1167,16 @@ impl ApInt { //+______ // 103831 <- temp1 // - // subtract duo by temp1 negated (with the carry from the two's complement - // being put into `wrap_carry`) and shifted (with `wrap_carry`) + // subtract duo by temp1 negated (with the carry from the two's + // complement being put into `wrap_carry`) + // and shifted (with `wrap_carry`) let mul = mul.lo(); let (temp0, mut mul_carry) = mul.carrying_mul(div[0]); let temp1 = temp0; let mut add0_carry = Digit::zero(); - // the increment from the two's complement can be stored in `wrap_carry` + // the increment from the two's complement can be stored in + // `wrap_carry` let (temp2, mut wrap_carry) = ((!temp1).dd().wrapping_add(Digit::one().dd()) << bits_ll) .lo_hi(); @@ -1174,10 +1217,12 @@ impl ApInt { | (div[duo_sd - 2].dd() >> (digit::BITS - duo_lz)) }; let mul = duo_sig_dd.wrapping_div(div_sig_dd).lo(); - // I could avoid allocation but it would involve more long division to recover + // I could avoid allocation but it would involve more long division to + // recover //`div`, followed by a second long multiplication with `mul - 1`. // this will become `-(div * mul)` - // note: div_sd != len - 1 because it would be caught by the first `mul` or + // note: div_sd != len - 1 because it would be caught by the first + // `mul` or //`mul-1` algorithm let mut sub: Vec = Vec::with_capacity(len); // first digit done and carry @@ -1217,7 +1262,8 @@ impl ApInt { return }, { - // the quotient is `quo + mult` and remainder is `duo - (div * mult)` + // the quotient is `quo + mult` and remainder is `duo - (div * + // mult)` twos_complement!(sub_len, sub); special1!(sub_len, duo, sub, div, mul, quo); return @@ -1250,7 +1296,8 @@ impl ApInt { len, div, { - // the quotient should be `quo + 1` and remainder should be `duo - div` + // the quotient should be `quo + 1` and remainder should be + // `duo - div` twos_complement!(len, div); add!(len, div, duo); for i0 in 0..len { @@ -1321,10 +1368,10 @@ impl ApInt { } } - // Note: Special cases are aggressively taken care of throughout this function, both because - // the core long division algorithm does not work on many edges, and because of optimization. - // find the most significant non zeroes, check for `duo` < `div`, and check for division by - // zero + // Note: Special cases are aggressively taken care of throughout this function, + // both because the core long division algorithm does not work on many + // edges, and because of optimization. find the most significant non + // zeroes, check for `duo` < `div`, and check for division by zero match div.iter().rposition(|x| x != &Digit::zero()) { Some(div_sd) => { // the initial most significant nonzero duo digit @@ -1386,12 +1433,12 @@ impl ApInt { } } - /// This function is intended to be inlined into all of the unsigned quotient and remainder - /// functions for optimal assembly. - /// `duo` is divided by `div`, and the remainder is assigned to `duo` and quotient assigned - /// to `div` - /// `false` is returned if division by zero happened. Nothing is modified in the case of - /// division by zero. + /// This function is intended to be inlined into all of the unsigned + /// quotient and remainder functions for optimal assembly. + /// `duo` is divided by `div`, and the remainder is assigned to `duo` and + /// quotient assigned to `div` + /// `false` is returned if division by zero happened. Nothing is modified in + /// the case of division by zero. #[inline] pub(crate) fn aarons_algorithm_remdiv(duo: &mut [Digit], div: &mut [Digit]) -> bool { if ApInt::aarons_algorithm_divrem(duo, div) { @@ -1407,8 +1454,9 @@ impl ApInt { } } - /// Divides `lhs` by `rhs` using **unsigned** interpretation and sets `lhs` equal to the - /// quotient and `rhs` equal to the remainder. This function **may** allocate memory. + /// Divides `lhs` by `rhs` using **unsigned** interpretation and sets `lhs` + /// equal to the quotient and `rhs` equal to the remainder. This + /// function **may** allocate memory. /// /// # Errors /// @@ -1430,14 +1478,17 @@ impl ApInt { } } } - // Note that the typical places `Err` `Ok` are returned is switched. This is because - //`rhs.is_zero()` is found as part of finding `duo_sd` inside `aarons_algorithm_divrem`, + // Note that the typical places `Err` `Ok` are returned is switched. This is + // because + //`rhs.is_zero()` is found as part of finding `duo_sd` inside + //`rhs.is_zero()` `aarons_algorithm_divrem`, // and `lhs.clone()` cannot be performed inside the match statement Err(Error::division_by_zero(DivOp::UnsignedDivRem, lhs.clone())) } - /// Divides `lhs` by `rhs` using **unsigned** interpretation and sets `lhs` equal to the - /// remainder and `rhs` equal to the quotient. This function **may** allocate memory. + /// Divides `lhs` by `rhs` using **unsigned** interpretation and sets `lhs` + /// equal to the remainder and `rhs` equal to the quotient. This + /// function **may** allocate memory. /// /// # Errors /// @@ -1462,8 +1513,8 @@ impl ApInt { Err(Error::division_by_zero(DivOp::UnsignedRemDiv, lhs.clone())) } - /// Quotient-assigns `lhs` by `rhs` inplace using **unsigned** interpretation. - /// This function **may** allocate memory. + /// Quotient-assigns `lhs` by `rhs` inplace using **unsigned** + /// interpretation. This function **may** allocate memory. /// /// # Errors /// @@ -1486,8 +1537,8 @@ impl ApInt { Err(Error::division_by_zero(DivOp::UnsignedDiv, self.clone())) } - /// Divides `lhs` by `rhs` using **unsigned** interpretation and returns the quotient. - /// This function **may** allocate memory. + /// Divides `lhs` by `rhs` using **unsigned** interpretation and returns the + /// quotient. This function **may** allocate memory. /// /// # Errors /// @@ -1497,8 +1548,8 @@ impl ApInt { try_forward_bin_mut_impl(self, rhs, ApInt::wrapping_udiv_assign) } - /// Remainder-assigns `lhs` by `rhs` inplace using **unsigned** interpretation. - /// This function **may** allocate memory. + /// Remainder-assigns `lhs` by `rhs` inplace using **unsigned** + /// interpretation. This function **may** allocate memory. /// /// # Errors /// @@ -1521,8 +1572,8 @@ impl ApInt { Err(Error::division_by_zero(DivOp::UnsignedRem, self.clone())) } - /// Divides `lhs` by `rhs` using **unsigned** interpretation and returns the remainder. - /// This function **may** allocate memory. + /// Divides `lhs` by `rhs` using **unsigned** interpretation and returns the + /// remainder. This function **may** allocate memory. /// /// # Errors /// @@ -1532,8 +1583,9 @@ impl ApInt { try_forward_bin_mut_impl(self, rhs, ApInt::wrapping_urem_assign) } - /// Divides `lhs` by `rhs` using **signed** interpretation and sets `lhs` equal to the - /// quotient and `rhs` equal to the remainder. This function **may** allocate memory. + /// Divides `lhs` by `rhs` using **signed** interpretation and sets `lhs` + /// equal to the quotient and `rhs` equal to the remainder. This + /// function **may** allocate memory. /// /// # Errors /// @@ -1571,8 +1623,9 @@ impl ApInt { Ok(()) } - /// Divides `lhs` by `rhs` using **signed** interpretation and sets `lhs` equal to the - /// remainder and `rhs` equal to the quotient. This function **may** allocate memory. + /// Divides `lhs` by `rhs` using **signed** interpretation and sets `lhs` + /// equal to the remainder and `rhs` equal to the quotient. This + /// function **may** allocate memory. /// /// # Errors /// @@ -1646,8 +1699,8 @@ impl ApInt { Ok(()) } - /// Divides `self` by `rhs` using **signed** interpretation and returns the quotient. - /// This function **may** allocate memory. + /// Divides `self` by `rhs` using **signed** interpretation and returns the + /// quotient. This function **may** allocate memory. /// /// # Errors /// @@ -1657,8 +1710,8 @@ impl ApInt { try_forward_bin_mut_impl(self, rhs, ApInt::wrapping_sdiv_assign) } - /// Remainder-assigns `lhs` by `rhs` inplace using **signed** interpretation. - /// This function **may** allocate memory. + /// Remainder-assigns `lhs` by `rhs` inplace using **signed** + /// interpretation. This function **may** allocate memory. /// /// # Errors /// @@ -1693,8 +1746,8 @@ impl ApInt { Ok(()) } - /// Divides `self` by `rhs` using **signed** interpretation and returns the remainder. - /// This function **may** allocate memory. + /// Divides `self` by `rhs` using **signed** interpretation and returns the + /// remainder. This function **may** allocate memory. /// /// # Errors /// @@ -1892,11 +1945,11 @@ mod tests { #[test] fn rigorous() { - // there are many special case and size optimization paths, so this test must be very - // rigorous. + // there are many special case and size optimization paths, so this test must + // be very rigorous. - // multiplication of apints composed of only u8::MAX in their least significant digits - // only works for num_u8 > 1 + // multiplication of apints composed of only u8::MAX in their least + // significant digits only works for num_u8 > 1 fn nine_test(num_u8: usize) { let mut lhs; let mut rhs = @@ -1913,8 +1966,9 @@ mod tests { lhs |= &nine; // imagine multiplying a string of base 10 nines together. // It will produce things like 998001, 8991, 98901, 9989001. - // this uses a formula for the number of nines, eights, and zeros except here - // nine is u8::MAX, eight is u8::MAX - 1, and zero is 0u8 + // this uses a formula for the number of nines, eights, and zeros + // except here nine is u8::MAX, eight is + // u8::MAX - 1, and zero is 0u8 let zeros_after_one = if lhs_nine < rhs_nine { lhs_nine } else { @@ -2045,24 +2099,34 @@ mod tests { fn simple() { /// does all of the simple division tests /// - `$signed`: if the functions are signed divisions or not - /// - `$fun_assign`: a division function such as `wrapping_udiv_assign` with that - /// signature - /// - `$fun_into`: a division function such as `into_wrapping_udiv` with that signature - /// - `$fun`: a division function such as `wrapping_udivrem_assign` with that signature - /// - `$r0`: the quotient or remainder or both of 80 by 7, depending on division - /// function type - /// - `$r1`, `$r2`, `$r3`: 80 by -7, -80 by 7, -80 by -7. These can be 0 if `$signed` is - /// false. + /// - `$fun_assign`: a division function such as + /// `wrapping_udiv_assign` with that signature + /// - `$fun_into`: a division function such as `into_wrapping_udiv` + /// with that signature + /// - `$fun`: a division function such as `wrapping_udivrem_assign` + /// with that signature + /// - `$r0`: the quotient or remainder or both of 80 by 7, depending + /// on division function type + /// - `$r1`, `$r2`, `$r3`: 80 by -7, -80 by 7, -80 by -7. These can + /// be 0 if `$signed` is false. macro_rules! s { - ($signed:expr,$fun_assign:ident,$fun_into:ident,$r0:expr,$r1:expr,$r2:expr,$r3:expr/*,$div_op:ident*/) => { - /*match $fun_assign - match ApInt::from(123u8).$fun_into(&ApInt::from(0u8)) { - Err(Error{kind: ErrorKind::DivisionByZero{op: DivOp::$div_op, lhs: x}, message: _, annotation: _}) => { - assert_eq!(x,ApInt::from(123u8)); - }, - _ => unreachable!(), - } - match ApInt::from(12345678912345689123456789123456789u128).*/ + ( + $signed:expr, + $fun_assign:ident, + $fun_into:ident, + $r0:expr, + $r1:expr, + $r2:expr, + $r3:expr + ) => { + // match $fun_assign + // match ApInt::from(123u8).$fun_into(&ApInt::from(0u8)) { + // Err(Error{kind: ErrorKind::DivisionByZero{op: DivOp::$div_op, lhs: + // x}, message: _, annotation: _}) => { assert_eq!(x,ApInt:: + // from(123u8)); }, + // _ => unreachable!(), + // } + // match ApInt::from(12345678912345689123456789123456789u128). { let lhs = ApInt::from(80i8); let rhs = ApInt::from(7i8); @@ -2098,38 +2162,36 @@ mod tests { } } }; - ($signed:expr,$fun:ident,$r0:expr,$r1:expr,$r2:expr,$r3:expr/*,$div_op:ident*/) => { + ($signed:expr, $fun:ident, $r0:expr, $r1:expr, $r2:expr, $r3:expr) => {{ + let mut lhs = ApInt::from(80i8); + let mut rhs = ApInt::from(7i8); + ApInt::$fun(&mut lhs, &mut rhs).unwrap(); + assert_eq!(lhs, ApInt::from($r0.0)); + assert_eq!(rhs, ApInt::from($r0.1)); + } + if $signed { { let mut lhs = ApInt::from(80i8); + let mut rhs = ApInt::from(-7i8); + ApInt::$fun(&mut lhs, &mut rhs).unwrap(); + assert_eq!(lhs, ApInt::from($r1.0)); + assert_eq!(rhs, ApInt::from($r1.1)); + } + { + let mut lhs = ApInt::from(-80i8); let mut rhs = ApInt::from(7i8); ApInt::$fun(&mut lhs, &mut rhs).unwrap(); - assert_eq!(lhs, ApInt::from($r0.0)); - assert_eq!(rhs, ApInt::from($r0.1)); + assert_eq!(lhs, ApInt::from($r2.0)); + assert_eq!(rhs, ApInt::from($r2.1)); } - if $signed { - { - let mut lhs = ApInt::from(80i8); - let mut rhs = ApInt::from(-7i8); - ApInt::$fun(&mut lhs, &mut rhs).unwrap(); - assert_eq!(lhs, ApInt::from($r1.0)); - assert_eq!(rhs, ApInt::from($r1.1)); - } - { - let mut lhs = ApInt::from(-80i8); - let mut rhs = ApInt::from(7i8); - ApInt::$fun(&mut lhs, &mut rhs).unwrap(); - assert_eq!(lhs, ApInt::from($r2.0)); - assert_eq!(rhs, ApInt::from($r2.1)); - } - { - let mut lhs = ApInt::from(-80i8); - let mut rhs = ApInt::from(-7i8); - ApInt::$fun(&mut lhs, &mut rhs).unwrap(); - assert_eq!(lhs, ApInt::from($r3.0)); - assert_eq!(rhs, ApInt::from($r3.1)); - } + { + let mut lhs = ApInt::from(-80i8); + let mut rhs = ApInt::from(-7i8); + ApInt::$fun(&mut lhs, &mut rhs).unwrap(); + assert_eq!(lhs, ApInt::from($r3.0)); + assert_eq!(rhs, ApInt::from($r3.1)); } - } + }}; } s!( false, @@ -2413,7 +2475,11 @@ mod tests { assert_eq!(rhs.clone().into_wrapping_udiv(&rhs).unwrap(), one); let temp = product.clone().into_wrapping_udiv(&lhs).unwrap(); if temp != rhs { - panic!("lhs_shl:{:?}\nrhs_shl:{:?}\nlhs:{:?}\nrhs:{:?}\n={:?}\ntemp:{:?}",lhs_shl[i],rhs_shl[i],lhs,rhs,product,temp); + panic!( + "lhs_shl:{:?}\nrhs_shl:{:?}\nlhs:{:?}\nrhs:{:?}\n={:?}\ntemp:{:?\ + }", + lhs_shl[i], rhs_shl[i], lhs, rhs, product, temp + ); } assert_eq!(product.clone().into_wrapping_udiv(&rhs).unwrap(), lhs); assert_eq!(zero.clone().into_wrapping_urem(&lhs).unwrap(), zero); @@ -2491,8 +2557,8 @@ mod tests { ); } - // throws all the functions together for an identities party. If one function breaks, the - // whole thing should break. + // throws all the functions together for an identities party. If one function + // breaks, the whole thing should break. fn identities( size: usize, width: BitWidth, @@ -2561,8 +2627,8 @@ mod tests { lhs.clone().into_wrapping_udiv(&tmp1).unwrap() ); if (shift == (size - 1)) && (lhs == tmp1) { - // unfortunate numerical corner case where the result of the shift is -1 but the - // division ends up as +1 + // unfortunate numerical corner case where the result of the shift is -1 + // but the division ends up as +1 assert_eq!( lhs.clone().into_wrapping_sdiv(&tmp1).unwrap(), ApInt::one(width) @@ -2621,10 +2687,38 @@ mod tests { let mul_plus_rem = temp0.clone(); ApInt::wrapping_udivrem_assign(&mut temp0, &mut temp1).unwrap(); if temp0 != (lhs.clone() & &anti_overflow_mask) { - panic!("wrong div\nlhs:{:?}\nactual:{:?}\nrhs:{:?}\nthird:{:?}\nrem:{:?}\nmul:{:?}\nmul_plus_rem:{:?}\ntemp0:{:?}\ntemp1:{:?}",lhs,(lhs.clone() & &anti_overflow_mask),rhs,third,rem,mul,mul_plus_rem,temp0,temp1) + panic!( + "wrong div\nlhs:{:?}\nactual:{:?}\nrhs:{:?}\nthird:{:?}\\ + \ + nrem:{:?}\nmul:{:?}\nmul_plus_rem:{:?}\ntemp0:{:?}\ntemp1:\ + {:?}", + lhs, + (lhs.clone() & &anti_overflow_mask), + rhs, + third, + rem, + mul, + mul_plus_rem, + temp0, + temp1 + ) } if temp1 != rem { - panic!("wrong rem\nlhs:{:?}\nactual:{:?}\nrhs:{:?}\nthird:{:?}\nrem:{:?}\nmul:{:?}\nmul_plus_rem:{:?}\ntemp0:{:?}\ntemp1:{:?}",lhs,(lhs.clone() & &anti_overflow_mask),rhs,third,rem,mul,mul_plus_rem,temp0,temp1) + panic!( + "wrong rem\nlhs:{:?}\nactual:{:?}\nrhs:{:?}\nthird:{:?}\\ + \ + nrem:{:?}\nmul:{:?}\nmul_plus_rem:{:?}\ntemp0:{:?}\ntemp1:\ + {:?}", + lhs, + (lhs.clone() & &anti_overflow_mask), + rhs, + third, + rem, + mul, + mul_plus_rem, + temp0, + temp1 + ) } } } diff --git a/src/apint/bitwise.rs b/src/apint/bitwise.rs index 5465a8e..de9e1eb 100644 --- a/src/apint/bitwise.rs +++ b/src/apint/bitwise.rs @@ -176,8 +176,8 @@ impl ApInt { /// /// # Note /// - /// - If the bit at the given position was `0` it will be `1` - /// after this operation and vice versa. + /// - If the bit at the given position was `0` it will be `1` after this + /// operation and vice versa. /// /// # Errors /// @@ -260,9 +260,10 @@ impl ApInt { /// /// # Note /// - /// - If the sign bit was `0` it will be `1` after this operation and vice versa. - /// - Depending on the interpretation of the `ApInt` this - /// operation changes its signedness. + /// - If the sign bit was `0` it will be `1` after this operation and vice + /// versa. + /// - Depending on the interpretation of the `ApInt` this operation changes + /// its signedness. pub fn flip_sign_bit(&mut self) { let sign_bit_pos = self.width().sign_bit_pos(); self.flip_bit_at(sign_bit_pos).expect( @@ -282,7 +283,8 @@ impl ApInt { .sum::() } - /// Returns the number of zeros in the binary representation of this `ApInt`. + /// Returns the number of zeros in the binary representation of this + /// `ApInt`. pub fn count_zeros(&self) -> usize { let zeros = self .as_digit_slice() @@ -295,7 +297,8 @@ impl ApInt { zeros - (digit::BITS - self.width().excess_bits().unwrap_or(digit::BITS)) } - /// Returns the number of leading zeros in the binary representation of this `ApInt`. + /// Returns the number of leading zeros in the binary representation of this + /// `ApInt`. pub fn leading_zeros(&self) -> usize { let mut zeros = 0; for d in self.as_digit_slice().iter().rev() { @@ -308,7 +311,8 @@ impl ApInt { zeros - (digit::BITS - self.width().excess_bits().unwrap_or(digit::BITS)) } - /// Returns the number of trailing zeros in the binary representation of this `ApInt`. + /// Returns the number of trailing zeros in the binary representation of + /// this `ApInt`. pub fn trailing_zeros(&self) -> usize { let mut zeros = 0; for d in self.as_digit_slice() { diff --git a/src/apint/casting.rs b/src/apint/casting.rs index 0631725..334b685 100644 --- a/src/apint/casting.rs +++ b/src/apint/casting.rs @@ -153,8 +153,8 @@ impl ApInt { return Error::truncation_bitwidth_too_large(target_width, actual_width) .with_annotation(format!( "Cannot truncate `ApInt` with a width of {:?} - to an `ApInt` with a width of {:?} bits. \ - Do you mean to extend the instance instead?", + to an `ApInt` with a width of {:?} bits. Do you mean to extend \ + the instance instead?", actual_width.to_usize(), target_width.to_usize() )) @@ -174,8 +174,8 @@ impl ApInt { // The same applies to all bit widths that require the same // amount of digits for their representation. let excess_width = target_width.excess_bits().expect( - "We already filtered cases where `excess_bits` may return `None` \ - by requiring that `self.width() > target_width`.", + "We already filtered cases where `excess_bits` may return `None` by \ + requiring that `self.width() > target_width`.", ); self.most_significant_digit_mut() .truncate_to(excess_width) @@ -255,8 +255,8 @@ impl ApInt { if target_width < actual_width { return Error::extension_bitwidth_too_small(target_width, actual_width) .with_annotation(format!( - "Cannot zero-extend bit-width of {:?} to {:?} bits. \ - Do you mean to truncate the instance instead?", + "Cannot zero-extend bit-width of {:?} to {:?} bits. Do you mean to \ + truncate the instance instead?", actual_width, target_width )) .into() @@ -341,8 +341,8 @@ impl ApInt { if target_width < actual_width { return Error::extension_bitwidth_too_small(target_width, actual_width) .with_annotation(format!( - "Cannot sign-extend bit-width of {:?} to {:?} bits. \ - Do you mean to truncate the instance instead?", + "Cannot sign-extend bit-width of {:?} to {:?} bits. Do you mean to \ + truncate the instance instead?", actual_width, target_width )) .into() @@ -385,7 +385,8 @@ impl ApInt { assert!(target_req_digits > actual_req_digits); let additional_digits = target_req_digits - actual_req_digits; - // Fill most-significant-digit of `self` with `1` starting from its most-significant bit. + // Fill most-significant-digit of `self` with `1` starting from its + // most-significant bit. if let Some(excess_width) = actual_width.excess_width() { self.most_significant_digit_mut() .sign_extend_from(excess_width)?; @@ -442,11 +443,9 @@ impl ApInt { /// /// This operation will forward to /// - /// - [`truncate`](struct.ApInt.html#method.truncate) - /// if `target_width` is less than or equal to the width of - /// the given `ApInt` - /// - [`zero_extend`](struct.ApInt.html#method.zero_extend) - /// otherwise + /// - [`truncate`](struct.ApInt.html#method.truncate) if `target_width` is + /// less than or equal to the width of the given `ApInt` + /// - [`zero_extend`](struct.ApInt.html#method.zero_extend) otherwise pub fn zero_resize(&mut self, target_width: W) where W: Into, @@ -456,13 +455,13 @@ impl ApInt { if target_width <= actual_width { self.truncate(target_width).expect( - "It was asserted that `target_width` is \ - a valid truncation `BitWidth` in this context.", + "It was asserted that `target_width` is a valid truncation `BitWidth` \ + in this context.", ) } else { self.zero_extend(target_width).expect( - "It was asserted that `target_width` is \ - a valid zero-extension `BitWidth` in this context.", + "It was asserted that `target_width` is a valid zero-extension \ + `BitWidth` in this context.", ) } } @@ -473,11 +472,9 @@ impl ApInt { /// /// This operation will forward to /// - /// - [`truncate`](struct.ApInt.html#method.truncate) - /// if `target_width` is less than or equal to the width of - /// the given `ApInt` - /// - [`sign_extend`](struct.ApInt.html#method.sign_extend) - /// otherwise + /// - [`truncate`](struct.ApInt.html#method.truncate) if `target_width` is + /// less than or equal to the width of the given `ApInt` + /// - [`sign_extend`](struct.ApInt.html#method.sign_extend) otherwise pub fn sign_resize(&mut self, target_width: W) where W: Into, @@ -487,13 +484,13 @@ impl ApInt { if target_width <= actual_width { self.truncate(target_width).expect( - "It was asserted that `target_width` is \ - a valid truncation `BitWidth` in this context.", + "It was asserted that `target_width` is a valid truncation `BitWidth` \ + in this context.", ) } else { self.sign_extend(target_width).expect( - "It was asserted that `target_width` is \ - a valid sign-extension `BitWidth` in this context.", + "It was asserted that `target_width` is a valid sign-extension \ + `BitWidth` in this context.", ) } } @@ -543,35 +540,6 @@ mod tests { ApInt::from_u128(0x0000_0000_FFFF_FFFF_FFFF_FFFF_0000_0000), ApInt::from_u128(0x0000_0000_0000_0000_FFFF_FFFF_FFFF_FFFF), ApInt::all_set(BitWidth::w128()), - /* ApInt::zero(width_256), - * ApInt::one(width_256), - * ApInt::repeat_digit(width_256, Digit(1)), - * ApInt::repeat_digit(width_256, Digit(42)), - * ApInt::repeat_digit(width_256, Digit(1337)), - * ApInt::repeat_digit(width_256, 0xFFFF_FFFF_0000_0000), - * ApInt::repeat_digit(width_256, 0x0000_FFFF_FFFF_0000), - * ApInt::repeat_digit(width_256, 0x0000_0000_FFFF_FFFF), - * ApInt::all_set(width_256), */ - - /* ApInt::zero(width_500), - * ApInt::one(width_500), - * ApInt::repeat_digit(width_500, Digit(1)), - * ApInt::repeat_digit(width_500, Digit(42)), - * ApInt::repeat_digit(width_500, Digit(1337)), - * ApInt::repeat_digit(width_500, 0xFFFF_FFFF_0000_0000), - * ApInt::repeat_digit(width_500, 0x0000_FFFF_FFFF_0000), - * ApInt::repeat_digit(width_500, 0x0000_0000_FFFF_FFFF), - * ApInt::all_set(width_500), */ - - /* ApInt::zero(width_512), - * ApInt::one(width_512), - * ApInt::repeat_digit(width_512, Digit(1)), - * ApInt::repeat_digit(width_512, Digit(42)), - * ApInt::repeat_digit(width_512, Digit(1337)), - * ApInt::repeat_digit(width_512, 0xFFFF_FFFF_0000_0000), - * ApInt::repeat_digit(width_512, 0x0000_FFFF_FFFF_0000), - * ApInt::repeat_digit(width_512, 0x0000_0000_FFFF_FFFF), - * ApInt::all_set(width_512), */ ] .into_iter() } @@ -581,14 +549,16 @@ mod tests { /// Test Clone impl of `ApInt`. /// - /// Invariants between the origin `ApInt` `o` and for the cloned `c` are: + /// Invariants between the origin `ApInt` `o` and for the cloned `c` + /// are: /// /// - `o` and `c` have same bit widths - /// - If `o` is heap-allocated then `c` is, too and vice versa for stack. + /// - If `o` is heap-allocated then `c` is, too and vice versa for + /// stack. /// - `o` and `c` have an equal amount of digits and the values of their /// digits is equal and in the same order. - /// - Memory addresses of `c` and `o` won't overlap. (No aliasing!) - /// This is enforced by safe Rust. + /// - Memory addresses of `c` and `o` won't overlap. (No aliasing!) This + /// is enforced by safe Rust. #[test] fn clone() { for apint in test_apints() { diff --git a/src/apint/constructors.rs b/src/apint/constructors.rs index 4c346e4..e97155e 100644 --- a/src/apint/constructors.rs +++ b/src/apint/constructors.rs @@ -74,8 +74,8 @@ impl ApInt { /// /// # Panics /// - /// - If the given `width` represents a `BitWidth` smaller than - /// or equal to `64` bits. + /// - If the given `width` represents a `BitWidth` smaller than or equal to + /// `64` bits. pub(in crate::apint) unsafe fn new_ext( width: BitWidth, ext_ptr: *mut Digit, @@ -89,9 +89,11 @@ impl ApInt { } } - /// Creates a new `ApInt` from the given `Bit` value with a bit width of `1`. + /// Creates a new `ApInt` from the given `Bit` value with a bit width of + /// `1`. /// - /// This function is generic over types that are convertible to `Bit` such as `bool`. + /// This function is generic over types that are convertible to `Bit` such + /// as `bool`. pub fn from_bit(bit: B) -> ApInt where B: Into, @@ -166,11 +168,11 @@ impl ApInt { /// of a `Digit`s bitwidth (e.g. 64 bit). /// /// Users of this API may truncate, extend or simply resize the resulting - /// `ApInt` afterwards to obtain the desired bitwidth. This may be very cheap - /// depending on the difference between the actual and target bitwidths. - /// For example, `move_truncate`ing a `128` bitwidth `ApInt` to `100` is - /// relatively cheap and won't allocate memory since both `ApInt` instances can use - /// the same amount of `Digit`s. + /// `ApInt` afterwards to obtain the desired bitwidth. This may be very + /// cheap depending on the difference between the actual and target + /// bitwidths. For example, `move_truncate`ing a `128` bitwidth `ApInt` + /// to `100` is relatively cheap and won't allocate memory since both + /// `ApInt` instances can use the same amount of `Digit`s. /// /// # Errors /// @@ -183,16 +185,19 @@ impl ApInt { match buffer.len() { 0 => Err(Error::expected_non_empty_digits()), 1 => { - let first_and_only = *buffer - .first() - .expect("We have already asserted that `digits.len()` must be at exactly `1`."); + let first_and_only = *buffer.first().expect( + "We have already asserted that `digits.len()` must be at exactly \ + `1`.", + ); Ok(ApInt::new_inl(BitWidth::w64(), first_and_only)) } n => { use core::mem; - let bitwidth = BitWidth::new(n * digit::BITS) - .expect("We have already asserted that the number of items the given Iterator \ - iterates over is greater than `1` and thus non-zero and thus a valid `BitWidth`."); + let bitwidth = BitWidth::new(n * digit::BITS).expect( + "We have already asserted that the number of items the given \ + Iterator iterates over is greater than `1` and thus non-zero and \ + thus a valid `BitWidth`.", + ); let req_digits = bitwidth.required_digits(); buffer.shrink_to_fit(); assert_eq!(buffer.capacity(), req_digits); @@ -218,8 +223,8 @@ impl ApInt { /// Creates a new `ApInt` that represents the repetition of the given digit /// up to the given target bitwidth. /// - /// Note: The last digit in the generated sequence is truncated to make the `ApInt`'s - /// value representation fit the given bit-width. + /// Note: The last digit in the generated sequence is truncated to make the + /// `ApInt`'s value representation fit the given bit-width. pub(in crate::apint) fn repeat_digit(target_width: BitWidth, digit: D) -> ApInt where D: Into, @@ -229,18 +234,16 @@ impl ApInt { let req_digits = target_width.required_digits(); ApInt::from_iter(iter::repeat(digit).take(req_digits)) .expect( - "Since `required_digits` always returns `1` or more \ - required digits we can safely assume that this operation \ - never fails.", + "Since `required_digits` always returns `1` or more required digits we \ + can safely assume that this operation never fails.", ) .into_truncate(target_width) .expect( - "Since `BitWidth::required_digits` always returns the upper bound \ - for the number of digits required to represent the given `BitWidth` \ - and `ApInt::from_iter` will use exactly this upper bound \ - we can safely assume that `target_width` is always equal or \ - less than what `ApInt::from_iter` returns and thus truncation will \ - never fail.", + "Since `BitWidth::required_digits` always returns the upper bound for \ + the number of digits required to represent the given `BitWidth` and \ + `ApInt::from_iter` will use exactly this upper bound we can safely \ + assume that `target_width` is always equal or less than what \ + `ApInt::from_iter` returns and thus truncation will never fail.", ) } @@ -266,24 +269,28 @@ impl ApInt { ApInt::repeat_digit(width, digit::ONES) } - /// Returns the smallest unsigned `ApInt` that can be represented by the given `BitWidth`. + /// Returns the smallest unsigned `ApInt` that can be represented by the + /// given `BitWidth`. pub fn unsigned_min_value(width: BitWidth) -> ApInt { ApInt::zero(width) } - /// Returns the largest unsigned `ApInt` that can be represented by the given `BitWidth`. + /// Returns the largest unsigned `ApInt` that can be represented by the + /// given `BitWidth`. pub fn unsigned_max_value(width: BitWidth) -> ApInt { ApInt::all_set(width) } - /// Returns the smallest signed `ApInt` that can be represented by the given `BitWidth`. + /// Returns the smallest signed `ApInt` that can be represented by the given + /// `BitWidth`. pub fn signed_min_value(width: BitWidth) -> ApInt { let mut result = ApInt::zero(width); result.set_sign_bit(); result } - /// Returns the largest signed `ApInt` that can be represented by the given `BitWidth`. + /// Returns the largest signed `ApInt` that can be represented by the given + /// `BitWidth`. pub fn signed_max_value(width: BitWidth) -> ApInt { let mut result = ApInt::all_set(width); result.unset_sign_bit(); @@ -383,16 +390,11 @@ macro_rules! impl_from_array_for_apint { impl From<[u64; $n]> for ApInt { fn from(val: [u64; $n]) -> ApInt { - let buffer = val - .iter() - .rev() - .cloned() - .map(Digit) - .collect::>(); + let buffer = val.iter().rev().cloned().map(Digit).collect::>(); assert_eq!(buffer.len(), $n); ApInt::from_iter(buffer).expect( - "We asserted that `buffer.len()` is exactly `$n` \ - so we can expect `ApInt::from_iter` to be successful.", + "We asserted that `buffer.len()` is exactly `$n` so we can expect \ + `ApInt::from_iter` to be successful.", ) } } diff --git a/src/apint/mod.rs b/src/apint/mod.rs index 6981003..94134c9 100644 --- a/src/apint/mod.rs +++ b/src/apint/mod.rs @@ -24,7 +24,8 @@ pub(crate) use self::to_primitive::PrimitiveTy; use core::ptr::NonNull; -/// An arbitrary precision integer with modulo arithmetics similar to machine integers. +/// An arbitrary precision integer with modulo arithmetics similar to machine +/// integers. pub struct ApInt { /// The width in bits of this `ApInt`. len: BitWidth, diff --git a/src/apint/rand_impl.rs b/src/apint/rand_impl.rs index f729c3c..1ef73ba 100644 --- a/src/apint/rand_impl.rs +++ b/src/apint/rand_impl.rs @@ -32,14 +32,22 @@ impl ApInt { { let required_digits = width.required_digits(); assert!(required_digits >= 1); - use rand::distributions::{Standard, Distribution}; + use rand::distributions::{ + Distribution, + Standard, + }; let random_digits = Standard.sample_iter(rng).take(required_digits); + // The truncation will be cheap always! ApInt::from_iter(random_digits) - .expect("We asserted that `required_digits` is at least `1` or greater - so it is safe to assume that `ApInt::from_iter` won't fail.") - .into_truncate(width) // This truncation will be cheap always! - .expect("`BitWidth::required_digits` returns an upper bound for the - number of required digits, so it is safe to truncate.") + .expect( + "We asserted that `required_digits` is at least `1` or greater + so it is safe to assume that `ApInt::from_iter` won't fail.", + ) + .into_truncate(width) + .expect( + "`BitWidth::required_digits` returns an upper bound for the + number of required digits, so it is safe to truncate.", + ) } /// Randomizes the digits of this `ApInt` inplace. @@ -57,11 +65,12 @@ impl ApInt { where R: rand::Rng, { - use rand::distributions::{Standard, Distribution}; + use rand::distributions::{ + Distribution, + Standard, + }; let std_dist = Standard.sample_iter(rng); - self.digits_mut() - .zip(std_dist) - .for_each(|(d, r)| *d = r); + self.digits_mut().zip(std_dist).for_each(|(d, r)| *d = r); self.clear_unused_bits(); } } @@ -70,9 +79,7 @@ impl ApInt { mod tests { use super::*; use rand::SeedableRng; - use rand_xorshift::{ - XorShiftRng, - }; + use rand_xorshift::XorShiftRng; #[test] fn random_with_width_using() { diff --git a/src/apint/relational.rs b/src/apint/relational.rs index d1d41ef..bd54d72 100644 --- a/src/apint/relational.rs +++ b/src/apint/relational.rs @@ -40,26 +40,20 @@ impl ApInt { /// /// - If `self` and `rhs` have unmatching bit widths. pub fn checked_ult(&self, rhs: &ApInt) -> Result { - match self - .zip_access_data(rhs) - .map_err(|err| err.with_annotation(format!( - "Error occured on unsigned less-than (slt) comparison with `lhs < rhs` where \ - \n\tlhs = {:?}\ - \n\trhs = {:?}", - self, rhs) - ))? - { - ZipDataAccess::Inl(lhs, rhs) => { - Ok(lhs.repr() < rhs.repr()) - } + match self.zip_access_data(rhs).map_err(|err| { + err.with_annotation(format!( + "Error occured on unsigned less-than (slt) comparison with `lhs < rhs` \ + where \n\tlhs = {:?}\n\trhs = {:?}", + self, rhs + )) + })? { + ZipDataAccess::Inl(lhs, rhs) => Ok(lhs.repr() < rhs.repr()), ZipDataAccess::Ext(lhs, rhs) => { - for (l, r) in lhs.iter().rev() - .zip(rhs.iter().rev()) - { + for (l, r) in lhs.iter().rev().zip(rhs.iter().rev()) { match l.cmp(r) { - Ordering::Less => return Ok(true), + Ordering::Less => return Ok(true), Ordering::Greater => return Ok(false), - Ordering::Equal => () + Ordering::Equal => (), } } Ok(false) @@ -80,13 +74,13 @@ impl ApInt { /// - If `self` and `rhs` have unmatching bit widths. #[inline] pub fn checked_ule(&self, rhs: &ApInt) -> Result { - rhs.checked_ult(self).map(Not::not) - .map_err(|err| err.with_annotation(format!( - "Error occured on unsigned less-than or equals (ule) comparison with `lhs <= rhs` where \ - \n\tlhs = {:?}\ - \n\trhs = {:?}", - self, rhs) + rhs.checked_ult(self).map(Not::not).map_err(|err| { + err.with_annotation(format!( + "Error occured on unsigned less-than or equals (ule) comparison with \ + `lhs <= rhs` where \n\tlhs = {:?}\n\trhs = {:?}", + self, rhs )) + }) } /// Unsigned greater-than (`ugt`) comparison between `self` and `rhs`. @@ -102,13 +96,13 @@ impl ApInt { /// - If `self` and `rhs` have unmatching bit widths. #[inline] pub fn checked_ugt(&self, rhs: &ApInt) -> Result { - rhs.checked_ult(self) - .map_err(|err| err.with_annotation(format!( - "Error occured on unsigned greater-than (ugt) comparison with `lhs > rhs` where \ - \n\tlhs = {:?}\ - \n\trhs = {:?}", - self, rhs) + rhs.checked_ult(self).map_err(|err| { + err.with_annotation(format!( + "Error occured on unsigned greater-than (ugt) comparison with `lhs > \ + rhs` where \n\tlhs = {:?}\n\trhs = {:?}", + self, rhs )) + }) } /// Unsigned greater-equals (`uge`) comparison between `self` and `rhs`. @@ -124,13 +118,13 @@ impl ApInt { /// - If `self` and `rhs` have unmatching bit widths. #[inline] pub fn checked_uge(&self, rhs: &ApInt) -> Result { - self.checked_ult(rhs).map(Not::not) - .map_err(|err| err.with_annotation(format!( - "Error occured on unsigned greater-than or equals (ule) comparison with `lhs >= rhs` where \ - \n\tlhs = {:?}\ - \n\trhs = {:?}", - self, rhs) + self.checked_ult(rhs).map(Not::not).map_err(|err| { + err.with_annotation(format!( + "Error occured on unsigned greater-than or equals (ule) comparison with \ + `lhs >= rhs` where \n\tlhs = {:?}\n\trhs = {:?}", + self, rhs )) + }) } /// Signed less-than (`slt`) comparison between `self` and `rhs`. @@ -155,7 +149,7 @@ impl ApInt { let rhs = (rhs.repr() << infate_abs) as i64; Ok(lhs < rhs) } - ZipDataAccess::Ext(_, _) => { + ZipDataAccess::Ext(..) => { match (lhs.sign_bit(), rhs.sign_bit()) { (Bit::Unset, Bit::Unset) => lhs.checked_ult(rhs), (Bit::Unset, Bit::Set) => Ok(false), @@ -167,10 +161,10 @@ impl ApInt { }) .map_err(|err| { err.with_annotation(format!( - "Error occured on signed less-than (slt) comparison with `lhs < rhs` where \ - \n\tlhs = {:?}\ - \n\trhs = {:?}", - self, rhs)) + "Error occured on signed less-than (slt) comparison with `lhs < \ + rhs` where \n\tlhs = {:?}\n\trhs = {:?}", + self, rhs + )) }) } @@ -187,13 +181,13 @@ impl ApInt { /// - If `self` and `rhs` have unmatching bit widths. #[inline] pub fn checked_sle(&self, rhs: &ApInt) -> Result { - rhs.checked_slt(self).map(Not::not) - .map_err(|err| err.with_annotation(format!( - "Error occured on signed less-than or equals (ule) comparison with `lhs <= rhs` where \ - \n\tlhs = {:?}\ - \n\trhs = {:?}", - self, rhs) + rhs.checked_slt(self).map(Not::not).map_err(|err| { + err.with_annotation(format!( + "Error occured on signed less-than or equals (ule) comparison with `lhs \ + <= rhs` where \n\tlhs = {:?}\n\trhs = {:?}", + self, rhs )) + }) } /// Signed greater-than (`sgt`) comparison between `self` and `rhs`. @@ -209,13 +203,13 @@ impl ApInt { /// - If `self` and `rhs` have unmatching bit widths. #[inline] pub fn checked_sgt(&self, rhs: &ApInt) -> Result { - rhs.checked_slt(self) - .map_err(|err| err.with_annotation(format!( - "Error occured on signed greater-than (ugt) comparison with `lhs > rhs` where \ - \n\tlhs = {:?}\ - \n\trhs = {:?}", - self, rhs) + rhs.checked_slt(self).map_err(|err| { + err.with_annotation(format!( + "Error occured on signed greater-than (ugt) comparison with `lhs > rhs` \ + where \n\tlhs = {:?}\n\trhs = {:?}", + self, rhs )) + }) } /// Signed greater-equals (`sge`) comparison between `self` and `rhs`. @@ -231,13 +225,13 @@ impl ApInt { /// - If `self` and `rhs` have unmatching bit widths. #[inline] pub fn checked_sge(&self, rhs: &ApInt) -> Result { - self.checked_slt(rhs).map(Not::not) - .map_err(|err| err.with_annotation(format!( - "Error occured on signed greater-than or equals (ule) comparison with `lhs >= rhs` where \ - \n\tlhs = {:?}\ - \n\trhs = {:?}", - self, rhs) + self.checked_slt(rhs).map(Not::not).map_err(|err| { + err.with_annotation(format!( + "Error occured on signed greater-than or equals (ule) comparison with \ + `lhs >= rhs` where \n\tlhs = {:?}\n\trhs = {:?}", + self, rhs )) + }) } } diff --git a/src/apint/serde_impl.rs b/src/apint/serde_impl.rs index 6c97a6f..7d651c6 100644 --- a/src/apint/serde_impl.rs +++ b/src/apint/serde_impl.rs @@ -245,12 +245,17 @@ impl<'de> Deserialize<'de> for ApInt { } Ok(ApInt::from_iter(digits) - .expect("We already asserted that we deserialized the lower-bound \ - of `required_digits` so `ApInt::from_iter` is fail free.") + .expect( + "We already asserted that we deserialized the lower-bound of \ + `required_digits` so `ApInt::from_iter` is fail free.", + ) .into_truncate(width) - .expect("An `into_truncate` call to `width` cannot fail since `digits` - contains exactly `required_digits` digits and `ApInt::from_iter \ - always creates an `ApInt` with an upper bound bit width.")) + .expect( + "An `into_truncate` call to `width` cannot fail since `digits` + contains exactly `required_digits` digits and \ + `ApInt::from_iter always creates an `ApInt` with an upper \ + bound bit width.", + )) } } @@ -280,12 +285,17 @@ impl<'de> Deserialize<'de> for ApInt { } Ok(ApInt::from_iter(digits) - .expect("We already asserted that we deserialized the lower-bound \ - of `required_digits` so `ApInt::from_iter` is fail free.") + .expect( + "We already asserted that we deserialized the lower-bound of \ + `required_digits` so `ApInt::from_iter` is fail free.", + ) .into_truncate(width) - .expect("An `into_truncate` call to `width` cannot fail since `digits` - contains exactly `required_digits` digits and `ApInt::from_iter \ - always creates an `ApInt` with an upper bound bit width.")) + .expect( + "An `into_truncate` call to `width` cannot fail since `digits` \ + contains exactly `required_digits` digits and \ + `ApInt::from_iter always creates an `ApInt` with an upper \ + bound bit width.", + )) } } diff --git a/src/apint/serialization.rs b/src/apint/serialization.rs index 76d10b4..cdc4076 100644 --- a/src/apint/serialization.rs +++ b/src/apint/serialization.rs @@ -85,34 +85,46 @@ impl fmt::UpperHex for ApInt { /// # Deserialization impl ApInt { - /// Parses the given `input` `String` with the given `Radix` and returns an `ApInt` - /// with the given `target_width` `BitWidth`. + /// Parses the given `input` `String` with the given `Radix` and returns an + /// `ApInt` with the given `target_width` `BitWidth`. /// - /// **Note:** The given `input` is parsed as big-endian value. This means, the most significant bit (MSB) - /// is the leftst bit in the string representation provided by the user. + /// **Note:** The given `input` is parsed as big-endian value. This means, + /// the most significant bit (MSB) is the leftst bit in the string + /// representation provided by the user. /// - /// The string is assumed to contain no whitespace and contain only values within a subset of the - /// range of `0`..`9` and `a`..`z` depending on the given `radix`. + /// The string is assumed to contain no whitespace and contain only values + /// within a subset of the range of `0`..`9` and `a`..`z` depending on + /// the given `radix`. /// - /// The string is assumed to have no sign as `ApInt` does not handle signdness. + /// The string is assumed to have no sign as `ApInt` does not handle + /// signdness. /// /// # Errors /// /// - If `input` is empty. - /// - If `input` is not a valid representation for an `ApInt` for the given `radix`. - /// - If `input` has trailing zero characters (`0`), e.g. `"0042"` instead of `"42"`. - /// - If `input` represents an `ApInt` value that does not fit into the given `target_bitwidth`. + /// - If `input` is not a valid representation for an `ApInt` for the given + /// `radix`. + /// - If `input` has trailing zero characters (`0`), e.g. `"0042"` instead + /// of `"42"`. + /// - If `input` represents an `ApInt` value that does not fit into the + /// given `target_bitwidth`. /// /// # Examples /// /// ```no_run /// # use apint::ApInt; - /// let a = ApInt::from_str_radix(10, "42"); // ok - /// let b = ApInt::from_str_radix( 2, "1011011"); // ok (dec. = 91) - /// let c = ApInt::from_str_radix(16, "ffcc00"); // ok (dec. = 16763904) - /// let c = ApInt::from_str_radix(10, "256"); // Error: 256 does not fit within 8 bits! - /// let d = ApInt::from_str_radix( 2, "01020"); // Error: Invalid digit '2' at position 3 for given radix. - /// let e = ApInt::from_str_radix(16, "hello"); // Error: "hello" is not a valid ApInt representation! + /// // ok + /// let a = ApInt::from_str_radix(10, "42"); + /// // ok (dec. = 91) + /// let b = ApInt::from_str_radix(2, "1011011"); + /// // ok (dec. = 16763904) + /// let c = ApInt::from_str_radix(16, "ffcc00"); + /// // Error: 256 does not fit within 8 bits! + /// let c = ApInt::from_str_radix(10, "256"); + /// // Error: Invalid digit '2' at position 3 for given radix. + /// let d = ApInt::from_str_radix(2, "01020"); + /// // Error: "hello" is not a valid ApInt representation! + /// let e = ApInt::from_str_radix(16, "hello"); /// ``` pub fn from_str_radix(radix: R, input: S) -> Result where @@ -175,8 +187,8 @@ impl ApInt { Ok(result) } - // Convert from a power of two radix (bits == ilog2(radix)) where bits evenly divides - // Digit::BITS. + // Convert from a power of two radix (bits == ilog2(radix)) where bits evenly + // divides Digit::BITS. // // Forked from: https://github.com/rust-num/num/blob/master/bigint/src/biguint.rs#L126 // @@ -205,8 +217,8 @@ impl ApInt { ApInt::from_iter(data).unwrap() } - // Convert from a power of two radix (bits == ilog2(radix)) where bits doesn't evenly divide - // Digit::BITS. + // Convert from a power of two radix (bits == ilog2(radix)) where bits doesn't + // evenly divide Digit::BITS. // // Forked from: https://github.com/rust-num/num/blob/master/bigint/src/biguint.rs#L143 // @@ -226,7 +238,8 @@ impl ApInt { let mut d = 0; let mut dbits = 0; // Number of bits we currently have in d. - // Walk v accumulating bits in d; whenever we accumulate digit::BITS in d, spit out a digit: + // Walk v accumulating bits in d; whenever we accumulate digit::BITS in d, spit + // out a digit: for &c in v { d |= (DigitRepr::from(c)) << dbits; dbits += bits; @@ -234,8 +247,9 @@ impl ApInt { if dbits >= digit::BITS { data.push(Digit(d)); dbits -= digit::BITS; - // If `dbits` was greater than `digit::BITS`, we dropped some of the bits in c - // (they couldn't fit in d) - grab the bits we lost here: + // If `dbits` was greater than `digit::BITS`, we dropped some of the bits + // in c (they couldn't fit in d) - grab the bits we lost + // here: d = (DigitRepr::from(c)) >> (bits - dbits); } } @@ -290,12 +304,15 @@ impl ApInt { let carry = 0; for _d in &mut data { - // *d = mac_with_carry(0, *d, base, &mut carry); // TODO! This was commented out. + // *d = mac_with_carry(0, *d, base, &mut carry); // TODO! This + // was commented out. - // // fn carry_mul_add(a: Digit, b: Digit, c: Digit, carry: Digit) -> DigitAndCarry - // // Returns the result of `(a + (b * c)) + carry` and its implied carry value. + // // fn carry_mul_add(a: Digit, b: Digit, c: Digit, carry: + // Digit) -> DigitAndCarry // Returns the result + // of `(a + (b * c)) + carry` and its implied carry value. - // let DigitAndCarry(d, carry) = carry_mul_add(digit::ZERO, *d, base, carry); // TODO! This was commented out. + // let DigitAndCarry(d, carry) = carry_mul_add(digit::ZERO, *d, + // base, carry); // TODO! This was commented out. } debug_assert!(carry == 0); @@ -313,7 +330,8 @@ impl ApInt { /// Serialization /// ======================================================================= impl ApInt { - /// Returns a `String` representation of the binary encoded `ApInt` for the given `Radix`. + /// Returns a `String` representation of the binary encoded `ApInt` for the + /// given `Radix`. pub fn to_string_radix(&self, radix: R) -> String where R: Into, @@ -397,26 +415,10 @@ mod tests { fn small() { assert_hex(ApInt::zero(BitWidth::w32()), "0"); assert_hex(ApInt::one(BitWidth::w32()), "1"); - assert_hex( - ApInt::from(0xFEDC_BA98_u32), - "FEDC\ - BA98", - ); - assert_hex( - ApInt::all_set(BitWidth::w32()), - "FFFF\ - FFFF", - ); - assert_hex( - ApInt::signed_min_value(BitWidth::w32()), - "8000\ - 0000", - ); - assert_hex( - ApInt::signed_max_value(BitWidth::w32()), - "7FFF\ - FFFF", - ); + assert_hex(ApInt::from(0xFEDC_BA98_u32), "FEDCBA98"); + assert_hex(ApInt::all_set(BitWidth::w32()), "FFFFFFFF"); + assert_hex(ApInt::signed_min_value(BitWidth::w32()), "80000000"); + assert_hex(ApInt::signed_max_value(BitWidth::w32()), "7FFFFFFF"); } #[test] @@ -425,33 +427,19 @@ mod tests { assert_hex(ApInt::one(BitWidth::w128()), "1"); assert_hex( ApInt::from(0xFEDC_BA98_0A1B_7654_ABCD_0123_u128), - "FEDC\ - BA98\ - 0A1B\ - 7654\ - ABCD\ - 0123", + "FEDCBA980A1B7654ABCD0123", ); assert_hex( ApInt::all_set(BitWidth::w128()), - "FFFFFFFF\ - FFFFFFFF\ - FFFFFFFF\ - FFFFFFFF", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", ); assert_hex( ApInt::signed_min_value(BitWidth::w128()), - "80000000\ - 00000000\ - 00000000\ - 00000000", + "80000000000000000000000000000000", ); assert_hex( ApInt::signed_max_value(BitWidth::w128()), - "7FFFFFFF\ - FFFFFFFF\ - FFFFFFFF\ - FFFFFFFF", + "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", ); } } @@ -483,9 +471,11 @@ mod tests { for &input in &["_0", "_123", "__", "_1_0"] { assert_eq!( ApInt::from_str_radix(radix, input), - Err(Error::invalid_string_repr(input, radix) - .with_annotation("The input string starts with an underscore ('_') instead of a number. \ - The use of underscores is explicitely for separation of digits.")) + Err(Error::invalid_string_repr(input, radix).with_annotation( + "The input string starts with an underscore ('_') instead \ + of a number. The use of underscores is explicitely for \ + separation of digits." + )) ) } } @@ -497,9 +487,11 @@ mod tests { for &input in &["0_", "123_", "1_0_"] { assert_eq!( ApInt::from_str_radix(radix, input), - Err(Error::invalid_string_repr(input, radix) - .with_annotation("The input string ends with an underscore ('_') instead of a number. \ - The use of underscores is explicitely for separation of digits.")) + Err(Error::invalid_string_repr(input, radix).with_annotation( + "The input string ends with an underscore ('_') instead of \ + a number. The use of underscores is explicitely for \ + separation of digits." + )) ) } } @@ -554,12 +546,14 @@ mod tests { (8, "777_747_666", 0o777_747_666), (8, "111", 0b001_001_001), (8, "7_7777_7777_7777_7777_7777", u64::max_value() / 2), - // ( 8, "17_7777_7777_7777_7777_7777", u64::max_value()), // Does not work, yet! Should it work? + // ( 8, "17_7777_7777_7777_7777_7777", u64::max_value()), // Does not + // work, yet! Should it work? (10, "100", 100), (10, "42", 42), (10, "1337", 1337), (10, "5_000_000", 5_000_000), - // (10, "18_446_744_073_709_551_615", u64::max_value()), // Does not work, yet! + // (10, "18_446_744_073_709_551_615", u64::max_value()), // Does not + // work, yet! (16, "100", 0x100), (16, "42", 0x42), (16, "1337", 0x1337), diff --git a/src/apint/shift.rs b/src/apint/shift.rs index b46fccf..9fb6395 100644 --- a/src/apint/shift.rs +++ b/src/apint/shift.rs @@ -77,7 +77,8 @@ impl ApInt { /// /// # Errors /// - /// - If the given `shift_amount` is invalid for the bit width of this `ApInt`. + /// - If the given `shift_amount` is invalid for the bit width of this + /// `ApInt`. pub fn wrapping_shl_assign(&mut self, shift_amount: S) -> Result<()> where S: Into, @@ -121,13 +122,15 @@ impl ApInt { Ok(()) } - /// Shift this `ApInt` left by the given `shift_amount` bits and returns the result. + /// Shift this `ApInt` left by the given `shift_amount` bits and returns the + /// result. /// /// This operation is inplace and will **not** allocate memory. /// /// # Errors /// - /// - If the given `shift_amount` is invalid for the bit width of this `ApInt`. + /// - If the given `shift_amount` is invalid for the bit width of this + /// `ApInt`. pub fn into_wrapping_shl(self, shift_amount: S) -> Result where S: Into, @@ -141,7 +144,8 @@ impl ApInt { /// /// # Errors /// - /// - If the given `shift_amount` is invalid for the bit width of this `ApInt`. + /// - If the given `shift_amount` is invalid for the bit width of this + /// `ApInt`. pub fn wrapping_lshr_assign(&mut self, shift_amount: S) -> Result<()> where S: Into, @@ -184,7 +188,8 @@ impl ApInt { /// /// # Errors /// - /// - If the given `shift_amount` is invalid for the bit width of this `ApInt`. + /// - If the given `shift_amount` is invalid for the bit width of this + /// `ApInt`. pub fn into_wrapping_lshr(self, shift_amount: S) -> Result where S: Into, @@ -192,17 +197,20 @@ impl ApInt { try_forward_bin_mut_impl(self, shift_amount, ApInt::wrapping_lshr_assign) } - /// Arithmetically right-shifts this `ApInt` by the given `shift_amount` bits. + /// Arithmetically right-shifts this `ApInt` by the given `shift_amount` + /// bits. /// /// This operation is inplace and will **not** allocate memory. /// /// # Note /// - /// Arithmetic shifting copies the sign bit instead of filling up with zeros. + /// Arithmetic shifting copies the sign bit instead of filling up with + /// zeros. /// /// # Errors /// - /// - If the given `shift_amount` is invalid for the bit width of this `ApInt`. + /// - If the given `shift_amount` is invalid for the bit width of this + /// `ApInt`. pub fn wrapping_ashr_assign(&mut self, shift_amount: S) -> Result<()> where S: Into, @@ -260,18 +268,20 @@ impl ApInt { Ok(()) } - /// Arithmetically right-shifts this `ApInt` by the given `shift_amount` bits - /// and returns the result. + /// Arithmetically right-shifts this `ApInt` by the given `shift_amount` + /// bits and returns the result. /// /// This operation is inplace and will **not** allocate memory. /// /// # Note /// - /// Arithmetic shifting copies the sign bit instead of filling up with zeros. + /// Arithmetic shifting copies the sign bit instead of filling up with + /// zeros. /// /// # Errors /// - /// - If the given `shift_amount` is invalid for the bit width of this `ApInt`. + /// - If the given `shift_amount` is invalid for the bit width of this + /// `ApInt`. pub fn into_wrapping_ashr(self, shift_amount: S) -> Result where S: Into, diff --git a/src/apint/to_primitive.rs b/src/apint/to_primitive.rs index 0f5ed45..2aa7eca 100644 --- a/src/apint/to_primitive.rs +++ b/src/apint/to_primitive.rs @@ -135,15 +135,15 @@ impl ApInt { let target_width = prim_ty.associated_width(); if prim_ty.is_signed() && actual_width < target_width { lsd.sign_extend_from(actual_width).expect( - "We already asserted that `actual_width` < `target_width` \ - and since `target_width` is always less than or equal to \ - `64` bits calling `Digit::sign_extend_from` is safe for it.", + "We already asserted that `actual_width` < `target_width` and since \ + `target_width` is always less than or equal to `64` bits calling \ + `Digit::sign_extend_from` is safe for it.", ); } if target_width < BitWidth::w64() { lsd.truncate_to(target_width).expect( - "Since `target_width` is always less than or equal to \ - `64` bits calling `Digit::sign_extend_from` is safe for it.", + "Since `target_width` is always less than or equal to `64` bits calling \ + `Digit::sign_extend_from` is safe for it.", ); } lsd @@ -156,8 +156,8 @@ impl ApInt { /// /// # Note /// - /// - Basically this returns `true` if the least significant - /// bit of this `ApInt` is `1` and `false` otherwise. + /// - Basically this returns `true` if the least significant bit of this + /// `ApInt` is `1` and `false` otherwise. pub fn resize_to_bool(&self) -> bool { match self.resize_to_primitive_ty(PrimitiveTy::Bool) { Digit(0) => false, @@ -170,13 +170,11 @@ impl ApInt { /// /// # Note /// - /// - This operation will conserve the signedness of the - /// value. This means that for `ApInt` instances with - /// a `BitWidth` less than `8` bits the value is - /// sign extended to the target bit width. - /// - All bits but the least significant `8` bits are - /// being ignored by this operation to construct the - /// result. + /// - This operation will conserve the signedness of the value. This means + /// that for `ApInt` instances with a `BitWidth` less than `8` bits the + /// value is sign extended to the target bit width. + /// - All bits but the least significant `8` bits are being ignored by this + /// operation to construct the result. pub fn resize_to_i8(&self) -> i8 { self.resize_to_primitive_ty(PrimitiveTy::I8).repr() as i8 } @@ -185,9 +183,8 @@ impl ApInt { /// /// # Note /// - /// - All bits but the least significant `8` bits are - /// being ignored by this operation to construct the - /// result. + /// - All bits but the least significant `8` bits are being ignored by this + /// operation to construct the result. pub fn resize_to_u8(&self) -> u8 { self.resize_to_primitive_ty(PrimitiveTy::U8).repr() as u8 } @@ -196,13 +193,11 @@ impl ApInt { /// /// # Note /// - /// - This operation will conserve the signedness of the - /// value. This means that for `ApInt` instances with - /// a `BitWidth` less than `16` bits the value is - /// sign extended to the target bit width. - /// - All bits but the least significant `16` bits are - /// being ignored by this operation to construct the - /// result. + /// - This operation will conserve the signedness of the value. This means + /// that for `ApInt` instances with a `BitWidth` less than `16` bits the + /// value is sign extended to the target bit width. + /// - All bits but the least significant `16` bits are being ignored by this + /// operation to construct the result. pub fn resize_to_i16(&self) -> i16 { self.resize_to_primitive_ty(PrimitiveTy::I16).repr() as i16 } @@ -211,9 +206,8 @@ impl ApInt { /// /// # Note /// - /// - All bits but the least significant `16` bits are - /// being ignored by this operation to construct the - /// result. + /// - All bits but the least significant `16` bits are being ignored by this + /// operation to construct the result. pub fn resize_to_u16(&self) -> u16 { self.resize_to_primitive_ty(PrimitiveTy::U16).repr() as u16 } @@ -222,13 +216,11 @@ impl ApInt { /// /// # Note /// - /// - This operation will conserve the signedness of the - /// value. This means that for `ApInt` instances with - /// a `BitWidth` less than `32` bits the value is - /// sign extended to the target bit width. - /// - All bits but the least significant `32` bits are - /// being ignored by this operation to construct the - /// result. + /// - This operation will conserve the signedness of the value. This means + /// that for `ApInt` instances with a `BitWidth` less than `32` bits the + /// value is sign extended to the target bit width. + /// - All bits but the least significant `32` bits are being ignored by this + /// operation to construct the result. pub fn resize_to_i32(&self) -> i32 { self.resize_to_primitive_ty(PrimitiveTy::I32).repr() as i32 } @@ -237,9 +229,8 @@ impl ApInt { /// /// # Note /// - /// - All bits but the least significant `32` bits are - /// being ignored by this operation to construct the - /// result. + /// - All bits but the least significant `32` bits are being ignored by this + /// operation to construct the result. pub fn resize_to_u32(&self) -> u32 { self.resize_to_primitive_ty(PrimitiveTy::U32).repr() as u32 } @@ -248,13 +239,11 @@ impl ApInt { /// /// # Note /// - /// - This operation will conserve the signedness of the - /// value. This means that for `ApInt` instances with - /// a `BitWidth` less than `64` bits the value is - /// sign extended to the target bit width. - /// - All bits but the least significant `64` bits are - /// being ignored by this operation to construct the - /// result. + /// - This operation will conserve the signedness of the value. This means + /// that for `ApInt` instances with a `BitWidth` less than `64` bits the + /// value is sign extended to the target bit width. + /// - All bits but the least significant `64` bits are being ignored by this + /// operation to construct the result. pub fn resize_to_i64(&self) -> i64 { self.resize_to_primitive_ty(PrimitiveTy::I64).repr() as i64 } @@ -263,9 +252,8 @@ impl ApInt { /// /// # Note /// - /// - All bits but the least significant `64` bits are - /// being ignored by this operation to construct the - /// result. + /// - All bits but the least significant `64` bits are being ignored by this + /// operation to construct the result. pub fn resize_to_u64(&self) -> u64 { self.resize_to_primitive_ty(PrimitiveTy::U64).repr() as u64 } @@ -274,13 +262,11 @@ impl ApInt { /// /// # Note /// - /// - This operation will conserve the signedness of the - /// value. This means that for `ApInt` instances with - /// a `BitWidth` less than `128` bits the value is - /// sign extended to the target bit width. - /// - All bits but the least significant `128` bits are - /// being ignored by this operation to construct the - /// result. + /// - This operation will conserve the signedness of the value. This means + /// that for `ApInt` instances with a `BitWidth` less than `128` bits the + /// value is sign extended to the target bit width. + /// - All bits but the least significant `128` bits are being ignored by + /// this operation to construct the result. pub fn resize_to_i128(&self) -> i128 { let (lsd_0, rest) = self.split_least_significant_digit(); let (&lsd_1, _) = rest.split_first().unwrap_or((&Digit(0), &[])); @@ -292,9 +278,13 @@ impl ApInt { if actual_width < target_width { // Sign extend the `i128`. Fill up with `1` up to `128` bits // starting from the sign bit position. - let b = actual_width.to_usize(); // Number of bits representing the number in x. - let m: i128 = 1 << (b - 1); // Mask can be pre-computed if b is fixed. - result = (result ^ m) - m; // Resulting sign-extended number. + + // Number of bits representing the number in x. + let b = actual_width.to_usize(); + // Mask can be pre-computed if b is fixed. + let m: i128 = 1 << (b - 1); + // Resulting sign-extended number. + result = (result ^ m) - m; } result @@ -304,9 +294,8 @@ impl ApInt { /// /// # Note /// - /// - All bits but the least significant `128` bits are - /// being ignored by this operation to construct the - /// result. + /// - All bits but the least significant `128` bits are being ignored by + /// this operation to construct the result. pub fn resize_to_u128(&self) -> u128 { let (lsd_0, rest) = self.split_least_significant_digit(); let (&lsd_1, _) = rest.split_first().unwrap_or((&Digit(0), &[])); @@ -327,7 +316,8 @@ impl ApInt { /// If the given `PrimitiveTy` represents a signed integer type the /// returned `Digit` is also sign extended accordingly. /// This sign extension behaves equal to how in Rust a negative signed - /// `i32` is extended to an `i64` and correctly preserves the negative value. + /// `i32` is extended to an `i64` and correctly preserves the negative + /// value. /// /// # Errors /// @@ -344,14 +334,14 @@ impl ApInt { let target_width = prim_ty.associated_width(); if actual_width < target_width { lsd.sign_extend_from(actual_width).expect( - "We already asserted that `actual_width` < `target_width` \ - and since `target_width` is always less than or equal to \ - `64` bits calling `Digit::sign_extend_from` is safe for it.", + "We already asserted that `actual_width` < `target_width` and since \ + `target_width` is always less than or equal to `64` bits calling \ + `Digit::sign_extend_from` is safe for it.", ); if target_width < BitWidth::w64() { lsd.truncate_to(target_width).expect( - "Since `target_width` is always less than or equal to \ - `64` bits calling `Digit::sign_extend_from` is safe for it.", + "Since `target_width` is always less than or equal to `64` bits \ + calling `Digit::sign_extend_from` is safe for it.", ); } } @@ -369,8 +359,8 @@ impl ApInt { /// /// # Errors /// - /// - If the value represented by this `ApInt` can not be - /// represented by a `bool`. + /// - If the value represented by this `ApInt` can not be represented by a + /// `bool`. pub fn try_to_bool(&self) -> Result { match self.try_cast_to_primitive_ty(PrimitiveTy::Bool)? { Digit(0) => Ok(false), @@ -383,17 +373,16 @@ impl ApInt { /// /// # Note /// - /// - This operation will conserve the signedness of the - /// value. This means that for `ApInt` instances with - /// a `BitWidth` less than `8` bits the value is - /// sign extended to the target bit width. - /// - This conversion is possible as long as the value represented - /// by this `ApInt` does not exceed the maximum value of `u8`. + /// - This operation will conserve the signedness of the value. This means + /// that for `ApInt` instances with a `BitWidth` less than `8` bits the + /// value is sign extended to the target bit width. + /// - This conversion is possible as long as the value represented by this + /// `ApInt` does not exceed the maximum value of `u8`. /// /// # Errors /// - /// - If the value represented by this `ApInt` can not be - /// represented by a `i8`. + /// - If the value represented by this `ApInt` can not be represented by a + /// `i8`. pub fn try_to_i8(&self) -> Result { self.try_cast_to_primitive_ty(PrimitiveTy::I8) .map(|d| d.repr() as i8) @@ -403,13 +392,13 @@ impl ApInt { /// /// # Note /// - /// - This conversion is possible as long as the value represented - /// by this `ApInt` does not exceed the maximum value of `u8`. + /// - This conversion is possible as long as the value represented by this + /// `ApInt` does not exceed the maximum value of `u8`. /// /// # Errors /// - /// - If the value represented by this `ApInt` can not be - /// represented by a `u8`. + /// - If the value represented by this `ApInt` can not be represented by a + /// `u8`. pub fn try_to_u8(&self) -> Result { self.try_cast_to_primitive_ty(PrimitiveTy::U8) .map(|d| d.repr() as u8) @@ -419,17 +408,16 @@ impl ApInt { /// /// # Note /// - /// - This operation will conserve the signedness of the - /// value. This means that for `ApInt` instances with - /// a `BitWidth` less than `16` bits the value is - /// sign extended to the target bit width. - /// - This conversion is possible as long as the value represented - /// by this `ApInt` does not exceed the maximum value of `u16`. + /// - This operation will conserve the signedness of the value. This means + /// that for `ApInt` instances with a `BitWidth` less than `16` bits the + /// value is sign extended to the target bit width. + /// - This conversion is possible as long as the value represented by this + /// `ApInt` does not exceed the maximum value of `u16`. /// /// # Errors /// - /// - If the value represented by this `ApInt` can not be - /// represented by a `i16`. + /// - If the value represented by this `ApInt` can not be represented by a + /// `i16`. pub fn try_to_i16(&self) -> Result { self.try_cast_to_primitive_ty(PrimitiveTy::I16) .map(|d| d.repr() as i16) @@ -439,13 +427,13 @@ impl ApInt { /// /// # Note /// - /// - This conversion is possible as long as the value represented - /// by this `ApInt` does not exceed the maximum value of `u16`. + /// - This conversion is possible as long as the value represented by this + /// `ApInt` does not exceed the maximum value of `u16`. /// /// # Errors /// - /// - If the value represented by this `ApInt` can not be - /// represented by a `u16`. + /// - If the value represented by this `ApInt` can not be represented by a + /// `u16`. pub fn try_to_u16(&self) -> Result { self.try_cast_to_primitive_ty(PrimitiveTy::U16) .map(|d| d.repr() as u16) @@ -455,17 +443,16 @@ impl ApInt { /// /// # Note /// - /// - This operation will conserve the signedness of the - /// value. This means that for `ApInt` instances with - /// a `BitWidth` less than `32` bits the value is - /// sign extended to the target bit width. - /// - This conversion is possible as long as the value represented - /// by this `ApInt` does not exceed the maximum value of `u32`. + /// - This operation will conserve the signedness of the value. This means + /// that for `ApInt` instances with a `BitWidth` less than `32` bits the + /// value is sign extended to the target bit width. + /// - This conversion is possible as long as the value represented by this + /// `ApInt` does not exceed the maximum value of `u32`. /// /// # Errors /// - /// - If the value represented by this `ApInt` can not be - /// represented by a `i32`. + /// - If the value represented by this `ApInt` can not be represented by a + /// `i32`. pub fn try_to_i32(&self) -> Result { self.try_cast_to_primitive_ty(PrimitiveTy::I32) .map(|d| d.repr() as i32) @@ -475,13 +462,13 @@ impl ApInt { /// /// # Note /// - /// - This conversion is possible as long as the value represented - /// by this `ApInt` does not exceed the maximum value of `u32`. + /// - This conversion is possible as long as the value represented by this + /// `ApInt` does not exceed the maximum value of `u32`. /// /// # Errors /// - /// - If the value represented by this `ApInt` can not be - /// represented by a `u32`. + /// - If the value represented by this `ApInt` can not be represented by a + /// `u32`. pub fn try_to_u32(&self) -> Result { self.try_cast_to_primitive_ty(PrimitiveTy::U32) .map(|d| d.repr() as u32) @@ -491,17 +478,16 @@ impl ApInt { /// /// # Note /// - /// - This operation will conserve the signedness of the - /// value. This means that for `ApInt` instances with - /// a `BitWidth` less than `64` bits the value is - /// sign extended to the target bit width. - /// - This conversion is possible as long as the value represented - /// by this `ApInt` does not exceed the maximum value of `u64`. + /// - This operation will conserve the signedness of the value. This means + /// that for `ApInt` instances with a `BitWidth` less than `64` bits the + /// value is sign extended to the target bit width. + /// - This conversion is possible as long as the value represented by this + /// `ApInt` does not exceed the maximum value of `u64`. /// /// # Errors /// - /// - If the value represented by this `ApInt` can not be - /// represented by a `i64`. + /// - If the value represented by this `ApInt` can not be represented by a + /// `i64`. pub fn try_to_i64(&self) -> Result { self.try_cast_to_primitive_ty(PrimitiveTy::I64) .map(|d| d.repr() as i64) @@ -511,13 +497,13 @@ impl ApInt { /// /// # Note /// - /// - This conversion is possible as long as the value represented - /// by this `ApInt` does not exceed the maximum value of `u64`. + /// - This conversion is possible as long as the value represented by this + /// `ApInt` does not exceed the maximum value of `u64`. /// /// # Errors /// - /// - If the value represented by this `ApInt` can not be - /// represented by a `u64`. + /// - If the value represented by this `ApInt` can not be represented by a + /// `u64`. pub fn try_to_u64(&self) -> Result { self.try_cast_to_primitive_ty(PrimitiveTy::U64) .map(|d| d.repr() as u64) @@ -527,17 +513,16 @@ impl ApInt { /// /// # Note /// - /// - This operation will conserve the signedness of the - /// value. This means that for `ApInt` instances with - /// a `BitWidth` less than `128` bits the value is - /// sign extended to the target bit width. - /// - This conversion is possible as long as the value represented - /// by this `ApInt` does not exceed the maximum value of `u128`. + /// - This operation will conserve the signedness of the value. This means + /// that for `ApInt` instances with a `BitWidth` less than `128` bits the + /// value is sign extended to the target bit width. + /// - This conversion is possible as long as the value represented by this + /// `ApInt` does not exceed the maximum value of `u128`. /// /// # Errors /// - /// - If the value represented by this `ApInt` can not be - /// represented by a `i128`. + /// - If the value represented by this `ApInt` can not be represented by a + /// `i128`. pub fn try_to_i128(&self) -> Result { let (lsd_0, rest) = self.split_least_significant_digit(); let (&lsd_1, rest) = rest.split_first().unwrap_or((&Digit(0), &[])); @@ -556,9 +541,13 @@ impl ApInt { if actual_width < target_width { // Sign extend the `i128`. Fill up with `1` up to `128` bits // starting from the sign bit position. - let b = actual_width.to_usize(); // Number of bits representing the number in x. - let m: i128 = 1 << (b - 1); // Mask can be pre-computed if b is fixed. - result = (result ^ m).wrapping_sub(m); // Resulting sign-extended number. + + // Number of bits representing the number in x. + let b = actual_width.to_usize(); + // Mask can be pre-computed if b is fixed. + let m: i128 = 1 << (b - 1); + // Resulting sign-extended number. + result = (result ^ m).wrapping_sub(m); } Ok(result) @@ -568,8 +557,8 @@ impl ApInt { /// /// # Note /// - /// - This conversion is possible as long as the value represented - /// by this `ApInt` does not exceed the maximum value of `u128`. + /// - This conversion is possible as long as the value represented by this + /// `ApInt` does not exceed the maximum value of `u128`. /// /// # Complexity /// @@ -577,8 +566,8 @@ impl ApInt { /// /// # Errors /// - /// - If the value represented by this `ApInt` can not be - /// represented by a `u128`. + /// - If the value represented by this `ApInt` can not be represented by a + /// `u128`. pub fn try_to_u128(&self) -> Result { let (lsd_0, rest) = self.split_least_significant_digit(); let (&lsd_1, rest) = rest.split_first().unwrap_or((&Digit(0), &[])); @@ -664,7 +653,8 @@ mod tests { vec![Bool, I8, U8, I16, U16, I32, U32, I64, U64, I128, U128].into_iter() } - /// Uses `test_values` to iterate over already constructed `ApInt` instances. + /// Uses `test_values` to iterate over already constructed `ApInt` + /// instances. fn test_vals_and_apints() -> impl Iterator { test_values() .cartesian_product(test_primitive_tys()) @@ -906,9 +896,11 @@ mod tests { assert!(ApInt::from(-1_i16).try_to_bool().is_err()); assert!(ApInt::from(42_u32).try_to_bool().is_err()); assert!(ApInt::from(1337_u64).try_to_bool().is_err()); - assert!(ApInt::from(0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_u128) - .try_to_bool() - .is_err()); + assert!( + ApInt::from(0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_u128) + .try_to_bool() + .is_err() + ); } #[test] @@ -1000,9 +992,13 @@ mod tests { if actual_width < target_width { // Sign extend the `i128`. Fill up with `1` up to `128` bits // starting from the sign bit position. - let b = actual_width.to_usize(); // Number of bits representing the number in x. - let m: i128 = 1 << (b - 1); // Mask can be pre-computed if b is fixed. - result = (result ^ m).wrapping_sub(m); // Resulting sign-extended number. + + // Number of bits representing the number in x. + let b = actual_width.to_usize(); + // Mask can be pre-computed if b is fixed. + let m: i128 = 1 << (b - 1); + // Resulting sign-extended number. + result = (result ^ m).wrapping_sub(m); } assert_eq!(apint.try_to_i128(), Ok(result)) } else { diff --git a/src/apint/utils.rs b/src/apint/utils.rs index c68c238..ccd6cea 100644 --- a/src/apint/utils.rs +++ b/src/apint/utils.rs @@ -128,7 +128,8 @@ impl ApInt { } } - /// Mutably accesses the internal `Digit` data of this `ApInt` in a safe way. + /// Mutably accesses the internal `Digit` data of this `ApInt` in a safe + /// way. #[inline] pub(in crate::apint) fn access_data_mut(&mut self) -> DataAccessMut { match self.storage() { @@ -137,7 +138,8 @@ impl ApInt { } } - /// Zips both given `ApInt` instances and tries to access their data in a safe way. + /// Zips both given `ApInt` instances and tries to access their data in a + /// safe way. /// /// # Errors /// @@ -160,8 +162,8 @@ impl ApInt { }) } - /// Zips both given `ApInt` instances and tries to mutably access `self` data and immutably - /// access `other` data in a safe way. + /// Zips both given `ApInt` instances and tries to mutably access `self` + /// data and immutably access `other` data in a safe way. /// /// # Errors /// @@ -189,8 +191,8 @@ impl ApInt { }) } - /// Zips both given `ApInt` instances and tries to mutably access `lhs` and `rhs` data - /// in a safe way. + /// Zips both given `ApInt` instances and tries to mutably access `lhs` and + /// `rhs` data in a safe way. /// /// # Errors /// @@ -269,7 +271,8 @@ impl ApInt { Ok(()) } - /// Returns a slice over the `Digit`s of this `ApInt` in little-endian order. + /// Returns a slice over the `Digit`s of this `ApInt` in little-endian + /// order. #[inline] pub(in crate::apint) fn as_digit_slice(&self) -> &[Digit] { use core::slice; @@ -281,7 +284,8 @@ impl ApInt { } } - /// Returns a mutable slice over the `Digit`s of this `ApInt` in little-endian order. + /// Returns a mutable slice over the `Digit`s of this `ApInt` in + /// little-endian order. #[inline] pub(in crate::apint) fn as_digit_slice_mut(&mut self) -> &mut [Digit] { use core::slice; @@ -302,7 +306,8 @@ impl ApInt { } } - /// Returns a mutable reference to the most significant `Digit` of this `ApInt`. + /// Returns a mutable reference to the most significant `Digit` of this + /// `ApInt`. #[inline] pub(in crate::apint) fn most_significant_digit_mut(&mut self) -> &mut Digit { match self.access_data_mut() { @@ -328,9 +333,8 @@ impl ApInt { self.most_significant_digit() .get(sign_bit_pos.to_pos_within_digit()) .expect( - "`BitWidth::excess_bits` returns a number that \ - is always a valid `BitPos` for a `Digit` so this \ - operation cannot fail.", + "`BitWidth::excess_bits` returns a number that is always a valid \ + `BitPos` for a `Digit` so this operation cannot fail.", ) } @@ -357,8 +361,8 @@ impl ApInt { self.most_significant_digit_mut() .retain_last_n(bits) .expect( - "`BitWidth::excess_bits` always returns a number of \ - bits that can safely forwarded to `Digit::retain_last_n`.", + "`BitWidth::excess_bits` always returns a number of bits that can \ + safely forwarded to `Digit::retain_last_n`.", ); } } @@ -368,8 +372,8 @@ impl ApInt { /// # Note /// /// - Zero (`0`) is also called the additive neutral element. - /// - This operation is more efficient than comparing two instances - /// of `ApInt` for the same reason. + /// - This operation is more efficient than comparing two instances of + /// `ApInt` for the same reason. #[inline] pub fn is_zero(&self) -> bool { match self.access_data() { @@ -383,8 +387,8 @@ impl ApInt { /// # Note /// /// - One (`1`) is also called the multiplicative neutral element. - /// - This operation is more efficient than comparing two instances - /// of `ApInt` for the same reason. + /// - This operation is more efficient than comparing two instances of + /// `ApInt` for the same reason. #[inline] pub fn is_one(&self) -> bool { match self.access_data() { @@ -410,15 +414,15 @@ impl ApInt { self.least_significant_bit() == Bit::Set } - /// Returns `true` if the **signed** representation of this `ApInt` is positive. - /// Equivalent to testing if the most significant bit is zero. + /// Returns `true` if the **signed** representation of this `ApInt` is + /// positive. Equivalent to testing if the most significant bit is zero. #[inline] pub fn is_positive(&self) -> bool { self.most_significant_bit() == Bit::Unset } - /// Returns `true` if the **signed** representation of this `ApInt` is negative. - /// Equivalent to testing if the most significant bit is one. + /// Returns `true` if the **signed** representation of this `ApInt` is + /// negative. Equivalent to testing if the most significant bit is one. #[inline] pub fn is_negative(&self) -> bool { self.most_significant_bit() == Bit::Set @@ -432,9 +436,8 @@ impl ApInt { DataAccess::Inl(digit) => (digit, &[]), DataAccess::Ext(digits) => { let (lsd, rest) = digits.split_first().expect( - "An `ApInt` always has at least one digit so calling \ - `split_first` on a slice of its digits will never \ - return `None`.", + "An `ApInt` always has at least one digit so calling `split_first` \ + on a slice of its digits will never return `None`.", ); (*lsd, rest) } @@ -449,9 +452,8 @@ impl ApInt { DataAccess::Inl(digit) => (digit, &[]), DataAccess::Ext(digits) => { let (lsd, rest) = digits.split_last().expect( - "An `ApInt` always has at least one digit so calling \ - `split_last` on a slice of its digits will never \ - return `None`.", + "An `ApInt` always has at least one digit so calling `split_last` \ + on a slice of its digits will never return `None`.", ); (*lsd, rest) } diff --git a/src/bitpos.rs b/src/bitpos.rs index 01d4292..0690adf 100644 --- a/src/bitpos.rs +++ b/src/bitpos.rs @@ -26,21 +26,23 @@ impl BitPos { /// /// # Errors /// - /// - This operation cannot fail but may do so in future version of this library. + /// - This operation cannot fail but may do so in future version of this + /// library. #[inline] pub fn new(pos: usize) -> Result { Ok(BitPos(pos)) } - /// Converts this `BitPos` into its associated `BitPos` that is usable to operate - /// on `Digit` instances. + /// Converts this `BitPos` into its associated `BitPos` that is usable to + /// operate on `Digit` instances. #[inline] pub(crate) fn to_pos_within_digit(self) -> BitPos { BitPos(self.0 % digit::BITS) } - /// Splits this `BitPos` that may range over several `Digit`s within an `ApInt` - /// into the associated `Digit` offset and its `Digit`-relative bit position. + /// Splits this `BitPos` that may range over several `Digit`s within an + /// `ApInt` into the associated `Digit` offset and its `Digit`-relative + /// bit position. #[inline] pub(crate) fn to_digit_and_bit_pos(self) -> (DigitPos, BitPos) { let digit_pos = self.0 / digit::BITS; diff --git a/src/bitwidth.rs b/src/bitwidth.rs index a05da83..fea7e50 100644 --- a/src/bitwidth.rs +++ b/src/bitwidth.rs @@ -86,7 +86,8 @@ impl BitWidth { shift_amount.into().to_usize() < self.0 } - /// Returns the `BitPos` for the sign bit of an `ApInt` with this `BitWidth`. + /// Returns the `BitPos` for the sign bit of an `ApInt` with this + /// `BitWidth`. #[inline] pub(crate) fn sign_bit_pos(self) -> BitPos { BitPos::from(self.to_usize() - 1) @@ -136,8 +137,8 @@ impl BitWidth { } /// Returns a storage specifier that tells the caller if `ApInt`'s - /// associated with this bitwidth require an external memory (`Ext`) to store - /// their digits or may use inplace memory (`Inl`). + /// associated with this bitwidth require an external memory (`Ext`) to + /// store their digits or may use inplace memory (`Inl`). /// /// *Note:* Maybe this method should be removed. A constructor for /// `Storage` fits better for this purpose. diff --git a/src/digit.rs b/src/digit.rs index 8946a87..b0f6c2c 100644 --- a/src/digit.rs +++ b/src/digit.rs @@ -73,11 +73,7 @@ impl Bit { impl From for Bit { #[inline] fn from(flag: bool) -> Bit { - if flag { - Bit::Set - } else { - Bit::Unset - } + if flag { Bit::Set } else { Bit::Unset } } } @@ -122,10 +118,12 @@ impl fmt::UpperHex for Digit { /// A doubled digit. /// -/// This is used as a compute unit for `Digit`'s since many `Digit` arithmetic operations -/// may overflow or have carries this is required in order to not lose those overflow- and underflow values. +/// This is used as a compute unit for `Digit`'s since many `Digit` arithmetic +/// operations may overflow or have carries this is required in order to not +/// lose those overflow- and underflow values. /// -/// Has wrapping arithmetics for better machine emulation and improved performance. +/// Has wrapping arithmetics for better machine emulation and improved +/// performance. #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub(crate) struct DoubleDigit(pub DoubleDigitRepr); @@ -363,7 +361,8 @@ impl Digit { Digit(self.repr().wrapping_mul(other.repr())) } - // TODO if and when `carrying_mul` (rust-lang rfc #2417) is stabilized, this function and others in this crate should use `carrying_mul` as the operation + // TODO if and when `carrying_mul` (rust-lang rfc #2417) is stabilized, this + // function and others in this crate should use `carrying_mul` as the operation pub(crate) fn carrying_mul(self, other: Digit) -> (Digit, Digit) { let temp = self.dd().wrapping_mul(other.dd()); (temp.lo(), temp.hi()) @@ -440,8 +439,9 @@ impl Digit { /// - This can be truncated again to a real target `BitWidth` afterwards if /// the users wishes to. /// - /// - Implementation inspired by - /// [Bit Twiddling Hacks](https://graphics.stanford.edu/~seander/bithacks.html#VariableSignExtend). + /// - Implementation inspired by [Bit Twiddling + /// Hacks](https://graphics.stanford.edu/~seander/bithacks.html# + /// VariableSignExtend). /// /// # Errors /// @@ -456,8 +456,9 @@ impl Digit { let b = from.to_usize(); // number of bits representing the number in x let x = self.repr() as i64; // sign extend this b-bit number to r let m: i64 = 1 << (b - 1); // mask can be pre-computed if b is fixed - // x = x & ((1 << b) - 1); // (Skip this if bits in x above position b are already zero.) - // We don't need this step since this condition is an invariant of `Digit`. + // x = x & ((1 << b) - 1); // (Skip this if bits in x above position b are + // already zero.) We don't need this step since this condition is an + // invariant of `Digit`. let r: i64 = (x ^ m).wrapping_sub(m); // resulting sign-extended number self.0 = r as u64; Ok(()) diff --git a/src/digit_seq.rs b/src/digit_seq.rs index 2e3060d..11b5047 100644 --- a/src/digit_seq.rs +++ b/src/digit_seq.rs @@ -30,7 +30,8 @@ impl<'a> Iterator for ContiguousDigitSeq<'a> { /// A sequence of mutable digits. /// -/// This is a very efficient `DigitSeqMut` since its data is contiguous in memory. +/// This is a very efficient `DigitSeqMut` since its data is contiguous in +/// memory. #[derive(Debug)] pub(crate) struct ContiguousDigitSeqMut<'a> { digits: slice::IterMut<'a, Digit>, diff --git a/src/errors.rs b/src/errors.rs index 57757fa..101b17f 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -26,16 +26,20 @@ use std::error; /// This also stores the unique information tied to the error report. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum ErrorKind { - /// Returned on trying to create a `Radix` from an invalid `u8` representation. + /// Returned on trying to create a `Radix` from an invalid `u8` + /// representation. InvalidRadix(u8), - /// Returned whenever trying to parse an invalid string representation for an `ApInt`. + /// Returned whenever trying to parse an invalid string representation for + /// an `ApInt`. InvalidStringRepr { - /// The string storing the invalid representation of the int for the given radix. + /// The string storing the invalid representation of the int for the + /// given radix. input: String, /// The radix that was used. radix: Radix, - /// An optional index and character when encountering an invalid character. + /// An optional index and character when encountering an invalid + /// character. pos_char: Option<(usize, char)>, }, @@ -58,19 +62,23 @@ pub enum ErrorKind { /// Returns on trying to cast an `ApInt` to a primitive type /// that can not represent the value represented by the `ApInt`. ValueUnrepresentable { - /// The `ApInt` that the user wanted to represent as the given `PrimitiveTy`. + /// The `ApInt` that the user wanted to represent as the given + /// `PrimitiveTy`. value: ApInt, - /// The `PrimitiveTy` that the user wanted for representing the given `ApInt`. + /// The `PrimitiveTy` that the user wanted for representing the given + /// `ApInt`. destination_ty: PrimitiveTy, }, /// Returned on violation of matching bitwidth constraints of operations. UnmatchingBitwidth(BitWidth, BitWidth), - /// Returned on trying to create a `BitWidth` from an invalid `usize` representation. + /// Returned on trying to create a `BitWidth` from an invalid `usize` + /// representation. InvalidBitWidth(usize), - /// Returned on truncating an `ApInt` with a bitwidth greater than the current one. + /// Returned on truncating an `ApInt` with a bitwidth greater than the + /// current one. TruncationBitWidthTooLarge { /// The target bit width. target: BitWidth, @@ -78,7 +86,8 @@ pub enum ErrorKind { current: BitWidth, }, - /// Returned on extending an `ApInt` with a bitwidth less than the current one. + /// Returned on extending an `ApInt` with a bitwidth less than the current + /// one. ExtensionBitWidthTooSmall { /// The target bit width. target: BitWidth, @@ -121,8 +130,9 @@ pub enum DivOp { /// Represents an error that may occure upon using the `ApInt` library. /// -/// All errors have a unique kind which also stores extra information for error reporting. -/// Besides that an `Error` also stores a message and an optional additional annotation. +/// All errors have a unique kind which also stores extra information for error +/// reporting. Besides that an `Error` also stores a message and an optional +/// additional annotation. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Error { kind: ErrorKind, @@ -187,10 +197,18 @@ impl Error { S: Into, { let input = input.into(); - Error{ - kind: ErrorKind::InvalidStringRepr{input, radix, pos_char: None}, - message: format!("Encountered an invalid string representation for the given radix (= {:?}).", radix), - annotation: None + Error { + kind: ErrorKind::InvalidStringRepr { + input, + radix, + pos_char: None, + }, + message: format!( + "Encountered an invalid string representation for the given radix (= \ + {:?}).", + radix + ), + annotation: None, } } @@ -204,11 +222,18 @@ impl Error { S: Into, { let input = input.into(); - Error{ - kind: ErrorKind::InvalidStringRepr{input, radix, pos_char: None}, - message: format!("Encountered an invalid character (= '{:?}') at position {:?} within the given string \ - representation for the given radix (= {:?}).", ch, pos, radix), - annotation: None + Error { + kind: ErrorKind::InvalidStringRepr { + input, + radix, + pos_char: None, + }, + message: format!( + "Encountered an invalid character (= '{:?}') at position {:?} within \ + the given string representation for the given radix (= {:?}).", + ch, pos, radix + ), + annotation: None, } } @@ -231,10 +256,14 @@ impl Error { { let target = target.into(); let current = current.into(); - Error{ - kind: ErrorKind::ExtensionBitWidthTooSmall{target, current}, - message: format!("Tried to extend an `ApInt` with a width of {:?} to a smaller target width of {:?}", current, target), - annotation: None + Error { + kind: ErrorKind::ExtensionBitWidthTooSmall { target, current }, + message: format!( + "Tried to extend an `ApInt` with a width of {:?} to a smaller target \ + width of {:?}", + current, target + ), + annotation: None, } } @@ -245,10 +274,14 @@ impl Error { { let target = target.into(); let current = current.into(); - Error{ - kind: ErrorKind::TruncationBitWidthTooLarge{target, current}, - message: format!("Tried to truncate an `ApInt` with a width of {:?} to a larger target width of {:?}", current, target), - annotation: None + Error { + kind: ErrorKind::TruncationBitWidthTooLarge { target, current }, + message: format!( + "Tried to truncate an `ApInt` with a width of {:?} to a larger target \ + width of {:?}", + current, target + ), + annotation: None, } } @@ -259,10 +292,14 @@ impl Error { { let lhs = lhs.into(); let rhs = rhs.into(); - Error{ + Error { kind: ErrorKind::UnmatchingBitwidth(lhs, rhs), - message: format!("Encountered invalid operation on entities with non-matching bit-widths of {:?} and {:?}.", lhs, rhs), - annotation: None + message: format!( + "Encountered invalid operation on entities with non-matching bit-widths \ + of {:?} and {:?}.", + lhs, rhs + ), + annotation: None, } } @@ -293,18 +330,24 @@ impl Error { { let pos = pos.into(); let width = width.into(); - Error{ - kind: ErrorKind::InvalidBitAccess{pos, width}, - message: format!("Encountered invalid bit access at position {:?} with a total bit-width of {:?}.", pos, width), - annotation: None + Error { + kind: ErrorKind::InvalidBitAccess { pos, width }, + message: format!( + "Encountered invalid bit access at position {:?} with a total bit-width \ + of {:?}.", + pos, width + ), + annotation: None, } } pub(crate) fn expected_non_empty_digits() -> Error { - Error{ + Error { kind: ErrorKind::ExpectedNonEmptyDigits, - message: "Encountered an empty iterator upon construction of an `ApInt` from a digit iterator.".to_owned(), - annotation: None + message: "Encountered an empty iterator upon construction of an `ApInt` \ + from a digit iterator." + .to_owned(), + annotation: None, } } @@ -313,8 +356,8 @@ impl Error { destination_ty: PrimitiveTy, ) -> Error { let message = format!( - "Encountered a value ({:?}) that is unrepresentable \ - by the destination type {:?}.", + "Encountered a value ({:?}) that is unrepresentable by the destination type \ + {:?}.", value, destination_ty ); Error { @@ -329,7 +372,8 @@ impl Error { pub(crate) fn division_by_zero(op: DivOp, lhs: ApInt) -> Error { let message = format!( - "Encountered a division-by-zero for operation (= {:?}) with the left hand-side value: (= {:?})", + "Encountered a division-by-zero for operation (= {:?}) with the left \ + hand-side value: (= {:?})", op, lhs ); Error { diff --git a/src/int.rs b/src/int.rs index 0797a6c..dc4f4d3 100644 --- a/src/int.rs +++ b/src/int.rs @@ -49,10 +49,12 @@ use core::{ /// Signed machine integer with arbitrary bitwidths and modulo arithmetics. /// -/// Thin convenience wrapper around `ApInt` for static signed interpretation of the value. +/// Thin convenience wrapper around `ApInt` for static signed interpretation of +/// the value. /// -/// This very cheaply transformes to and from `ApInt` and `UInt` instances and together with -/// `UInt` offers a more elegant and higher-level abstraction interface to the lower-level `ApInt`. +/// This very cheaply transformes to and from `ApInt` and `UInt` instances and +/// together with `UInt` offers a more elegant and higher-level abstraction +/// interface to the lower-level `ApInt`. #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(serde_support, Serialize)] #[cfg_attr(serde_support, Deserialize)] @@ -82,7 +84,8 @@ impl Int { impl Int { /// Creates a new `Int` from the given `Bit` value with a bit width of `1`. /// - /// This function is generic over types that are convertible to `Bit` such as `bool`. + /// This function is generic over types that are convertible to `Bit` such + /// as `bool`. pub fn from_bit(bit: B) -> Int where B: Into, @@ -145,12 +148,14 @@ impl Int { Int::from(ApInt::all_set(width)) } - /// Returns the smallest `Int` that can be represented by the given `BitWidth`. + /// Returns the smallest `Int` that can be represented by the given + /// `BitWidth`. pub fn min_value(width: BitWidth) -> Int { Int::from(ApInt::signed_min_value(width)) } - /// Returns the largest `Int` that can be represented by the given `BitWidth`. + /// Returns the largest `Int` that can be represented by the given + /// `BitWidth`. pub fn max_value(width: BitWidth) -> Int { Int::from(ApInt::signed_max_value(width)) } @@ -223,8 +228,8 @@ impl Int { /// # Note /// /// - Zero (`0`) is also called the additive neutral element. - /// - This operation is more efficient than comparing two instances - /// of `Int` for the same reason. + /// - This operation is more efficient than comparing two instances of `Int` + /// for the same reason. pub fn is_zero(&self) -> bool { self.value.is_zero() } @@ -234,8 +239,8 @@ impl Int { /// # Note /// /// - One (`1`) is also called the multiplicative neutral element. - /// - This operation is more efficient than comparing two instances - /// of `Int` for the same reason. + /// - This operation is more efficient than comparing two instances of `Int` + /// for the same reason. pub fn is_one(&self) -> bool { self.value.is_one() } @@ -361,8 +366,9 @@ impl Int { } } -/// If `self` and `rhs` have unmatching bit widths, `None` will be returned for `partial_cmp` -/// and `false` will be returned for the rest of the `PartialOrd` methods. +/// If `self` and `rhs` have unmatching bit widths, `None` will be returned for +/// `partial_cmp` and `false` will be returned for the rest of the `PartialOrd` +/// methods. impl PartialOrd for Int { fn partial_cmp(&self, rhs: &Int) -> Option { if self.value.width() != rhs.value.width() { @@ -403,8 +409,8 @@ impl Int { /// /// # Note /// - /// - Basically this returns `true` if the least significant - /// bit of this `Int` is `1` and `false` otherwise. + /// - Basically this returns `true` if the least significant bit of this + /// `Int` is `1` and `false` otherwise. pub fn resize_to_bool(&self) -> bool { self.value.resize_to_bool() } @@ -413,9 +419,8 @@ impl Int { /// /// # Note /// - /// - All bits but the least significant `8` bits are - /// being ignored by this operation to construct the - /// result. + /// - All bits but the least significant `8` bits are being ignored by this + /// operation to construct the result. pub fn resize_to_i8(&self) -> i8 { self.value.resize_to_i8() } @@ -424,9 +429,8 @@ impl Int { /// /// # Note /// - /// - All bits but the least significant `16` bits are - /// being ignored by this operation to construct the - /// result. + /// - All bits but the least significant `16` bits are being ignored by this + /// operation to construct the result. pub fn resize_to_i16(&self) -> i16 { self.value.resize_to_i16() } @@ -435,9 +439,8 @@ impl Int { /// /// # Note /// - /// - All bits but the least significant `32` bits are - /// being ignored by this operation to construct the - /// result. + /// - All bits but the least significant `32` bits are being ignored by this + /// operation to construct the result. pub fn resize_to_i32(&self) -> i32 { self.value.resize_to_i32() } @@ -446,9 +449,8 @@ impl Int { /// /// # Note /// - /// - All bits but the least significant `64` bits are - /// being ignored by this operation to construct the - /// result. + /// - All bits but the least significant `64` bits are being ignored by this + /// operation to construct the result. pub fn resize_to_i64(&self) -> i64 { self.value.resize_to_i64() } @@ -457,9 +459,8 @@ impl Int { /// /// # Note /// - /// - All bits but the least significant `128` bits are - /// being ignored by this operation to construct the - /// result. + /// - All bits but the least significant `128` bits are being ignored by + /// this operation to construct the result. pub fn resize_to_i128(&self) -> i128 { self.value.resize_to_i128() } @@ -477,8 +478,8 @@ impl Int { /// /// # Errors /// - /// - If the value represented by this `Int` can not be - /// represented by a `bool`. + /// - If the value represented by this `Int` can not be represented by a + /// `bool`. pub fn try_to_bool(&self) -> Result { self.value.try_to_bool() } @@ -487,13 +488,13 @@ impl Int { /// /// # Note /// - /// - This conversion is possible as long as the value represented - /// by this `Int` does not exceed the maximum value of `i8`. + /// - This conversion is possible as long as the value represented by this + /// `Int` does not exceed the maximum value of `i8`. /// /// # Errors /// - /// - If the value represented by this `Int` can not be - /// represented by a `u8`. + /// - If the value represented by this `Int` can not be represented by a + /// `u8`. pub fn try_to_i8(&self) -> Result { self.value.try_to_i8() } @@ -502,13 +503,13 @@ impl Int { /// /// # Note /// - /// - This conversion is possible as long as the value represented - /// by this `Int` does not exceed the maximum value of `i16`. + /// - This conversion is possible as long as the value represented by this + /// `Int` does not exceed the maximum value of `i16`. /// /// # Errors /// - /// - If the value represented by this `Int` can not be - /// represented by a `i16`. + /// - If the value represented by this `Int` can not be represented by a + /// `i16`. pub fn try_to_i16(&self) -> Result { self.value.try_to_i16() } @@ -517,13 +518,13 @@ impl Int { /// /// # Note /// - /// - This conversion is possible as long as the value represented - /// by this `Int` does not exceed the maximum value of `i32`. + /// - This conversion is possible as long as the value represented by this + /// `Int` does not exceed the maximum value of `i32`. /// /// # Errors /// - /// - If the value represented by this `Int` can not be - /// represented by a `i32`. + /// - If the value represented by this `Int` can not be represented by a + /// `i32`. pub fn try_to_i32(&self) -> Result { self.value.try_to_i32() } @@ -532,13 +533,13 @@ impl Int { /// /// # Note /// - /// - This conversion is possible as long as the value represented - /// by this `Int` does not exceed the maximum value of `i64`. + /// - This conversion is possible as long as the value represented by this + /// `Int` does not exceed the maximum value of `i64`. /// /// # Errors /// - /// - If the value represented by this `Int` can not be - /// represented by a `i64`. + /// - If the value represented by this `Int` can not be represented by a + /// `i64`. pub fn try_to_i64(&self) -> Result { self.value.try_to_i64() } @@ -547,8 +548,8 @@ impl Int { /// /// # Note /// - /// - This conversion is possible as long as the value represented - /// by this `Int` does not exceed the maximum value of `i128`. + /// - This conversion is possible as long as the value represented by this + /// `Int` does not exceed the maximum value of `i128`. /// /// # Complexity /// @@ -556,8 +557,8 @@ impl Int { /// /// # Errors /// - /// - If the value represented by this `Int` can not be - /// represented by a `i128`. + /// - If the value represented by this `Int` can not be represented by a + /// `i128`. pub fn try_to_i128(&self) -> Result { self.value.try_to_i128() } @@ -571,7 +572,8 @@ impl Int { /// /// # Errors /// - /// - If the given `shift_amount` is invalid for the bit width of this `Int`. + /// - If the given `shift_amount` is invalid for the bit width of this + /// `Int`. pub fn wrapping_shl_assign(&mut self, shift_amount: S) -> Result<()> where S: Into, @@ -579,13 +581,15 @@ impl Int { self.value.wrapping_shl_assign(shift_amount) } - /// Shift this `Int` left by the given `shift_amount` bits and returns the result. + /// Shift this `Int` left by the given `shift_amount` bits and returns the + /// result. /// /// This operation is inplace and will **not** allocate memory. /// /// # Errors /// - /// - If the given `shift_amount` is invalid for the bit width of this `Int`. + /// - If the given `shift_amount` is invalid for the bit width of this + /// `Int`. pub fn into_wrapping_shl(self, shift_amount: S) -> Result where S: Into, @@ -599,7 +603,8 @@ impl Int { /// /// # Errors /// - /// - If the given `shift_amount` is invalid for the bit width of this `Int`. + /// - If the given `shift_amount` is invalid for the bit width of this + /// `Int`. pub fn wrapping_shr_assign(&mut self, shift_amount: S) -> Result<()> where S: Into, @@ -614,7 +619,8 @@ impl Int { /// /// # Errors /// - /// - If the given `shift_amount` is invalid for the bit width of this `Int`. + /// - If the given `shift_amount` is invalid for the bit width of this + /// `Int`. pub fn into_wrapping_shr(self, shift_amount: S) -> Result where S: Into, @@ -775,8 +781,7 @@ impl Int { /// # Note /// /// - This is useful for method chaining. - /// - For more details look into - /// [`extend`](struct.Int.html#method.extend). + /// - For more details look into [`extend`](struct.Int.html#method.extend). /// /// # Errors /// @@ -814,8 +819,7 @@ impl Int { /// # Note /// /// - This is useful for method chaining. - /// - For more details look into - /// [`resize`](struct.Int.html#method.resize). + /// - For more details look into [`resize`](struct.Int.html#method.resize). pub fn into_resize(self, target_width: W) -> Int where W: Into, @@ -829,11 +833,9 @@ impl Int { /// /// This operation will forward to /// - /// - [`truncate`](struct.Int.html#method.truncate) - /// if `target_width` is less than or equal to the width of - /// the given `Int` - /// - [`extend`](struct.Int.html#method.extend) - /// otherwise + /// - [`truncate`](struct.Int.html#method.truncate) if `target_width` is + /// less than or equal to the width of the given `Int` + /// - [`extend`](struct.Int.html#method.extend) otherwise pub fn resize(&mut self, target_width: W) where W: Into, @@ -965,8 +967,8 @@ impl Int { /// /// # Note /// - /// - If the bit at the given position was `0` it will be `1` - /// after this operation and vice versa. + /// - If the bit at the given position was `0` it will be `1` after this + /// operation and vice versa. /// /// # Errors /// @@ -1024,9 +1026,10 @@ impl Int { /// /// # Note /// - /// - If the sign bit was `0` it will be `1` after this operation and vice versa. - /// - Depending on the interpretation of the `Int` this - /// operation changes its signedness. + /// - If the sign bit was `0` it will be `1` after this operation and vice + /// versa. + /// - Depending on the interpretation of the `Int` this operation changes + /// its signedness. pub fn flip_sign_bit(&mut self) { self.value.flip_sign_bit() } @@ -1044,12 +1047,14 @@ impl Int { self.value.count_zeros() } - /// Returns the number of leading zeros in the binary representation of this `Int`. + /// Returns the number of leading zeros in the binary representation of this + /// `Int`. pub fn leading_zeros(&self) -> usize { self.value.leading_zeros() } - /// Returns the number of trailing zeros in the binary representation of this `Int`. + /// Returns the number of trailing zeros in the binary representation of + /// this `Int`. pub fn trailing_zeros(&self) -> usize { self.value.trailing_zeros() } @@ -1215,8 +1220,9 @@ impl Int { /// /// # Note /// - /// In the low-level bit-wise representation there is no difference between signed - /// and unsigned subtraction of fixed bit-width integers. (Cite: LLVM) + /// In the low-level bit-wise representation there is no difference between + /// signed and unsigned subtraction of fixed bit-width integers. (Cite: + /// LLVM) /// /// # Errors /// @@ -1229,8 +1235,9 @@ impl Int { /// /// # Note /// - /// In the low-level bit-wise representation there is no difference between signed - /// and unsigned subtraction of fixed bit-width integers. (Cite: LLVM) + /// In the low-level bit-wise representation there is no difference between + /// signed and unsigned subtraction of fixed bit-width integers. (Cite: + /// LLVM) /// /// # Errors /// @@ -1243,8 +1250,9 @@ impl Int { /// /// # Note /// - /// In the low-level bit-wise representation there is no difference between signed - /// and unsigned multiplication of fixed bit-width integers. (Cite: LLVM) + /// In the low-level bit-wise representation there is no difference between + /// signed and unsigned multiplication of fixed bit-width integers. + /// (Cite: LLVM) /// /// # Errors /// @@ -1257,8 +1265,9 @@ impl Int { /// /// # Note /// - /// In the low-level bit-wise representation there is no difference between signed - /// and unsigned multiplication of fixed bit-width integers. (Cite: LLVM) + /// In the low-level bit-wise representation there is no difference between + /// signed and unsigned multiplication of fixed bit-width integers. + /// (Cite: LLVM) /// /// # Errors /// @@ -1271,9 +1280,10 @@ impl Int { /// /// # Note /// - /// - This operation will **not** allocate memory and computes inplace of `self`. - /// - In the low-level machine abstraction signed division and unsigned division - /// are two different operations. + /// - This operation will **not** allocate memory and computes inplace of + /// `self`. + /// - In the low-level machine abstraction signed division and unsigned + /// division are two different operations. /// /// # Errors /// @@ -1286,9 +1296,10 @@ impl Int { /// /// # Note /// - /// - This operation will **not** allocate memory and computes inplace of `self`. - /// - In the low-level machine abstraction signed division and unsigned division - /// are two different operations. + /// - This operation will **not** allocate memory and computes inplace of + /// `self`. + /// - In the low-level machine abstraction signed division and unsigned + /// division are two different operations. /// /// # Errors /// @@ -1297,13 +1308,15 @@ impl Int { self.value.wrapping_sdiv_assign(&rhs.value) } - /// Calculates the **unsigned** remainder of `self` by `rhs` and returns the result. + /// Calculates the **unsigned** remainder of `self` by `rhs` and returns the + /// result. /// /// # Note /// - /// - This operation will **not** allocate memory and computes inplace of `self`. - /// - In the low-level machine abstraction signed division and unsigned division - /// are two different operations. + /// - This operation will **not** allocate memory and computes inplace of + /// `self`. + /// - In the low-level machine abstraction signed division and unsigned + /// division are two different operations. /// /// # Errors /// @@ -1316,9 +1329,10 @@ impl Int { /// /// # Note /// - /// - This operation will **not** allocate memory and computes inplace of `self`. - /// - In the low-level machine abstraction signed division and unsigned division - /// are two different operations. + /// - This operation will **not** allocate memory and computes inplace of + /// `self`. + /// - In the low-level machine abstraction signed division and unsigned + /// division are two different operations. /// /// # Errors /// diff --git a/src/lib.rs b/src/lib.rs index 251e0db..41f04fd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,20 +1,22 @@ //! Arbitrary precision integers library. //! -//! This library mainly features the **A**rbitrary **p**recision **Int**eger (`ApInt`) type -//! which is an `n-bit` integer type acting like a machine integer working in the twos-complement. +//! This library mainly features the **A**rbitrary **p**recision **Int**eger +//! (`ApInt`) type which is an `n-bit` integer type acting like a machine +//! integer working in the twos-complement. //! -//! This is useful for emulating machine integers for example in constant evaluation of compilers -//! or for solving bitvector formulas of SMT solvers. +//! This is useful for emulating machine integers for example in constant +//! evaluation of compilers or for solving bitvector formulas of SMT solvers. //! -//! Internally `ApInt` uses small-value optimization for values with a bit-width less than or -//! equal to `64` bits. It uses `64` bit digits and thus its algorithms computes within the base -//! of 264. +//! Internally `ApInt` uses small-value optimization for values with a bit-width +//! less than or equal to `64` bits. It uses `64` bit digits and thus its +//! algorithms computes within the base of 264. //! -//! The `ApInt` data structure does **not** know signedness. Instead, the operations defined on it -//! (methods) do so. This makes it the perfect building block for higher-level primitives later on. +//! The `ApInt` data structure does **not** know signedness. Instead, the +//! operations defined on it (methods) do so. This makes it the perfect building +//! block for higher-level primitives later on. //! -//! The crate was designed for correctness of emulation and performance in mind and the interface -//! of `ApInt` is very comprehensive. +//! The crate was designed for correctness of emulation and performance in mind +//! and the interface of `ApInt` is very comprehensive. // #![allow(dead_code)] // #![deny(missing_docs)] diff --git a/src/radix.rs b/src/radix.rs index 9feca52..04f4a04 100644 --- a/src/radix.rs +++ b/src/radix.rs @@ -21,15 +21,18 @@ use crate::{ /// /// - The binary 2-radix supports only `0` and `1` as input. /// - The decimal 10-radix supports `0`..=`9` as input characters. -/// - The hex-dec 16-radix supports inputs characters within `0`..=`9` and `a`..=`f`. +/// - The hex-dec 16-radix supports inputs characters within `0`..=`9` and +/// `a`..=`f`. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct Radix(u8); impl Radix { - /// The minimum supported radix is the binary that has only `0` and `1` in its alphabet. - const MIN: u8 = 2; - /// The maximum supported radix is the 36-ary that has an alphabet containing `0..9` and `a..z`. + /// The maximum supported radix is the 36-ary that has an alphabet + /// containing `0..9` and `a..z`. const MAX: u8 = 36; + /// The minimum supported radix is the binary that has only `0` and `1` in + /// its alphabet. + const MIN: u8 = 2; /// Create a new `Radix` from the given `u8`. /// @@ -50,28 +53,29 @@ impl Radix { self.0 } - /// Returns `true` if the given byte is a valid ascii representation for this `Radix` - /// and `false` otherwise. + /// Returns `true` if the given byte is a valid ascii representation for + /// this `Radix` and `false` otherwise. #[inline] pub(crate) fn is_valid_byte(self, byte: u8) -> bool { byte < self.to_u8() } - /// Returns `true` if the number represenatation of this `Radix` is a power of two - /// and `false` otherwise. + /// Returns `true` if the number represenatation of this `Radix` is a power + /// of two and `false` otherwise. #[inline] pub(crate) fn is_power_of_two(self) -> bool { self.to_u8().is_power_of_two() } - /// Returns the number of bits required to store a single digit with this `Radix`. + /// Returns the number of bits required to store a single digit with this + /// `Radix`. /// /// This is equivalent to the logarithm of base 2 for this `Radix`. /// /// # Example /// - /// For binary `Radix` (`= 2`) there are only digits `0` and `1` which can be - /// stored in `1` bit each. + /// For binary `Radix` (`= 2`) there are only digits `0` and `1` which can + /// be stored in `1` bit each. /// For a hexdec `Radix` (`= 16`) digits are `0`..=`9`,`A`..=`F` and a digit /// requires `4` bits to be stored. /// @@ -91,8 +95,8 @@ impl Radix { /// /// # Example /// - /// For binary `Radix` (`= 2`) there are only digits `0` and `1` which can be - /// stored in `1` bit each. + /// For binary `Radix` (`= 2`) there are only digits `0` and `1` which can + /// be stored in `1` bit each. /// For a hexdec `Radix` (`= 16`) digits are `0`..=`9`,`A`..=`F` and a digit /// requires `4` bits to be stored. /// For a decimal `Radix` (`= 10`) digits `None` is returned. @@ -110,22 +114,23 @@ impl Radix { /// Returns the greatest power of the radix <= digit::BASE. /// - /// Note: This operation is only valid for `Radix` instances that are not a power-of-two. + /// Note: This operation is only valid for `Radix` instances that are not a + /// power-of-two. #[inline] pub(crate) fn get_radix_base(self) -> (Digit, usize) { assert!(!self.is_power_of_two()); // To generate this table: // ``` - // for radix in 2u64..37 { - // let mut power = digit::BITS / find_last_bit_set(radix.to_u8() as u64); - // let mut base = (radix.to_u8() as u32).pow(power as u32); - // while let Some(b) = base.checked_mul(radix) { - // base = b; - // power += 1; - // } - // println!("({:20}, {:2}), // {:2}", base, power, radix); - // } + // for radix in 2u64..37 { + // let mut power = digit::BITS / find_last_bit_set(radix.to_u8() as u64); + // let mut base = (radix.to_u8() as u32).pow(power as u32); + // while let Some(b) = base.checked_mul(radix) { + // base = b; + // power += 1; + // } + // println!("({:20}, {:2}), // {:2}", base, power, radix); + // } // ``` const BASES: [(DigitRepr, usize); 37] = [ (0, 0), // 0 (invalid Radix!) diff --git a/src/storage.rs b/src/storage.rs index dbee2a1..061c7ec 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -25,10 +25,12 @@ where } impl Storage { - /// Returns `true` if the given `BitWidth` is small enough to be stored inline. + /// Returns `true` if the given `BitWidth` is small enough to be stored + /// inline. /// - /// Note: Inline storage in the context of `ApInt` means that it is space-optimized - /// similar to the well-known small-string optimization. + /// Note: Inline storage in the context of `ApInt` means that it is + /// space-optimized similar to the well-known small-string + /// optimization. #[inline] fn is_inline(width: BitWidth) -> bool { width.to_usize() <= digit::BITS diff --git a/src/uint.rs b/src/uint.rs index e163753..271b52a 100644 --- a/src/uint.rs +++ b/src/uint.rs @@ -44,10 +44,12 @@ use core::{ /// Unsigned machine integer with arbitrary bitwidths and modulo arithmetics. /// -/// Thin convenience wrapper around `ApInt` for static unsigned interpretation of the value. +/// Thin convenience wrapper around `ApInt` for static unsigned interpretation +/// of the value. /// -/// This very cheaply transformes to and from `ApInt` and `Int` instances and together with -/// `Int` offers a more elegant and higher-level abstraction interface to the lower-level `ApInt`. +/// This very cheaply transformes to and from `ApInt` and `Int` instances and +/// together with `Int` offers a more elegant and higher-level abstraction +/// interface to the lower-level `ApInt`. #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(serde_support, Serialize)] #[cfg_attr(serde_support, Deserialize)] @@ -77,7 +79,8 @@ impl UInt { impl UInt { /// Creates a new `UInt` from the given `Bit` value with a bit width of `1`. /// - /// This function is generic over types that are convertible to `Bit` such as `bool`. + /// This function is generic over types that are convertible to `Bit` such + /// as `bool`. pub fn from_bit(bit: B) -> UInt where B: Into, @@ -140,12 +143,14 @@ impl UInt { UInt::from(ApInt::all_set(width)) } - /// Returns the smallest `UInt` that can be represented by the given `BitWidth`. + /// Returns the smallest `UInt` that can be represented by the given + /// `BitWidth`. pub fn min_value(width: BitWidth) -> UInt { UInt::from(ApInt::unsigned_min_value(width)) } - /// Returns the largest `UInt` that can be represented by the given `BitWidth`. + /// Returns the largest `UInt` that can be represented by the given + /// `BitWidth`. pub fn max_value(width: BitWidth) -> UInt { UInt::from(ApInt::unsigned_max_value(width)) } @@ -218,8 +223,8 @@ impl UInt { /// # Note /// /// - Zero (`0`) is also called the additive neutral element. - /// - This operation is more efficient than comparing two instances - /// of `UInt` for the same reason. + /// - This operation is more efficient than comparing two instances of + /// `UInt` for the same reason. pub fn is_zero(&self) -> bool { self.value.is_zero() } @@ -229,8 +234,8 @@ impl UInt { /// # Note /// /// - One (`1`) is also called the multiplicative neutral element. - /// - This operation is more efficient than comparing two instances - /// of `UInt` for the same reason. + /// - This operation is more efficient than comparing two instances of + /// `UInt` for the same reason. pub fn is_one(&self) -> bool { self.value.is_one() } @@ -311,8 +316,9 @@ impl UInt { } } -/// If `self` and `rhs` have unmatching bit widths, `None` will be returned for `partial_cmp` -/// and `false` will be returned for the rest of the `PartialOrd` methods. +/// If `self` and `rhs` have unmatching bit widths, `None` will be returned for +/// `partial_cmp` and `false` will be returned for the rest of the `PartialOrd` +/// methods. impl PartialOrd for UInt { fn partial_cmp(&self, rhs: &UInt) -> Option { if self.value.width() != rhs.value.width() { @@ -353,8 +359,8 @@ impl UInt { /// /// # Note /// - /// - Basically this returns `true` if the least significant - /// bit of this `UInt` is `1` and `false` otherwise. + /// - Basically this returns `true` if the least significant bit of this + /// `UInt` is `1` and `false` otherwise. pub fn resize_to_bool(&self) -> bool { self.value.resize_to_bool() } @@ -363,9 +369,8 @@ impl UInt { /// /// # Note /// - /// - All bits but the least significant `8` bits are - /// being ignored by this operation to construct the - /// result. + /// - All bits but the least significant `8` bits are being ignored by this + /// operation to construct the result. pub fn resize_to_u8(&self) -> u8 { self.value.resize_to_u8() } @@ -374,9 +379,8 @@ impl UInt { /// /// # Note /// - /// - All bits but the least significant `16` bits are - /// being ignored by this operation to construct the - /// result. + /// - All bits but the least significant `16` bits are being ignored by this + /// operation to construct the result. pub fn resize_to_u16(&self) -> u16 { self.value.resize_to_u16() } @@ -385,9 +389,8 @@ impl UInt { /// /// # Note /// - /// - All bits but the least significant `32` bits are - /// being ignored by this operation to construct the - /// result. + /// - All bits but the least significant `32` bits are being ignored by this + /// operation to construct the result. pub fn resize_to_u32(&self) -> u32 { self.value.resize_to_u32() } @@ -396,9 +399,8 @@ impl UInt { /// /// # Note /// - /// - All bits but the least significant `64` bits are - /// being ignored by this operation to construct the - /// result. + /// - All bits but the least significant `64` bits are being ignored by this + /// operation to construct the result. pub fn resize_to_u64(&self) -> u64 { self.value.resize_to_u64() } @@ -407,9 +409,8 @@ impl UInt { /// /// # Note /// - /// - All bits but the least significant `128` bits are - /// being ignored by this operation to construct the - /// result. + /// - All bits but the least significant `128` bits are being ignored by + /// this operation to construct the result. pub fn resize_to_u128(&self) -> u128 { self.value.resize_to_u128() } @@ -427,8 +428,8 @@ impl UInt { /// /// # Errors /// - /// - If the value represented by this `UInt` can not be - /// represented by a `bool`. + /// - If the value represented by this `UInt` can not be represented by a + /// `bool`. pub fn try_to_bool(&self) -> Result { self.value.try_to_bool() } @@ -437,13 +438,13 @@ impl UInt { /// /// # Note /// - /// - This conversion is possible as long as the value represented - /// by this `UInt` does not exceed the maximum value of `u8`. + /// - This conversion is possible as long as the value represented by this + /// `UInt` does not exceed the maximum value of `u8`. /// /// # Errors /// - /// - If the value represented by this `UInt` can not be - /// represented by a `u8`. + /// - If the value represented by this `UInt` can not be represented by a + /// `u8`. pub fn try_to_u8(&self) -> Result { self.value.try_to_u8() } @@ -452,13 +453,13 @@ impl UInt { /// /// # Note /// - /// - This conversion is possible as long as the value represented - /// by this `UInt` does not exceed the maximum value of `u16`. + /// - This conversion is possible as long as the value represented by this + /// `UInt` does not exceed the maximum value of `u16`. /// /// # Errors /// - /// - If the value represented by this `UInt` can not be - /// represented by a `u16`. + /// - If the value represented by this `UInt` can not be represented by a + /// `u16`. pub fn try_to_u16(&self) -> Result { self.value.try_to_u16() } @@ -467,13 +468,13 @@ impl UInt { /// /// # Note /// - /// - This conversion is possible as long as the value represented - /// by this `UInt` does not exceed the maximum value of `u32`. + /// - This conversion is possible as long as the value represented by this + /// `UInt` does not exceed the maximum value of `u32`. /// /// # Errors /// - /// - If the value represented by this `UInt` can not be - /// represented by a `u32`. + /// - If the value represented by this `UInt` can not be represented by a + /// `u32`. pub fn try_to_u32(&self) -> Result { self.value.try_to_u32() } @@ -482,13 +483,13 @@ impl UInt { /// /// # Note /// - /// - This conversion is possible as long as the value represented - /// by this `UInt` does not exceed the maximum value of `u64`. + /// - This conversion is possible as long as the value represented by this + /// `UInt` does not exceed the maximum value of `u64`. /// /// # Errors /// - /// - If the value represented by this `UInt` can not be - /// represented by a `u64`. + /// - If the value represented by this `UInt` can not be represented by a + /// `u64`. pub fn try_to_u64(&self) -> Result { self.value.try_to_u64() } @@ -497,8 +498,8 @@ impl UInt { /// /// # Note /// - /// - This conversion is possible as long as the value represented - /// by this `UInt` does not exceed the maximum value of `u128`. + /// - This conversion is possible as long as the value represented by this + /// `UInt` does not exceed the maximum value of `u128`. /// /// # Complexity /// @@ -506,8 +507,8 @@ impl UInt { /// /// # Errors /// - /// - If the value represented by this `UInt` can not be - /// represented by a `u128`. + /// - If the value represented by this `UInt` can not be represented by a + /// `u128`. pub fn try_to_u128(&self) -> Result { self.value.try_to_u128() } @@ -521,7 +522,8 @@ impl UInt { /// /// # Errors /// - /// - If the given `shift_amount` is invalid for the bit width of this `UInt`. + /// - If the given `shift_amount` is invalid for the bit width of this + /// `UInt`. pub fn wrapping_shl_assign(&mut self, shift_amount: S) -> Result<()> where S: Into, @@ -529,13 +531,15 @@ impl UInt { self.value.wrapping_shl_assign(shift_amount) } - /// Shift this `UInt` left by the given `shift_amount` bits and returns the result. + /// Shift this `UInt` left by the given `shift_amount` bits and returns the + /// result. /// /// This operation is inplace and will **not** allocate memory. /// /// # Errors /// - /// - If the given `shift_amount` is invalid for the bit width of this `UInt`. + /// - If the given `shift_amount` is invalid for the bit width of this + /// `UInt`. pub fn into_wrapping_shl(self, shift_amount: S) -> Result where S: Into, @@ -549,7 +553,8 @@ impl UInt { /// /// # Errors /// - /// - If the given `shift_amount` is invalid for the bit width of this `UInt`. + /// - If the given `shift_amount` is invalid for the bit width of this + /// `UInt`. pub fn wrapping_shr_assign(&mut self, shift_amount: S) -> Result<()> where S: Into, @@ -564,7 +569,8 @@ impl UInt { /// /// # Errors /// - /// - If the given `shift_amount` is invalid for the bit width of this `UInt`. + /// - If the given `shift_amount` is invalid for the bit width of this + /// `UInt`. pub fn into_wrapping_shr(self, shift_amount: S) -> Result where S: Into, @@ -732,8 +738,7 @@ impl UInt { /// # Note /// /// - This is useful for method chaining. - /// - For more details look into - /// [`extend`](struct.UInt.html#method.extend). + /// - For more details look into [`extend`](struct.UInt.html#method.extend). /// /// # Errors /// @@ -771,8 +776,7 @@ impl UInt { /// # Note /// /// - This is useful for method chaining. - /// - For more details look into - /// [`resize`](struct.UInt.html#method.resize). + /// - For more details look into [`resize`](struct.UInt.html#method.resize). pub fn into_resize(self, target_width: W) -> UInt where W: Into, @@ -786,11 +790,9 @@ impl UInt { /// /// This operation will forward to /// - /// - [`truncate`](struct.UInt.html#method.truncate) - /// if `target_width` is less than or equal to the width of - /// the given `UInt` - /// - [`extend`](struct.UInt.html#method.extend) - /// otherwise + /// - [`truncate`](struct.UInt.html#method.truncate) if `target_width` is + /// less than or equal to the width of the given `UInt` + /// - [`extend`](struct.UInt.html#method.extend) otherwise pub fn resize(&mut self, target_width: W) where W: Into, @@ -922,8 +924,8 @@ impl UInt { /// /// # Note /// - /// - If the bit at the given position was `0` it will be `1` - /// after this operation and vice versa. + /// - If the bit at the given position was `0` it will be `1` after this + /// operation and vice versa. /// /// # Errors /// @@ -973,12 +975,14 @@ impl UInt { self.value.count_zeros() } - /// Returns the number of leading zeros in the binary representation of this `UInt`. + /// Returns the number of leading zeros in the binary representation of this + /// `UInt`. pub fn leading_zeros(&self) -> usize { self.value.leading_zeros() } - /// Returns the number of trailing zeros in the binary representation of this `UInt`. + /// Returns the number of trailing zeros in the binary representation of + /// this `UInt`. pub fn trailing_zeros(&self) -> usize { self.value.trailing_zeros() } @@ -1130,8 +1134,9 @@ impl UInt { /// /// # Note /// - /// In the low-level bit-wise representation there is no difference between signed - /// and unsigned subtraction of fixed bit-width integers. (Cite: LLVM) + /// In the low-level bit-wise representation there is no difference between + /// signed and unsigned subtraction of fixed bit-width integers. (Cite: + /// LLVM) /// /// # Errors /// @@ -1144,8 +1149,9 @@ impl UInt { /// /// # Note /// - /// In the low-level bit-wise representation there is no difference between signed - /// and unsigned subtraction of fixed bit-width integers. (Cite: LLVM) + /// In the low-level bit-wise representation there is no difference between + /// signed and unsigned subtraction of fixed bit-width integers. (Cite: + /// LLVM) /// /// # Errors /// @@ -1158,8 +1164,9 @@ impl UInt { /// /// # Note /// - /// In the low-level bit-wise representation there is no difference between signed - /// and unsigned multiplication of fixed bit-width integers. (Cite: LLVM) + /// In the low-level bit-wise representation there is no difference between + /// signed and unsigned multiplication of fixed bit-width integers. + /// (Cite: LLVM) /// /// # Errors /// @@ -1172,8 +1179,9 @@ impl UInt { /// /// # Note /// - /// In the low-level bit-wise representation there is no difference between signed - /// and unsigned multiplication of fixed bit-width integers. (Cite: LLVM) + /// In the low-level bit-wise representation there is no difference between + /// signed and unsigned multiplication of fixed bit-width integers. + /// (Cite: LLVM) /// /// # Errors /// @@ -1186,9 +1194,10 @@ impl UInt { /// /// # Note /// - /// - This operation will **not** allocate memory and computes inplace of `self`. - /// - In the low-level machine abstraction signed division and unsigned division - /// are two different operations. + /// - This operation will **not** allocate memory and computes inplace of + /// `self`. + /// - In the low-level machine abstraction signed division and unsigned + /// division are two different operations. /// /// # Errors /// @@ -1201,9 +1210,10 @@ impl UInt { /// /// # Note /// - /// - This operation will **not** allocate memory and computes inplace of `self`. - /// - In the low-level machine abstraction signed division and unsigned division - /// are two different operations. + /// - This operation will **not** allocate memory and computes inplace of + /// `self`. + /// - In the low-level machine abstraction signed division and unsigned + /// division are two different operations. /// /// # Errors /// @@ -1212,13 +1222,15 @@ impl UInt { self.value.wrapping_udiv_assign(&rhs.value) } - /// Calculates the **unsigned** remainder of `self` by `rhs` and returns the result. + /// Calculates the **unsigned** remainder of `self` by `rhs` and returns the + /// result. /// /// # Note /// - /// - This operation will **not** allocate memory and computes inplace of `self`. - /// - In the low-level machine abstraction signed division and unsigned division - /// are two different operations. + /// - This operation will **not** allocate memory and computes inplace of + /// `self`. + /// - In the low-level machine abstraction signed division and unsigned + /// division are two different operations. /// /// # Errors /// @@ -1231,9 +1243,10 @@ impl UInt { /// /// # Note /// - /// - This operation will **not** allocate memory and computes inplace of `self`. - /// - In the low-level machine abstraction signed division and unsigned division - /// are two different operations. + /// - This operation will **not** allocate memory and computes inplace of + /// `self`. + /// - In the low-level machine abstraction signed division and unsigned + /// division are two different operations. /// /// # Errors ///