Skip to content
/ rust Public
forked from rust-lang/rust

Commit aafbb9f

Browse files
authored
Rollup merge of rust-lang#152179 - nickkuk:overflow-direction-note, r=jhpratt
Add documentation note about signed overflow direction In rust-lang#151989 (comment) I noticed that signed overflow direction can be determined by returned wrapped value. It is not very obvious (especially, assuming additional `carry: bool` summand), but it is important if we want to add new leading (signed) limb to big integer in this case. Examples for small summands `x, y: i8` with result extension: | x | y | overflow | result as (u8, i8) | | ---- | ---- | -------- | ------------------ | | -1 | -128 | true | (127, -1) | | 0 | -1 | false | (255, -1) | | 2 | 2 | false | (4, 0) | | 127 | 1 | true | (128, 0) | Here is general proof. 1. Set $s=2^{N-1}$ and let's say `iN::carrying_add(x, y, c)` returns `(result, true)` then $$ \mathrm{result}=\begin{cases} x + y + c + 2s,& x + y + c \le -s-1,\\ x+y+c-2s,& x+y+c\ge s. \end{cases} $$ First case is overflowing below `iN::MIN` and we have $$ \mathrm{result}\ge -s-s+0+2s =0;\qquad \mathrm{result}=x + y + c + 2s\le -s-1+2s = s - 1, $$ so we obtain $[0; s-1]$ which is exactly range of non-negative `iN`. Second case is overflowing above `iN::MAX` and $$ \mathrm{result}=x+y+c-2s\ge s-2s =-s;\qquad \mathrm{result}\le s-1 + s-1+1-2s = -1, $$ that is, $[-s,-1]$ which is exactly range of negative `iN`. 2. Now suppose that `iN::borrowing_sub(x,y,b)` returns `(result, true)` then $$ \mathrm{result}=\begin{cases} x - y - b + 2s,& x - y - b \le -s-1,\\ x - y - b - 2s,& x - y - b\ge s. \end{cases} $$ First case is overflowing below `iN::MIN` and we have $$ \mathrm{result}\ge -s-(s-1)-1+2s =0;\qquad \mathrm{result}=x - y - b + 2s\le -s-1+2s = s - 1. $$ Second case is overflowing above `iN::MAX` and $$ \mathrm{result}=x-y-b-2s\ge s-2s =-s;\qquad \mathrm{result}\le s-1 - (-s) - 0 - 2s = -1. $$
2 parents 9988101 + 689e8c2 commit aafbb9f

1 file changed

Lines changed: 10 additions & 2 deletions

File tree

library/core/src/num/int_macros.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2481,7 +2481,8 @@ macro_rules! int_impl {
24812481
///
24822482
/// Returns a tuple of the addition along with a boolean indicating
24832483
/// whether an arithmetic overflow would occur. If an overflow would have
2484-
/// occurred then the wrapped value is returned.
2484+
/// occurred then the wrapped value is returned (negative if overflowed
2485+
/// above [`MAX`](Self::MAX), non-negative if below [`MIN`](Self::MIN)).
24852486
///
24862487
/// # Examples
24872488
///
@@ -2516,6 +2517,9 @@ macro_rules! int_impl {
25162517
/// The output boolean returned by this method is *not* a carry flag,
25172518
/// and should *not* be added to a more significant word.
25182519
///
2520+
/// If overflow occurred, the wrapped value is returned (negative if overflowed
2521+
/// above [`MAX`](Self::MAX), non-negative if below [`MIN`](Self::MIN)).
2522+
///
25192523
/// If the input carry is false, this method is equivalent to
25202524
/// [`overflowing_add`](Self::overflowing_add).
25212525
///
@@ -2583,7 +2587,8 @@ macro_rules! int_impl {
25832587
/// Calculates `self` - `rhs`.
25842588
///
25852589
/// Returns a tuple of the subtraction along with a boolean indicating whether an arithmetic overflow
2586-
/// would occur. If an overflow would have occurred then the wrapped value is returned.
2590+
/// would occur. If an overflow would have occurred then the wrapped value is returned
2591+
/// (negative if overflowed above [`MAX`](Self::MAX), non-negative if below [`MIN`](Self::MIN)).
25872592
///
25882593
/// # Examples
25892594
///
@@ -2619,6 +2624,9 @@ macro_rules! int_impl {
26192624
/// The output boolean returned by this method is *not* a borrow flag,
26202625
/// and should *not* be subtracted from a more significant word.
26212626
///
2627+
/// If overflow occurred, the wrapped value is returned (negative if overflowed
2628+
/// above [`MAX`](Self::MAX), non-negative if below [`MIN`](Self::MIN)).
2629+
///
26222630
/// If the input borrow is false, this method is equivalent to
26232631
/// [`overflowing_sub`](Self::overflowing_sub).
26242632
///

0 commit comments

Comments
 (0)