1
Fork 0
rust/library/core/tests
bors 18bfe5d8a9 Auto merge of #92048 - Urgau:num-midpoint, r=scottmcm
Add midpoint function for all integers and floating numbers

This pull-request adds the `midpoint` function to `{u,i}{8,16,32,64,128,size}`, `NonZeroU{8,16,32,64,size}` and `f{32,64}`.

This new function is analog to the [C++ midpoint](https://en.cppreference.com/w/cpp/numeric/midpoint) function, and basically compute `(a + b) / 2` with a rounding towards ~~`a`~~ negative infinity in the case of integers. Or simply said: `midpoint(a, b)` is `(a + b) >> 1` as if it were performed in a sufficiently-large signed integral type.

Note that unlike the C++ function this pull-request does not implement this function on pointers (`*const T` or `*mut T`). This could be implemented in a future pull-request if desire.

### Implementation

For `f32` and `f64` the implementation in based on the `libcxx` [one](18ab892ff7/libcxx/include/__numeric/midpoint.h (L65-L77)). I originally tried many different approach but all of them failed or lead me with a poor version of the `libcxx`. Note that `libstdc++` has a very similar one; Microsoft STL implementation is also basically the same as `libcxx`. It unfortunately doesn't seems like a better way exist.

For unsigned integers I created the macro `midpoint_impl!`, this macro has two branches:
 - The first one take `$SelfT` and is used when there is no unsigned integer with at least the double of bits. The code simply use this formula `a + (b - a) / 2` with the arguments in the correct order and signs to have the good rounding.
 - The second branch is used when a `$WideT` (at least double of bits as `$SelfT`) is provided, using a wider number means that no overflow can occur, this greatly improve the codegen (no branch and less instructions).

For signed integers the code basically forwards the signed numbers to the unsigned version of midpoint by mapping the signed numbers to their unsigned numbers (`ex: i8 [-128; 127] to [0; 255]`) and vice versa.
I originally created a version that worked directly on the signed numbers but the code was "ugly" and not understandable. Despite this mapping "overhead" the codegen is better than my most optimized version on signed integers.

~~Note that in the case of unsigned numbers I tried to be smart and used `#[cfg(target_pointer_width = "64")]` to determine if using the wide version was better or not by looking at the assembly on godbolt. This was applied to `u32`, `u64` and `usize` and doesn't change the behavior only the assembly code generated.~~
2023-05-14 19:33:02 +00:00
..
fmt Update format_args!() test to account for inlining. 2023-03-16 11:21:50 +01:00
hash fix library and rustdoc tests 2023-04-16 11:38:52 +00:00
iter Revert "Mark DoubleEndedIterator as #[const_trait] using rustc_do_not_const_check, implement const Iterator and DoubleEndedIterator for Range." 2023-04-08 08:18:29 +00:00
net Move IpAddr and SocketAddr to core 2023-02-26 13:50:08 +01:00
num Auto merge of #92048 - Urgau:num-midpoint, r=scottmcm 2023-05-14 19:33:02 +00:00
ops Expand the docs for ops::ControlFlow a bit 2021-02-06 22:36:05 -08:00
panic Fix test (location_const_file) 2022-10-08 11:48:53 +00:00
alloc.rs Re-optimize Layout::array 2022-07-13 17:07:41 -07:00
any.rs Update bootstrap cfg 2022-12-28 09:18:43 -05:00
array.rs replace advance_by returning usize with Result<(), NonZeroUsize> 2023-03-27 16:03:14 +02:00
ascii.rs introduce {char, u8}::is_ascii_octdigit 2022-09-27 11:55:13 +05:30
asserting.rs Spelling library/ 2023-04-26 02:10:22 -04:00
atomic.rs fix library and rustdoc tests 2023-04-16 11:38:52 +00:00
bool.rs fix library and rustdoc tests 2023-04-16 11:38:52 +00:00
cell.rs fix library and rustdoc tests 2023-04-16 11:38:52 +00:00
char.rs fix library and rustdoc tests 2023-04-16 11:38:52 +00:00
clone.rs fix rustdoc and core test 2023-04-29 08:50:56 +00:00
cmp.rs fix library and rustdoc tests 2023-04-16 11:38:52 +00: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
future.rs add tests 2022-02-02 23:07:02 +09:00
intrinsics.rs Switch bootstrap cfgs 2022-02-25 08:00:52 -05:00
lazy.rs Rollup merge of #110419 - jsoref:spelling-library, r=jyn514 2023-04-26 18:51:41 +02:00
lib.rs Auto merge of #92048 - Urgau:num-midpoint, r=scottmcm 2023-05-14 19:33:02 +00:00
macros.rs Allow leading pipe in matches!() patterns. 2021-07-15 22:05:45 +03:00
manually_drop.rs Test ManuallyDrop::clone_from. 2021-07-05 11:55:45 +00:00
mem.rs major test improvements 2023-04-21 02:45:48 -07:00
nonzero.rs Implement Neg for signed non-zero integers. 2023-04-20 14:27:29 +09:00
ops.rs Test not never 2021-11-21 19:10:39 -08:00
option.rs fix library and rustdoc tests 2023-04-16 11:38:52 +00: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.rs Make some methods of Pin<&mut T> unstable const 2020-09-18 19:23:50 +02:00
pin_macro.rs Write {ui,} tests for pin_macro and pin! 2022-02-14 16:56:37 +01:00
ptr.rs avoid mixing accesses of ptrs derived from a mutable ref and parent ptrs 2023-02-12 15:16:27 +01:00
result.rs Remove unstable Result::into_ok_or_err 2022-08-17 17:20:42 -07:00
simd.rs Introduce core::simd trait imports in tests 2022-07-20 18:08:20 -07:00
slice.rs replace advance_by returning usize with Result<(), NonZeroUsize> 2023-03-27 16:03:14 +02:00
str.rs Update paths in comments. 2022-12-30 14:00:42 +01:00
str_lossy.rs Expose Utf8Lossy as Utf8Chunks 2022-08-20 12:49:20 -04:00
task.rs Remove test of static Context 2023-01-02 10:33:23 -08:00
time.rs fix library and rustdoc tests 2023-04-16 11:38:52 +00: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 libcore tests: avoid int2ptr casts 2022-06-27 13:30:44 -04:00