rust/library/core/tests
bors d117b7f211 Auto merge of #132195 - clarfonthey:bigint-mul, r=scottmcm
Tidy up bigint multiplication methods

This tidies up the library version of the bigint multiplication methods after the addition of the intrinsics in #133663. It follows [this summary](https://github.com/rust-lang/rust/issues/85532#issuecomment-2403442775) of what's desired for these methods.

Note that, if `2H = N`, then `uH::MAX * uH::MAX + uH::MAX + uH::MAX` is `uN::MAX`, and that we can effectively add two "carry" values without overflowing.

For ease of terminology, the "low-order" or "least significant" or "wrapping" half of multiplication will be called the low part, and the "high-order" or "most significant" or "overflowing" half of multiplication will be called the high part. In all cases, the return convention is `(low, high)` and left unchanged by this PR, to be litigated later.

## API Changes

The original API:

```rust
impl uN {
    // computes self * rhs
    pub const fn widening_mul(self, rhs: uN) -> (uN, uN);

    // computes self * rhs + carry
    pub const fn carrying_mul(self, rhs: uN, carry: uN) -> (uN, uN);
}
```

The added API:

```rust
impl uN {
    // computes self * rhs + carry1 + carry2
    pub const fn carrying2_mul(self, rhs: uN, carry: uN, add: uN) -> (uN, uN);
}
impl iN {
    // note that the low part is unsigned
    pub const fn widening_mul(self, rhs: iN) -> (uN, iN);
    pub const fn carrying_mul(self, rhs: iN, carry: iN) -> (uN, iN);
    pub const fn carrying_mul_add(self, rhs: iN, carry: iN, add: iN) -> (uN, iN);
}
```

Additionally, a naive implementation has been added for `u128` and `i128` since there are no double-wide types for those. Eventually, an intrinsic will be added to make these more efficient, but rather than doing this all at once, the library changes are added first.

## Justifications for API

The unsigned parts are done to ensure consistency with overflowing addition: for a two's complement integer, you want to have unsigned overflow semantics for all parts of the integer except the highest one. This is because overflow for unsigned integers happens on the highest bit (from `MAX` to zero), whereas overflow for signed integers happens on the second highest bit (from `MAX` to `MIN`). Since the sign information only matters in the highest part, we use unsigned overflow for everything but that part.

There is still discussion on the merits of signed bigint *addition* methods, since getting the behaviour right is very subtle, but at least for signed bigint *multiplication*, the sign of the operands does make a difference. So, it feels appropriate that at least until we've nailed down the final API, there should be an option to do signed versions of these methods.

Additionally, while it's unclear whether we need all three versions of bigint multiplication (widening, carrying-1, and carrying-2), since it's possible to have up to two carries without overflow, there should at least be a method to allow that. We could potentially only offer the carry-2 method and expect that adding zero carries afterword will optimise correctly, but again, this can be litigated before stabilisation.

## Note on documentation

While a lot of care was put into the documentation for the `widening_mul` and `carrying_mul` methods on unsigned integers, I have not taken this same care for `carrying_mul_add` or the signed versions. While I have updated the doc tests to be more appropriate, there will likely be many documentation changes done before stabilisation.

## Note on tests

Alongside this change, I've added several tests to ensure that these methods work as expected. These are alongside the codegen tests for the intrinsics.
2024-12-31 18:49:36 +00:00
..
async_iter Remove unnecessary lets and borrowing from Waker::noop() usage. 2024-01-17 12:00:27 -08:00
ffi CStr: derive PartialEq, Eq; add test for Ord 2024-07-25 14:18:40 +03:00
fmt Refactored FormattingOptions to use a bitmask for storing flags 2024-12-05 21:48:35 +01:00
hash Use #[derive(Default)] instead of manually implementing it 2024-12-23 03:01:29 +00:00
io Make io::BorrowedCursor::advance safe 2024-02-07 16:46:28 +01:00
iter Impl FromIterator for tuples with arity 1-12 2024-12-26 08:47:49 +01:00
net core/net: add Ipv[46]Addr::from_octets, Ipv6Addr::from_segments 2024-10-13 20:26:23 +02:00
num Tidy up bigint mul methods 2024-12-27 22:01:51 -05:00
ops Explicitly specify type parameter on FromResidual impls in stdlib. 2024-08-12 12:54:18 -05:00
panic Fix test (location_const_file) 2022-10-08 11:48:53 +00:00
alloc.rs rename ptr::invalid -> ptr::without_provenance 2024-02-21 20:15:52 +01:00
any.rs Adjust library tests for unused_tuple_struct_fields -> dead_code 2024-01-02 15:34:37 -05:00
array.rs Reformat use declarations. 2024-07-29 08:26:52 +10:00
ascii_char.rs core: optimise Debug impl for ascii::Char 2024-08-09 22:50:57 +02:00
ascii.rs Optimize escape_ascii 2024-10-09 17:17:50 -04:00
asserting.rs Spelling library/ 2023-04-26 02:10:22 -04:00
atomic.rs update bootstrap configs 2024-10-15 20:30:23 -07:00
bool.rs fix library and rustdoc tests 2023-04-16 11:38:52 +00:00
cell.rs apply fmt 2024-01-11 15:04:48 +03:00
char.rs remove redundant imports 2023-12-10 10:56:22 +08:00
clone.rs Update core CloneToUninit tests 2024-11-13 13:42:41 -06:00
cmp.rs Reformat use declarations. 2024-07-29 08:26:52 +10:00
const_ptr.rs cleanup code w/ pointers in std a little 2022-08-05 16:47:49 +04:00
convert.rs fix library and rustdoc tests 2023-04-16 11:38:52 +00:00
error.rs Reformat using the new identifier sorting from rustfmt 2024-09-22 19:11:29 -04:00
ffi.rs CStr: derive PartialEq, Eq; add test for Ord 2024-07-25 14:18:40 +03:00
future.rs Reformat using the new identifier sorting from rustfmt 2024-09-22 19:11:29 -04:00
intrinsics.rs Override carrying_mul_add in cg_llvm 2024-12-27 08:17:40 -08:00
lazy.rs Do not run test where it cannot run 2024-10-17 09:33:39 -04:00
lib.rs Auto merge of #132195 - clarfonthey:bigint-mul, r=scottmcm 2024-12-31 18:49:36 +00:00
macros.rs Rustfmt 2024-09-13 15:18:30 -03:00
manually_drop.rs Flip cfg's for bootstrap bump 2023-07-12 21:38:55 -04:00
mem.rs fix UB in a test 2024-09-09 16:17:34 +02:00
nonzero.rs Add LowerExp and UpperExp implementations 2024-10-08 12:09:03 +02:00
ops.rs Explicitly specify type parameter on FromResidual impls in stdlib. 2024-08-12 12:54:18 -05:00
option.rs Make Option::as_[mut_]slice const 2024-06-19 21:44:47 +01:00
panic.rs Add newlines 2022-09-27 19:23:52 +00:00
pattern.rs mv std libs to library/ 2020-07-27 19:51:13 -05:00
pin_macro.rs Reformat using the new identifier sorting from rustfmt 2024-09-22 19:11:29 -04:00
pin.rs Partially stabilize const_pin 2024-10-16 21:24:38 +01:00
ptr.rs core: fix const ptr::swap_nonoverlapping when there are pointers at odd offsets in the type 2024-12-23 16:24:45 +01:00
result.rs Reformat use declarations. 2024-07-29 08:26:52 +10:00
simd.rs Fix library tests 2023-11-26 08:50:39 -05:00
slice.rs Support ranges in <[T]>::get_many_mut() 2024-11-25 10:04:06 +02:00
str_lossy.rs Stabilize Utf8Chunks 2024-04-24 15:27:47 -07:00
str.rs Update paths in comments. 2022-12-30 14:00:42 +01:00
task.rs Remove test of static Context 2023-01-02 10:33:23 -08:00
time.rs core: add Duration constructors 2024-01-24 14:24:57 +01:00
tuple.rs mv std libs to library/ 2020-07-27 19:51:13 -05:00
unicode.rs revert changes to unicode stability 2022-07-08 21:18:15 +00:00
waker.rs Reformat using the new identifier sorting from rustfmt 2024-09-22 19:11:29 -04:00