fixed_bigint/
patch_num_traits.rs1pub trait OverflowingShl: Sized {
17 fn overflowing_shl(self, rhs: u32) -> (Self, bool);
18}
19pub trait OverflowingShr: Sized {
20 fn overflowing_shr(self, rhs: u32) -> (Self, bool);
21}
22
23macro_rules! overflowing_shift_impl {
24 ($trait_name:ident, $method:ident, $t:ty) => {
25 impl $trait_name for $t {
26 #[inline]
27 fn $method(self, rhs: u32) -> ($t, bool) {
28 <$t>::$method(self, rhs)
29 }
30 }
31 };
32}
33
34overflowing_shift_impl!(OverflowingShl, overflowing_shl, u8);
35overflowing_shift_impl!(OverflowingShl, overflowing_shl, u16);
36overflowing_shift_impl!(OverflowingShl, overflowing_shl, u32);
37overflowing_shift_impl!(OverflowingShl, overflowing_shl, u64);
38
39overflowing_shift_impl!(OverflowingShr, overflowing_shr, u8);
40overflowing_shift_impl!(OverflowingShr, overflowing_shr, u16);
41overflowing_shift_impl!(OverflowingShr, overflowing_shr, u32);
42overflowing_shift_impl!(OverflowingShr, overflowing_shr, u64);
43
44pub trait WideningMul: Sized {
51 type Output;
52 fn widening_mul(self, rhs: Self) -> (Self::Output, Self::Output);
56}
57
58macro_rules! widening_mul_impl {
59 ($t:ty, $double:ty, $bits:expr) => {
60 impl WideningMul for $t {
61 type Output = Self;
62 fn widening_mul(self, rhs: Self) -> (Self, Self) {
63 let product = (self as $double) * (rhs as $double);
64 (product as $t, (product >> $bits) as $t)
65 }
66 }
67 impl WideningMul for &$t {
68 type Output = $t;
69 fn widening_mul(self, rhs: Self) -> ($t, $t) {
70 <$t as WideningMul>::widening_mul(*self, *rhs)
71 }
72 }
73 };
74}
75
76widening_mul_impl!(u8, u16, 8);
77widening_mul_impl!(u16, u32, 16);
78widening_mul_impl!(u32, u64, 32);
79widening_mul_impl!(u64, u128, 64);
80
81pub trait CarryingMul: Sized {
88 type Output;
89 fn carrying_mul(self, rhs: Self, carry: Self) -> (Self::Output, Self::Output);
94
95 fn carrying_mul_add(self, rhs: Self, addend: Self, carry: Self)
100 -> (Self::Output, Self::Output);
101}
102
103macro_rules! carrying_mul_impl {
104 ($t:ty, $double:ty, $bits:expr) => {
105 impl CarryingMul for $t {
106 type Output = Self;
107 fn carrying_mul(self, rhs: Self, carry: Self) -> (Self, Self) {
108 let product = (self as $double) * (rhs as $double) + (carry as $double);
109 (product as $t, (product >> $bits) as $t)
110 }
111
112 fn carrying_mul_add(self, rhs: Self, addend: Self, carry: Self) -> (Self, Self) {
113 let product =
114 (self as $double) * (rhs as $double) + (addend as $double) + (carry as $double);
115 (product as $t, (product >> $bits) as $t)
116 }
117 }
118 impl CarryingMul for &$t {
119 type Output = $t;
120 fn carrying_mul(self, rhs: Self, carry: Self) -> ($t, $t) {
121 <$t as CarryingMul>::carrying_mul(*self, *rhs, *carry)
122 }
123 fn carrying_mul_add(self, rhs: Self, addend: Self, carry: Self) -> ($t, $t) {
124 <$t as CarryingMul>::carrying_mul_add(*self, *rhs, *addend, *carry)
125 }
126 }
127 };
128}
129
130carrying_mul_impl!(u8, u16, 8);
131carrying_mul_impl!(u16, u32, 16);
132carrying_mul_impl!(u32, u64, 32);
133carrying_mul_impl!(u64, u128, 64);