concrete_commons/numeric/
unsigned.rs1use std::ops::{
2 Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
3 Mul, MulAssign, Not, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
4};
5
6use crate::numeric::CastInto;
7
8use super::{CastFrom, Numeric, SignedInteger};
9
10pub trait UnsignedInteger:
12 Numeric
13 + Ord
14 + Eq
15 + Add<Self, Output = Self>
16 + AddAssign<Self>
17 + Div<Self, Output = Self>
18 + DivAssign<Self>
19 + Mul<Self, Output = Self>
20 + MulAssign<Self>
21 + Rem<Self, Output = Self>
22 + RemAssign<Self>
23 + Sub<Self, Output = Self>
24 + SubAssign<Self>
25 + BitAnd<Self, Output = Self>
26 + BitAndAssign<Self>
27 + BitOr<Self, Output = Self>
28 + BitOrAssign<Self>
29 + BitXor<Self, Output = Self>
30 + BitXorAssign<Self>
31 + Not<Output = Self>
32 + Shl<usize, Output = Self>
33 + ShlAssign<usize>
34 + Shr<usize, Output = Self>
35 + ShrAssign<usize>
36 + CastFrom<f64>
37 + CastInto<f64>
38{
39 type Signed: SignedInteger<Unsigned = Self> + CastFrom<Self>;
41 #[must_use]
43 fn wrapping_add(self, other: Self) -> Self;
44 #[must_use]
46 fn wrapping_sub(self, other: Self) -> Self;
47 #[must_use]
49 fn wrapping_div(self, other: Self) -> Self;
50 #[must_use]
52 fn wrapping_mul(self, other: Self) -> Self;
53 #[must_use]
55 fn wrapping_neg(self) -> Self;
56 #[must_use]
58 fn wrapping_pow(self, exp: u32) -> Self;
59 #[must_use]
61 fn wrapping_shl(self, rhs: u32) -> Self;
62 #[must_use]
64 fn wrapping_shr(self, rhs: u32) -> Self;
65 fn into_signed(self) -> Self::Signed;
67 fn to_bits_string(&self, block_length: usize) -> String;
70}
71
72macro_rules! implement {
73 ($Type: tt, $SignedType:ty, $bits:expr) => {
74 impl Numeric for $Type {
75 const BITS: usize = $bits;
76 const ZERO: Self = 0;
77 const ONE: Self = 1;
78 const TWO: Self = 2;
79 const MAX: Self = <$Type>::MAX;
80 }
81 impl UnsignedInteger for $Type {
82 type Signed = $SignedType;
83 fn into_signed(self) -> Self::Signed {
84 Self::Signed::cast_from(self)
85 }
86 fn to_bits_string(&self, break_every: usize) -> String {
87 let mut strn = match <$Type as Numeric>::BITS {
88 8 => format!("{:08b}", self),
89 16 => format!("{:016b}", self),
90 32 => format!("{:032b}", self),
91 64 => format!("{:064b}", self),
92 128 => format!("{:0128b}", self),
93 _ => unreachable!(),
94 };
95 for i in (1..(<$Type as Numeric>::BITS / break_every)).rev() {
96 strn.insert(i * break_every, ' ');
97 }
98 strn
99 }
100 fn wrapping_add(self, other: Self) -> Self {
101 self.wrapping_add(other)
102 }
103 fn wrapping_sub(self, other: Self) -> Self {
104 self.wrapping_sub(other)
105 }
106 fn wrapping_div(self, other: Self) -> Self {
107 self.wrapping_div(other)
108 }
109 fn wrapping_mul(self, other: Self) -> Self {
110 self.wrapping_mul(other)
111 }
112 fn wrapping_neg(self) -> Self {
113 self.wrapping_neg()
114 }
115 fn wrapping_shl(self, rhs: u32) -> Self {
116 self.wrapping_shl(rhs)
117 }
118 fn wrapping_shr(self, rhs: u32) -> Self {
119 self.wrapping_shr(rhs)
120 }
121 fn wrapping_pow(self, exp: u32) -> Self {
122 self.wrapping_pow(exp)
123 }
124 }
125 };
126}
127
128implement!(u8, i8, 8);
129implement!(u16, i16, 16);
130implement!(u32, i32, 32);
131implement!(u64, i64, 64);
132implement!(u128, i128, 128);
133
134#[cfg(test)]
135mod test {
136 use super::*;
137
138 #[test]
139 fn test_uint8_binary_rep() {
140 let a: u8 = 100;
141 let b = a.to_bits_string(4);
142 assert_eq!(b, "0110 0100".to_string());
143 }
144
145 #[test]
146 fn test_uint16_binary_rep() {
147 let a: u16 = 25702;
148 let b = a.to_bits_string(4);
149 assert_eq!(b, "0110 0100 0110 0110".to_string());
150 }
151
152 #[test]
153 fn test_uint32_binary_rep() {
154 let a: u32 = 1684411356;
155 let b = a.to_bits_string(4);
156 assert_eq!(b, "0110 0100 0110 0110 0001 0011 1101 1100".to_string());
157 }
158
159 #[test]
160 fn test_uint64_binary_rep() {
161 let a: u64 = 7_234_491_689_707_068_824;
162 let b = a.to_bits_string(4);
163 assert_eq!(
164 b,
165 "0110 0100 0110 0110 0001 0011 1101 1100 \
166 1001 1111 1000 0001 0101 1101 1001 1000"
167 .to_string()
168 );
169 }
170
171 #[test]
172 fn test_uint128_binary_rep() {
173 let a: u128 = 124_282_366_920_938_463_463_374_121_543_098_288_434;
174 let b = a.to_bits_string(4);
175 assert_eq!(
176 b,
177 "0101 1101 0111 1111 1110 1001 1100 0111 \
178 1000 1110 0110 0010 0000 0101 1011 0000 \
179 1011 1000 0011 0000 0001 0000 1001 0110 \
180 0011 1010 0110 1101 1100 1001 0011 0010"
181 .to_string()
182 );
183 }
184}