Coverage Report

Created: 2026-03-31 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/bnum-0.12.1/src/buint/overflowing.rs
Line
Count
Source
1
use crate::digit;
2
use crate::doc;
3
use crate::ExpType;
4
5
macro_rules! overflowing {
6
    ($BUint: ident, $BInt: ident, $Digit: ident) => {
7
        #[doc = doc::overflowing::impl_desc!()]
8
        impl<const N: usize> $BUint<N> {
9
            #[doc = doc::overflowing::overflowing_add!(U)]
10
            #[must_use = doc::must_use_op!()]
11
            #[inline]
12
0
            pub const fn overflowing_add(self, rhs: Self) -> (Self, bool) {
13
0
                let mut out = Self::ZERO;
14
0
                let mut carry = false;
15
0
                let mut i = 0;
16
0
                while i < N {
17
0
                    let result = digit::$Digit::carrying_add(self.digits[i], rhs.digits[i], carry);
18
0
                    out.digits[i] = result.0;
19
0
                    carry = result.1;
20
0
                    i += 1;
21
0
                }
22
0
                (out, carry)
23
0
            }
Unexecuted instantiation: <bnum::buint::BUint<16>>::overflowing_add
Unexecuted instantiation: <bnum::buint::BUint<17>>::overflowing_add
Unexecuted instantiation: <bnum::buint::BUint<1>>::overflowing_add
Unexecuted instantiation: <bnum::buint::BUint<2>>::overflowing_add
Unexecuted instantiation: <bnum::buint::BUint<3>>::overflowing_add
Unexecuted instantiation: <bnum::buint::BUint<4>>::overflowing_add
Unexecuted instantiation: <bnum::buint::BUint<5>>::overflowing_add
Unexecuted instantiation: <bnum::buint::BUint<6>>::overflowing_add
Unexecuted instantiation: <bnum::buint::BUint<7>>::overflowing_add
Unexecuted instantiation: <bnum::buint::BUint<8>>::overflowing_add
Unexecuted instantiation: <bnum::buint::BUint<9>>::overflowing_add
Unexecuted instantiation: <bnum::buint::BUint<10>>::overflowing_add
Unexecuted instantiation: <bnum::buint::BUint<11>>::overflowing_add
Unexecuted instantiation: <bnum::buint::BUint<12>>::overflowing_add
Unexecuted instantiation: <bnum::buint::BUint<13>>::overflowing_add
Unexecuted instantiation: <bnum::buint::BUint<14>>::overflowing_add
Unexecuted instantiation: <bnum::buint::BUint<15>>::overflowing_add
Unexecuted instantiation: <bnum::buint::BUint<_>>::overflowing_add
Unexecuted instantiation: <bnum::buint::BUintD16<_>>::overflowing_add
Unexecuted instantiation: <bnum::buint::BUintD8<_>>::overflowing_add
Unexecuted instantiation: <bnum::buint::BUintD32<_>>::overflowing_add
24
25
            #[doc = doc::overflowing::overflowing_add_signed!(U)]
26
            #[must_use = doc::must_use_op!()]
27
            #[inline]
28
0
            pub const fn overflowing_add_signed(self, rhs: $BInt<N>) -> (Self, bool) {
29
0
                let (sum, overflow) = self.overflowing_add(rhs.to_bits());
30
0
                (sum, rhs.is_negative() != overflow)
31
0
            }
Unexecuted instantiation: <bnum::buint::BUint<_>>::overflowing_add_signed
Unexecuted instantiation: <bnum::buint::BUintD16<_>>::overflowing_add_signed
Unexecuted instantiation: <bnum::buint::BUintD8<_>>::overflowing_add_signed
Unexecuted instantiation: <bnum::buint::BUintD32<_>>::overflowing_add_signed
32
33
            #[doc = doc::overflowing::overflowing_sub!(U)]
34
            #[must_use = doc::must_use_op!()]
35
            #[inline]
36
0
            pub const fn overflowing_sub(self, rhs: Self) -> (Self, bool) {
37
0
                let mut out = Self::ZERO;
38
0
                let mut borrow = false;
39
0
                let mut i = 0;
40
0
                while i < N {
41
0
                    let result =
42
0
                        digit::$Digit::borrowing_sub(self.digits[i], rhs.digits[i], borrow);
43
0
                    out.digits[i] = result.0;
44
0
                    borrow = result.1;
45
0
                    i += 1;
46
0
                }
47
0
                (out, borrow)
48
0
            }
Unexecuted instantiation: <bnum::buint::BUint<16>>::overflowing_sub
Unexecuted instantiation: <bnum::buint::BUint<17>>::overflowing_sub
Unexecuted instantiation: <bnum::buint::BUint<1>>::overflowing_sub
Unexecuted instantiation: <bnum::buint::BUint<2>>::overflowing_sub
Unexecuted instantiation: <bnum::buint::BUint<3>>::overflowing_sub
Unexecuted instantiation: <bnum::buint::BUint<4>>::overflowing_sub
Unexecuted instantiation: <bnum::buint::BUint<5>>::overflowing_sub
Unexecuted instantiation: <bnum::buint::BUint<6>>::overflowing_sub
Unexecuted instantiation: <bnum::buint::BUint<7>>::overflowing_sub
Unexecuted instantiation: <bnum::buint::BUint<8>>::overflowing_sub
Unexecuted instantiation: <bnum::buint::BUint<9>>::overflowing_sub
Unexecuted instantiation: <bnum::buint::BUint<10>>::overflowing_sub
Unexecuted instantiation: <bnum::buint::BUint<11>>::overflowing_sub
Unexecuted instantiation: <bnum::buint::BUint<12>>::overflowing_sub
Unexecuted instantiation: <bnum::buint::BUint<13>>::overflowing_sub
Unexecuted instantiation: <bnum::buint::BUint<14>>::overflowing_sub
Unexecuted instantiation: <bnum::buint::BUint<15>>::overflowing_sub
Unexecuted instantiation: <bnum::buint::BUint<_>>::overflowing_sub
Unexecuted instantiation: <bnum::buint::BUintD16<_>>::overflowing_sub
Unexecuted instantiation: <bnum::buint::BUintD8<_>>::overflowing_sub
Unexecuted instantiation: <bnum::buint::BUintD32<_>>::overflowing_sub
49
50
            #[doc = doc::overflowing::overflowing_mul!(U)]
51
            #[must_use = doc::must_use_op!()]
52
            #[inline]
53
0
            pub const fn overflowing_mul(self, rhs: Self) -> (Self, bool) {
54
                // TODO: implement a faster multiplication algorithm for large values of `N`
55
0
                self.long_mul(rhs)
56
0
            }
Unexecuted instantiation: <bnum::buint::BUint<16>>::overflowing_mul
Unexecuted instantiation: <bnum::buint::BUint<17>>::overflowing_mul
Unexecuted instantiation: <bnum::buint::BUint<2>>::overflowing_mul
Unexecuted instantiation: <bnum::buint::BUint<3>>::overflowing_mul
Unexecuted instantiation: <bnum::buint::BUint<4>>::overflowing_mul
Unexecuted instantiation: <bnum::buint::BUint<5>>::overflowing_mul
Unexecuted instantiation: <bnum::buint::BUint<6>>::overflowing_mul
Unexecuted instantiation: <bnum::buint::BUint<7>>::overflowing_mul
Unexecuted instantiation: <bnum::buint::BUint<8>>::overflowing_mul
Unexecuted instantiation: <bnum::buint::BUint<9>>::overflowing_mul
Unexecuted instantiation: <bnum::buint::BUint<10>>::overflowing_mul
Unexecuted instantiation: <bnum::buint::BUint<11>>::overflowing_mul
Unexecuted instantiation: <bnum::buint::BUint<12>>::overflowing_mul
Unexecuted instantiation: <bnum::buint::BUint<13>>::overflowing_mul
Unexecuted instantiation: <bnum::buint::BUint<14>>::overflowing_mul
Unexecuted instantiation: <bnum::buint::BUint<15>>::overflowing_mul
Unexecuted instantiation: <bnum::buint::BUint<_>>::overflowing_mul
Unexecuted instantiation: <bnum::buint::BUintD16<_>>::overflowing_mul
Unexecuted instantiation: <bnum::buint::BUintD8<_>>::overflowing_mul
Unexecuted instantiation: <bnum::buint::BUintD32<_>>::overflowing_mul
57
58
            #[doc = doc::overflowing::overflowing_div!(U)]
59
            #[must_use = doc::must_use_op!()]
60
            #[inline]
61
0
            pub const fn overflowing_div(self, rhs: Self) -> (Self, bool) {
62
0
                (self.wrapping_div(rhs), false)
63
0
            }
Unexecuted instantiation: <bnum::buint::BUint<_>>::overflowing_div
Unexecuted instantiation: <bnum::buint::BUintD16<_>>::overflowing_div
Unexecuted instantiation: <bnum::buint::BUintD8<_>>::overflowing_div
Unexecuted instantiation: <bnum::buint::BUintD32<_>>::overflowing_div
64
65
            #[doc = doc::overflowing::overflowing_div_euclid!(U)]
66
            #[must_use = doc::must_use_op!()]
67
            #[inline]
68
0
            pub const fn overflowing_div_euclid(self, rhs: Self) -> (Self, bool) {
69
0
                self.overflowing_div(rhs)
70
0
            }
Unexecuted instantiation: <bnum::buint::BUint<_>>::overflowing_div_euclid
Unexecuted instantiation: <bnum::buint::BUintD16<_>>::overflowing_div_euclid
Unexecuted instantiation: <bnum::buint::BUintD8<_>>::overflowing_div_euclid
Unexecuted instantiation: <bnum::buint::BUintD32<_>>::overflowing_div_euclid
71
72
            #[doc = doc::overflowing::overflowing_rem!(U)]
73
            #[must_use = doc::must_use_op!()]
74
            #[inline]
75
0
            pub const fn overflowing_rem(self, rhs: Self) -> (Self, bool) {
76
0
                (self.wrapping_rem(rhs), false)
77
0
            }
Unexecuted instantiation: <bnum::buint::BUint<_>>::overflowing_rem
Unexecuted instantiation: <bnum::buint::BUintD16<_>>::overflowing_rem
Unexecuted instantiation: <bnum::buint::BUintD8<_>>::overflowing_rem
Unexecuted instantiation: <bnum::buint::BUintD32<_>>::overflowing_rem
78
79
            #[doc = doc::overflowing::overflowing_rem_euclid!(U)]
80
            #[must_use = doc::must_use_op!()]
81
            #[inline]
82
0
            pub const fn overflowing_rem_euclid(self, rhs: Self) -> (Self, bool) {
83
0
                self.overflowing_rem(rhs)
84
0
            }
Unexecuted instantiation: <bnum::buint::BUint<_>>::overflowing_rem_euclid
Unexecuted instantiation: <bnum::buint::BUintD16<_>>::overflowing_rem_euclid
Unexecuted instantiation: <bnum::buint::BUintD8<_>>::overflowing_rem_euclid
Unexecuted instantiation: <bnum::buint::BUintD32<_>>::overflowing_rem_euclid
85
86
            #[doc = doc::overflowing::overflowing_neg!(U)]
87
            #[must_use = doc::must_use_op!()]
88
            #[inline]
89
0
            pub const fn overflowing_neg(self) -> (Self, bool) {
90
0
                let (a, b) = (self.not()).overflowing_add(Self::ONE);
91
0
                (a, !b)
92
0
            }
Unexecuted instantiation: <bnum::buint::BUint<_>>::overflowing_neg
Unexecuted instantiation: <bnum::buint::BUintD16<_>>::overflowing_neg
Unexecuted instantiation: <bnum::buint::BUintD8<_>>::overflowing_neg
Unexecuted instantiation: <bnum::buint::BUintD32<_>>::overflowing_neg
93
94
            #[doc = doc::overflowing::overflowing_shl!(U)]
95
            #[must_use = doc::must_use_op!()]
96
            #[inline]
97
0
            pub const fn overflowing_shl(self, rhs: ExpType) -> (Self, bool) {
98
                unsafe {
99
0
                    if rhs >= Self::BITS {
100
0
                        (
101
0
                            Self::unchecked_shl_internal(self, rhs & (Self::BITS - 1)),
102
0
                            true,
103
0
                        )
104
                    } else {
105
0
                        (Self::unchecked_shl_internal(self, rhs), false)
106
                    }
107
                }
108
0
            }
Unexecuted instantiation: <bnum::buint::BUint<2>>::overflowing_shl
Unexecuted instantiation: <bnum::buint::BUint<_>>::overflowing_shl
Unexecuted instantiation: <bnum::buint::BUintD16<_>>::overflowing_shl
Unexecuted instantiation: <bnum::buint::BUintD8<_>>::overflowing_shl
Unexecuted instantiation: <bnum::buint::BUintD32<_>>::overflowing_shl
109
110
            #[doc = doc::overflowing::overflowing_shr!(U)]
111
            #[must_use = doc::must_use_op!()]
112
            #[inline]
113
0
            pub const fn overflowing_shr(self, rhs: ExpType) -> (Self, bool) {
114
                unsafe {
115
0
                    if rhs >= Self::BITS {
116
0
                        (
117
0
                            Self::unchecked_shr_internal(self, rhs & (Self::BITS - 1)),
118
0
                            true,
119
0
                        )
120
                    } else {
121
0
                        (Self::unchecked_shr_internal(self, rhs), false)
122
                    }
123
                }
124
0
            }
Unexecuted instantiation: <bnum::buint::BUint<16>>::overflowing_shr
Unexecuted instantiation: <bnum::buint::BUint<17>>::overflowing_shr
Unexecuted instantiation: <bnum::buint::BUint<3>>::overflowing_shr
Unexecuted instantiation: <bnum::buint::BUint<4>>::overflowing_shr
Unexecuted instantiation: <bnum::buint::BUint<5>>::overflowing_shr
Unexecuted instantiation: <bnum::buint::BUint<6>>::overflowing_shr
Unexecuted instantiation: <bnum::buint::BUint<7>>::overflowing_shr
Unexecuted instantiation: <bnum::buint::BUint<8>>::overflowing_shr
Unexecuted instantiation: <bnum::buint::BUint<9>>::overflowing_shr
Unexecuted instantiation: <bnum::buint::BUint<10>>::overflowing_shr
Unexecuted instantiation: <bnum::buint::BUint<11>>::overflowing_shr
Unexecuted instantiation: <bnum::buint::BUint<12>>::overflowing_shr
Unexecuted instantiation: <bnum::buint::BUint<13>>::overflowing_shr
Unexecuted instantiation: <bnum::buint::BUint<14>>::overflowing_shr
Unexecuted instantiation: <bnum::buint::BUint<15>>::overflowing_shr
Unexecuted instantiation: <bnum::buint::BUint<_>>::overflowing_shr
Unexecuted instantiation: <bnum::buint::BUintD16<_>>::overflowing_shr
Unexecuted instantiation: <bnum::buint::BUintD8<_>>::overflowing_shr
Unexecuted instantiation: <bnum::buint::BUintD32<_>>::overflowing_shr
125
126
            #[doc = doc::overflowing::overflowing_pow!(U)]
127
            #[must_use = doc::must_use_op!()]
128
            #[inline]
129
0
            pub const fn overflowing_pow(mut self, mut pow: ExpType) -> (Self, bool) {
130
                // exponentiation by squaring
131
0
                if pow == 0 {
132
0
                    return (Self::ONE, false);
133
0
                }
134
0
                let mut overflow = false;
135
0
                let mut y = Self::ONE;
136
0
                while pow > 1 {
137
0
                    if pow & 1 == 1 {
138
0
                        let (prod, o) = y.overflowing_mul(self);
139
0
                        overflow |= o;
140
0
                        y = prod;
141
0
                    }
142
0
                    let (prod, o) = self.overflowing_mul(self);
143
0
                    overflow |= o;
144
0
                    self = prod;
145
0
                    pow >>= 1;
146
                }
147
0
                let (prod, o) = self.overflowing_mul(y);
148
0
                (prod, o || overflow)
149
0
            }
Unexecuted instantiation: <bnum::buint::BUint<_>>::overflowing_pow
Unexecuted instantiation: <bnum::buint::BUintD16<_>>::overflowing_pow
Unexecuted instantiation: <bnum::buint::BUintD8<_>>::overflowing_pow
Unexecuted instantiation: <bnum::buint::BUintD32<_>>::overflowing_pow
150
        }
151
    };
152
}
153
154
#[cfg(test)]
155
crate::test::all_digit_tests! {
156
    use crate::test::{test_bignum, types::utest};
157
158
    test_bignum! {
159
        function: <utest>::overflowing_add(a: utest, b: utest)
160
    }
161
    test_bignum! {
162
        function: <utest>::overflowing_sub(a: utest, b: utest)
163
    }
164
    test_bignum! {
165
        function: <utest>::overflowing_mul(a: utest, b: utest)
166
    }
167
    test_bignum! {
168
        function: <utest>::overflowing_div(a: utest, b: utest),
169
        skip: b == 0
170
    }
171
    test_bignum! {
172
        function: <utest>::overflowing_div_euclid(a: utest, b: utest),
173
        skip: b == 0
174
    }
175
    test_bignum! {
176
        function: <utest>::overflowing_rem(a: utest, b: utest),
177
        skip: b == 0
178
    }
179
    test_bignum! {
180
        function: <utest>::overflowing_rem_euclid(a: utest, b: utest),
181
        skip: b == 0
182
    }
183
    test_bignum! {
184
        function: <utest>::overflowing_neg(a: utest)
185
    }
186
    test_bignum! {
187
        function: <utest>::overflowing_shl(a: utest, b: u16)
188
    }
189
    test_bignum! {
190
        function: <utest>::overflowing_shr(a: utest, b: u16)
191
    }
192
    test_bignum! {
193
        function: <utest>::overflowing_pow(a: utest, b: u16)
194
    }
195
}
196
197
crate::macro_impl!(overflowing);