radix_common/math/
bnum_integer.rs

1//! Definitions of safe integers and uints.
2
3use crate::math::traits::*;
4
5use bnum::{BInt, BUint};
6use num_bigint::BigInt;
7use num_integer::Roots;
8use num_traits::{FromPrimitive, One, Pow, ToPrimitive, Zero};
9use paste::paste;
10use sbor::rust::cmp::{Ord, PartialEq, PartialOrd};
11use sbor::rust::convert::{From, TryFrom};
12use sbor::rust::fmt;
13use sbor::rust::ops::{Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign};
14use sbor::rust::ops::{BitXor, BitXorAssign, Div, DivAssign};
15use sbor::rust::ops::{Mul, MulAssign, Neg, Not, Rem, RemAssign};
16use sbor::rust::ops::{Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign};
17use sbor::rust::str::FromStr;
18use sbor::rust::string::*;
19use sbor::rust::vec::Vec;
20
21pub mod bits;
22pub mod convert;
23pub mod test;
24pub mod test_macros;
25
26macro_rules! types {
27    ($($t:ident, $wrap:ty),*) => {
28        paste!{
29            $(
30                /// Provides safe integer arithmetic.
31                ///
32                /// Operations like `+`, '-', '*', or '/' sometimes produce overflow
33                /// which is detected and results in a panic, in of silently
34                /// wrapping around.
35                ///
36                /// The bit length of output type will be the greater one in the math operation,
37                /// and if any of the types was signed, then the resulting type will be signed too,
38                /// otherwise the output type is unsigned.
39                ///
40                /// The underlying value can be retrieved through the `.0` index of the
41                #[doc = "`" $t "` tuple."]
42                ///
43                /// # Layout
44                ///
45                #[doc = "`" $t "` will have the same methods and traits as"]
46                /// the built-in counterpart.
47                #[cfg_attr(
48                    feature = "fuzzing",
49                    derive(::arbitrary::Arbitrary, ::serde::Serialize, ::serde::Deserialize)
50                )]
51                #[derive(Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
52                #[repr(transparent)]
53                pub struct $t(pub $wrap);
54
55                impl $t {
56                    pub const MIN: Self = Self($wrap::MIN);
57                    pub const MAX: Self = Self($wrap::MAX);
58                    pub const ZERO: Self = Self($wrap::ZERO);
59                    pub const ONE: Self = Self($wrap::ONE);
60                    pub const TEN: Self = Self($wrap::TEN);
61                    pub const BITS: u32 = $wrap::BITS as u32;
62                    pub const BYTES: u32 = $wrap::BYTES as u32;
63                    pub const N: usize = ($wrap::BYTES / 8) as usize;
64                }
65
66                impl Default for $t {
67                    fn default() -> Self {
68                        Self::ZERO
69                    }
70                }
71
72                impl fmt::Debug for $t {
73                    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74                        self.0.fmt(f)
75                    }
76                }
77
78                impl fmt::Display for $t {
79                    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80                        self.0.fmt(f)
81                    }
82                }
83
84                impl Zero for $t {
85                    fn zero() -> Self {
86                        Self::ZERO
87                    }
88
89                    fn is_zero(&self) -> bool {
90                        $wrap::ZERO == self.0
91                    }
92
93                    fn set_zero(&mut self) {
94                        self.0 = $wrap::ZERO;
95                    }
96                }
97
98                impl One for $t {
99                    fn one() -> Self {
100                        Self::ONE
101                    }
102                }
103            )*
104        }
105    };
106}
107types! {
108    I192, BInt::<3>,
109    I256, BInt::<4>,
110    I320, BInt::<5>,
111    I384, BInt::<6>,
112    I448, BInt::<7>,
113    I512, BInt::<8>,
114    I768, BInt::<12>,
115    U192, BUint::<3>,
116    U256, BUint::<4>,
117    U320, BUint::<5>,
118    U384, BUint::<6>,
119    U448, BUint::<7>,
120    U512, BUint::<8>,
121    U768, BUint::<12>
122}
123
124pub trait Sqrt {
125    fn sqrt(self) -> Self;
126}
127
128pub trait Cbrt {
129    fn cbrt(self) -> Self;
130}
131
132pub trait NthRoot {
133    fn nth_root(self, n: u32) -> Self;
134}
135
136macro_rules! forward_ref_unop {
137    (impl $imp:ident, $method:ident for $t:ty) => {
138        impl $imp for &$t {
139            type Output = <$t as $imp>::Output;
140
141            #[inline]
142            fn $method(self) -> <$t as $imp>::Output {
143                $imp::$method(*self)
144            }
145        }
146    };
147}
148
149macro_rules! forward_ref_binop {
150    (impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
151        impl<'a> $imp<$u> for &'a $t {
152            type Output = <$t as $imp<$u>>::Output;
153
154            #[inline]
155            fn $method(self, other: $u) -> <$t as $imp<$u>>::Output {
156                $imp::$method(*self, other)
157            }
158        }
159
160        impl $imp<&$u> for $t {
161            type Output = <$t as $imp<$u>>::Output;
162
163            #[inline]
164            fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output {
165                $imp::$method(self, *other)
166            }
167        }
168
169        impl $imp<&$u> for &$t {
170            type Output = <$t as $imp<$u>>::Output;
171
172            #[inline]
173            fn $method(self, other: &$u) -> <$t as $imp<$u>>::Output {
174                $imp::$method(*self, *other)
175            }
176        }
177    };
178}
179
180macro_rules! forward_ref_op_assign {
181    (impl $imp:ident, $method:ident for $t:ty, $u:ty) => {
182        impl $imp<&$u> for $t {
183            #[inline]
184            fn $method(&mut self, other: &$u) {
185                $imp::$method(self, *other);
186            }
187        }
188    };
189}
190
191macro_rules! op_impl {
192    ($($t:ty),*) => {
193        paste! {
194            $(
195                impl Add for $t {
196                    type Output = $t;
197
198                    #[inline]
199                    fn add(self, other: $t) -> Self {
200                        Self(self.0.checked_add(other.0).expect("Overflow"))
201                    }
202                }
203                forward_ref_binop! { impl Add, add for $t, $t }
204
205                impl AddAssign for $t {
206                    #[inline]
207                    fn add_assign(&mut self, other: $t) {
208                        self.0 = self.0.checked_add(other.0).expect("Overflow");
209                    }
210                }
211                forward_ref_op_assign! { impl AddAssign, add_assign for $t, $t }
212
213                impl Sub for $t {
214                    type Output = $t;
215
216                    #[inline]
217                    fn sub(self, other: $t) -> Self {
218                        Self(self.0.checked_sub(other.0).expect("Overflow"))
219                    }
220                }
221                forward_ref_binop! { impl Sub, sub for $t, $t }
222
223                impl SubAssign for $t {
224                    #[inline]
225                    fn sub_assign(&mut self, other: $t) {
226                        self.0 = self.0.checked_sub(other.0).expect("Overflow");
227                    }
228                }
229                forward_ref_op_assign! { impl SubAssign, sub_assign for $t, $t }
230
231                impl Mul for $t {
232                    type Output = $t;
233
234                    #[inline]
235                    fn mul(self, other: $t) -> Self {
236                        Self(self.0.checked_mul(other.0).expect("Overflow"))
237                    }
238                }
239                forward_ref_binop! { impl Mul, mul for $t, $t }
240
241                impl MulAssign for $t {
242                    #[inline]
243                    fn mul_assign(&mut self, other: $t) {
244                        self.0 = self.0.checked_mul(other.0).expect("Overflow");
245                    }
246                }
247                forward_ref_op_assign! { impl MulAssign, mul_assign for $t, $t }
248
249                impl Div for $t {
250                    type Output = $t;
251
252                    #[inline]
253                    fn div(self, other: $t) -> Self {
254                        Self(self.0.checked_div(other.0).expect("Overflow"))
255                    }
256                }
257                forward_ref_binop! { impl Div, div for $t, $t }
258
259                impl DivAssign for $t {
260                    #[inline]
261                    fn div_assign(&mut self, other: $t) {
262                        self.0 = self.0.checked_div(other.0).expect("Overflow");
263                    }
264                }
265                forward_ref_op_assign! { impl DivAssign, div_assign for $t, $t }
266
267                impl Rem for $t {
268                    type Output = $t;
269
270                    #[inline]
271                    fn rem(self, other: $t) -> Self {
272                        Self(self.0 % other.0)
273                    }
274                }
275                forward_ref_binop! { impl Rem, rem for $t, $t }
276
277                impl RemAssign for $t {
278                    #[inline]
279                    fn rem_assign(&mut self, other: $t) {
280                        self.0 = self.0 % other.0;
281                    }
282                }
283                forward_ref_op_assign! { impl RemAssign, rem_assign for $t, $t }
284
285                impl Not for $t {
286                    type Output = $t;
287
288                    #[inline]
289                    fn not(self) -> Self {
290                        Self(!self.0)
291                    }
292                }
293                forward_ref_unop! { impl Not, not for $t }
294
295                impl Pow<u32> for $t
296                {
297                    type Output = $t;
298
299                    /// Raises self to the power of `exp`, using exponentiation by squaring.
300                    ///
301                    #[inline]
302
303                    fn pow(self, exp: u32) -> Self {
304                        Self(self.0.checked_pow(exp).expect("Overflow"))
305                    }
306                }
307
308                impl Sqrt for $t
309                {
310                    fn sqrt(self) -> Self {
311                        Self(self.0.sqrt())
312                    }
313                }
314
315                impl Cbrt for $t
316                {
317                    fn cbrt(self) -> Self {
318                        Self(self.0.cbrt())
319                    }
320                }
321
322                impl NthRoot for $t
323                {
324                    fn nth_root(self, n: u32) -> Self {
325                        Self(self.0.nth_root(n))
326                    }
327                }
328
329                impl CheckedAdd for $t
330                {
331                    type Output = $t;
332
333                    fn checked_add(self, other: Self) -> Option<Self::Output> {
334                        let opt = self.0.checked_add(other.0);
335                        opt.map(|v| Self(v))
336                    }
337                }
338
339                impl SaturatingAdd for $t
340                {
341                    type Output = $t;
342
343                    fn saturating_add(self, other: Self) -> Self::Output {
344                        Self(self.0.saturating_add(other.0))
345                    }
346                }
347
348                impl CheckedSub for $t
349                {
350                    type Output = $t;
351
352                    fn checked_sub(self, other: Self) -> Option<Self::Output> {
353                        let opt = self.0.checked_sub(other.0);
354                        opt.map(|v| Self(v))
355                    }
356                }
357
358                impl CheckedMul for $t
359                {
360                    type Output = $t;
361
362                    fn checked_mul(self, other: Self) -> Option<Self::Output> {
363                        let opt = self.0.checked_mul(other.0);
364                        opt.map(|v| Self(v))
365                    }
366                }
367
368                impl CheckedDiv for $t
369                {
370                    type Output = $t;
371
372                    fn checked_div(self, other: Self) -> Option<Self::Output> {
373                        let opt = self.0.checked_div(other.0);
374                        opt.map(|v| Self(v))
375                    }
376                }
377            )*
378        }
379    };
380}
381op_impl! { I192 }
382op_impl! { I256 }
383op_impl! { I320 }
384op_impl! { I384 }
385op_impl! { I448 }
386op_impl! { I512 }
387op_impl! { I768 }
388op_impl! { U192 }
389op_impl! { U256 }
390op_impl! { U320 }
391op_impl! { U384 }
392op_impl! { U448 }
393op_impl! { U512 }
394op_impl! { U768 }
395
396macro_rules! op_impl_unsigned {
397    ($($t:ty),*) => {
398        paste! {
399            $(
400                impl $t {
401                    pub fn is_power_of_two(self) -> bool {
402                        self.0.is_power_of_two()
403                    }
404
405                    pub fn next_power_of_two(self) -> Self {
406                        Self(self.0.checked_next_power_of_two().expect("Overflow"))
407                    }
408                }
409            )*
410        }
411    };
412}
413op_impl_unsigned! { U192 }
414op_impl_unsigned! { U256 }
415op_impl_unsigned! { U320 }
416op_impl_unsigned! { U384 }
417op_impl_unsigned! { U448 }
418op_impl_unsigned! { U512 }
419op_impl_unsigned! { U768 }
420
421macro_rules! op_impl_signed {
422    ($($t:ty),*) => {
423        paste! {
424            $(
425                impl Neg for $t {
426                    type Output = Self;
427                    #[inline]
428                    fn neg(self) -> Self {
429                        Self(self.0.neg())
430                    }
431                }
432
433                impl CheckedNeg for $t {
434                    type Output = Self;
435
436                    #[inline]
437                    fn checked_neg(self) -> Option<Self::Output> {
438                        let c = self.0.checked_neg();
439                        c.map(Self)
440                    }
441                }
442
443
444                impl $t {
445
446                    /// Computes the absolute value of `self`, with overflow causing panic.
447                    ///
448                    /// The only case where such overflow can occur is when one takes the absolute value of the negative
449                    /// minimal value for the type this is a positive value that is too large to represent in the type. In
450                    /// such a case, this function panics.
451                    ///
452                    #[inline]
453                    #[must_use = "this returns the result of the operation, \
454                      without modifying the original"]
455                    pub fn abs(self) -> Self {
456                        Self(self.0.abs())
457                    }
458
459                    /// Returns a number representing sign of `self`.
460                    ///
461                    ///  - `0` if the number is zero
462                    ///  - `1` if the number is positive
463                    ///  - `-1` if the number is negative
464                    ///
465                    #[inline]
466                    #[must_use = "this returns the result of the operation, \
467                          without modifying the original"]
468                    pub fn signum(self) -> Self {
469                        Self(self.0.signum())
470                    }
471
472                    /// Returns `true` if `self` is positive and `false` if the number is zero or
473                    /// negative.
474                    ///
475                    #[must_use]
476                    #[inline]
477                    pub fn is_positive(self) -> bool {
478                        self.0.is_positive()
479                    }
480
481                    /// Returns `true` if `self` is negative and `false` if the number is zero or
482                    /// positive.
483                    ///
484                    #[must_use]
485                    #[inline]
486                    pub fn is_negative(self) -> bool {
487                        self.0.is_negative()
488                    }
489                }
490            )*
491        }
492    }
493}
494
495op_impl_signed! { I192 }
496op_impl_signed! { I256 }
497op_impl_signed! { I320 }
498op_impl_signed! { I384 }
499op_impl_signed! { I448 }
500op_impl_signed! { I512 }
501op_impl_signed! { I768 }
502
503macro_rules! error {
504    ($($t:ident),*) => {
505        paste! {
506            $(
507                #[derive(Debug, Clone, PartialEq, Eq)]
508                pub enum [<Parse $t Error>] {
509                    NegativeToUnsigned,
510                    InvalidLength,
511                    InvalidDigit,
512                    Empty,
513                    Overflow,
514                }
515
516                #[cfg(not(feature = "alloc"))]
517                impl std::error::Error for [<Parse $t Error>] {}
518
519                #[cfg(not(feature = "alloc"))]
520                impl fmt::Display for [<Parse $t Error>] {
521                    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
522                        write!(f, "{:?}", self)
523                    }
524                }
525            )*
526        }
527    };
528}
529error! {
530    I192,
531    I256,
532    I320,
533    I384,
534    I448,
535    I512,
536    I768,
537    U192,
538    U256,
539    U320,
540    U384,
541    U448,
542    U512,
543    U768
544}