1macro_rules! ilog {
2 ($method: ident $(, $base: ident : $ty: ty)?) => {
3 #[doc = doc::$method!(I)]
4 #[must_use = doc::must_use_op!()]
5 #[inline]
6 pub const fn $method(self, $($base : $ty),*) -> ExpType {
7 $(
8 if $base.le(&<$ty>::ONE) {
9 panic!(errors::err_msg!(errors::invalid_log_base!()))
10 }
11 ), *
12 if self.is_negative() {
13 panic!(errors::err_msg!(errors::non_positive_log_message!()))
14 } else {
15 self.bits.$method($($base.bits)?)
16 }
17 }
18 }
19}
20
21#[cfg(debug_assertions)]
22use crate::errors::option_expect;
23
24use crate::digit;
25use crate::ExpType;
26use crate::{doc, errors};
27
28use core::default::Default;
29
30use core::iter::{Iterator, Product, Sum};
31
32macro_rules! mod_impl {
33 ($BUint: ident, $BInt: ident, $Digit: ident) => {
34 #[doc = concat!(" [`", stringify!($BUint), "`].")]
36 #[doc = concat!("[`", stringify!($BUint), "`](crate::", stringify!($BUint), ")")]
39 #[doc = concat!("[`", stringify!($BUint), "`].")]
41 #[doc = doc::arithmetic_doc!($BInt)]
43
44 #[derive(Clone, Copy, Hash, PartialEq, Eq)]
45 #[repr(transparent)]
46 pub struct $BInt<const N: usize> {
47 pub(crate) bits: $BUint<N>,
48 }
49
50 impl<const N: usize> $BInt<N> {
51 #[doc = doc::count_ones!(I 256)]
52 #[must_use = doc::must_use_op!()]
53 #[inline]
54 pub const fn count_ones(self) -> ExpType {
55 self.bits.count_ones()
56 }
57
58 #[doc = doc::count_zeros!(I 256)]
59 #[must_use = doc::must_use_op!()]
60 #[inline]
61 pub const fn count_zeros(self) -> ExpType {
62 self.bits.count_zeros()
63 }
64
65 #[doc = doc::leading_zeros!(I 256)]
66 #[must_use = doc::must_use_op!()]
67 #[inline]
68 pub const fn leading_zeros(self) -> ExpType {
69 self.bits.leading_zeros()
70 }
71
72 #[doc = doc::trailing_zeros!(I 256)]
73 #[must_use = doc::must_use_op!()]
74 #[inline]
75 pub const fn trailing_zeros(self) -> ExpType {
76 self.bits.trailing_zeros()
77 }
78
79 #[doc = doc::leading_ones!(I 256, NEG_ONE)]
80 #[must_use = doc::must_use_op!()]
81 #[inline]
82 pub const fn leading_ones(self) -> ExpType {
83 self.bits.leading_ones()
84 }
85
86 #[doc = doc::trailing_ones!(I 256)]
87 #[must_use = doc::must_use_op!()]
88 #[inline]
89 pub const fn trailing_ones(self) -> ExpType {
90 self.bits.trailing_ones()
91 }
92
93 #[doc = doc::rotate_left!(I 256, "i")]
94 #[must_use = doc::must_use_op!()]
95 #[inline]
96 pub const fn rotate_left(self, n: ExpType) -> Self {
97 Self::from_bits(self.bits.rotate_left(n))
98 }
99
100 #[doc = doc::rotate_right!(I 256, "i")]
101 #[must_use = doc::must_use_op!()]
102 #[inline]
103 pub const fn rotate_right(self, n: ExpType) -> Self {
104 Self::from_bits(self.bits.rotate_right(n))
105 }
106
107 #[doc = doc::swap_bytes!(I 256, "i")]
108 #[must_use = doc::must_use_op!()]
109 #[inline]
110 pub const fn swap_bytes(self) -> Self {
111 Self::from_bits(self.bits.swap_bytes())
112 }
113
114 #[doc = doc::reverse_bits!(I 256, "i")]
115 #[must_use = doc::must_use_op!()]
116 #[inline]
117 pub const fn reverse_bits(self) -> Self {
118 Self::from_bits(self.bits.reverse_bits())
119 }
120
121 #[doc = doc::unsigned_abs!(I)]
122 #[must_use = doc::must_use_op!()]
123 #[inline]
124 pub const fn unsigned_abs(self) -> $BUint<N> {
125 if self.is_negative() {
126 self.wrapping_neg().bits
127 } else {
128 self.bits
129 }
130 }
131
132 #[doc = doc::pow!(I 256)]
133 #[must_use = doc::must_use_op!()]
134 #[inline]
135 pub const fn pow(self, exp: ExpType) -> Self {
136 #[cfg(debug_assertions)]
137 return option_expect!(self.checked_pow(exp), errors::err_msg!("attempt to calculate power with overflow"));
138
139 #[cfg(not(debug_assertions))]
140 self.wrapping_pow(exp)
141 }
142
143 #[doc = doc::div_euclid!(I)]
144 #[must_use = doc::must_use_op!()]
145 #[inline]
146 pub const fn div_euclid(self, rhs: Self) -> Self {
147 assert!(self.ne(&Self::MIN) || rhs.ne(&Self::NEG_ONE), errors::err_msg!("attempt to divide with overflow"));
148 self.wrapping_div_euclid(rhs)
149 }
150
151 #[doc = doc::rem_euclid!(I)]
152 #[must_use = doc::must_use_op!()]
153 #[inline]
154 pub const fn rem_euclid(self, rhs: Self) -> Self {
155 assert!(self.ne(&Self::MIN) || rhs.ne(&Self::NEG_ONE), errors::err_msg!("attempt to calculate remainder with overflow"));
156 self.wrapping_rem_euclid(rhs)
157 }
158
159 #[doc = doc::abs!(I)]
160 #[must_use = doc::must_use_op!()]
161 #[inline]
162 pub const fn abs(self) -> Self {
163 #[cfg(debug_assertions)]
164 return option_expect!(self.checked_abs(), errors::err_msg!("attempt to negate with overflow"));
165
166 #[cfg(not(debug_assertions))]
167 match self.checked_abs() {
168 Some(int) => int,
169 None => Self::MIN,
170 }
171 }
172
173 #[doc = doc::signum!(I)]
174 #[must_use = doc::must_use_op!()]
175 #[inline]
176 pub const fn signum(self) -> Self {
177 if self.is_negative() {
178 Self::NEG_ONE
179 } else if self.is_zero() {
180 Self::ZERO
181 } else {
182 Self::ONE
183 }
184 }
185
186 #[doc = doc::is_positive!(I)]
187 #[must_use = doc::must_use_op!()]
188 #[inline]
189 pub const fn is_positive(self) -> bool {
190 let signed_digit = self.signed_digit();
191 signed_digit.is_positive() || (signed_digit == 0 && !self.bits.is_zero())
192 }
193
194 #[doc = doc::is_negative!(I)]
195 #[must_use = doc::must_use_op!()]
196 #[inline]
197 pub const fn is_negative(self) -> bool {
198 self.signed_digit().is_negative()
199 }
200
201 #[doc = doc::doc_comment! {
202 I 256,
203 "Returns `true` if and only if `self == 2^k` for some integer `k`.",
204
205 "let n = " stringify!(I256) "::from(1i16 << 12);\n"
206 "assert!(n.is_power_of_two());\n"
207 "let m = " stringify!(I256) "::from(90i8);\n"
208 "assert!(!m.is_power_of_two());\n"
209 "assert!(!((-n).is_power_of_two()));"
210 }]
211 #[must_use]
212 #[inline]
213 pub const fn is_power_of_two(self) -> bool {
214 !self.is_negative() &&self.bits.is_power_of_two()
215 }
216
217 ilog!(ilog, base: Self);
218 ilog!(ilog2);
219 ilog!(ilog10);
220
221 #[doc = doc::abs_diff!(I)]
222 #[must_use = doc::must_use_op!()]
223 #[inline]
224 pub const fn abs_diff(self, other: Self) -> $BUint<N> {
225 if self.lt(&other) {
226 other.wrapping_sub(self).to_bits()
227 } else {
228 self.wrapping_sub(other).to_bits()
229 }
230 }
231
232 #[doc = doc::next_multiple_of!(I)]
233 #[must_use = doc::must_use_op!()]
234 #[inline]
235 pub const fn next_multiple_of(self, rhs: Self) -> Self {
236 let rem = self.wrapping_rem_euclid(rhs);
237 if rem.is_zero() {
238 return self;
239 }
240 if rem.is_negative() == rhs.is_negative() {
241 self.add(rhs.sub(rem))
242 } else {
243 self.sub(rem)
244 }
245 }
246
247 #[doc = doc::div_floor!(I)]
248 #[must_use = doc::must_use_op!()]
249 #[inline]
250 pub const fn div_floor(self, rhs: Self) -> Self {
251 if rhs.is_zero() {
252 errors::div_zero!();
253 }
254 let (div, rem) = self.div_rem_unchecked(rhs);
255 if rem.is_zero() || self.is_negative() == rhs.is_negative() {
256 div
257 } else {
258 div.sub(Self::ONE)
259 }
260 }
261
262 #[doc = doc::div_ceil!(I)]
263 #[must_use = doc::must_use_op!()]
264 #[inline]
265 pub const fn div_ceil(self, rhs: Self) -> Self {
266 if rhs.is_zero() {
267 errors::div_zero!();
268 }
269 let (div, rem) = self.div_rem_unchecked(rhs);
270 if rem.is_zero() || self.is_negative() != rhs.is_negative() {
271 div
272 } else {
273 div.add(Self::ONE)
274 }
275 }
276 }
277
278 impl<const N: usize> $BInt<N> {
279 #[doc = doc::bits!(I 256)]
280 #[must_use]
281 #[inline]
282 pub const fn bits(&self) -> ExpType {
283 self.bits.bits()
284 }
285
286 #[doc = doc::bit!(I 256)]
287 #[must_use]
288 #[inline]
289 pub const fn bit(&self, b: ExpType) -> bool {
290 self.bits.bit(b)
291 }
292
293 #[inline(always)]
294 pub(crate) const fn signed_digit(&self) -> digit::$Digit::SignedDigit {
295 self.bits.digits[N - 1] as _
296 }
297
298 #[doc = doc::is_zero!(I 256)]
299 #[must_use]
300 #[inline]
301 pub const fn is_zero(&self) -> bool {
302 self.bits.is_zero()
303 }
304
305 #[doc = doc::is_one!(I 256)]
306 #[must_use]
307 #[inline]
308 pub const fn is_one(&self) -> bool {
309 self.bits.is_one()
310 }
311
312 #[doc = concat!("[`", stringify!($BUint), "`]")]
316 #[doc = concat!("[`", stringify!($BInt), "`]")]
318 #[must_use]
320 #[inline(always)]
321 pub const fn from_bits(bits: $BUint<N>) -> Self {
322 Self { bits }
323 }
324
325 #[doc = concat!("[`", stringify!($BInt), "`]")]
329 #[doc = concat!("[`", stringify!($BUint), "`]")]
331 #[must_use]
333 #[inline(always)]
334 pub const fn to_bits(self) -> $BUint<N> {
335 self.bits
336 }
337 }
338
339 impl<const N: usize> Default for $BInt<N> {
340 #[doc = doc::default!()]
341 #[inline]
342 fn default() -> Self {
343 Self::ZERO
344 }
345 }
346
347 impl<const N: usize> Product<Self> for $BInt<N> {
348 #[inline]
349 fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
350 iter.fold(Self::ONE, |a, b| a * b)
351 }
352 }
353
354 impl<'a, const N: usize> Product<&'a Self> for $BInt<N> {
355 #[inline]
356 fn product<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
357 iter.fold(Self::ONE, |a, b| a * b)
358 }
359 }
360
361 impl<const N: usize> Sum<Self> for $BInt<N> {
362 #[inline]
363 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
364 iter.fold(Self::ZERO, |a, b| a + b)
365 }
366 }
367
368 impl<'a, const N: usize> Sum<&'a Self> for $BInt<N> {
369 #[inline]
370 fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
371 iter.fold(Self::ZERO, |a, b| a + b)
372 }
373 }
374
375 #[cfg(any(test))]
376 impl<const N: usize> quickcheck::Arbitrary for $BInt<N> {
377 #[inline]
378 fn arbitrary(g: &mut quickcheck::Gen) -> Self {
379 Self::from_bits(<$BUint::<N> as quickcheck::Arbitrary>::arbitrary(g))
380 }
381 }
382 };
383}
384
385crate::macro_impl!(mod_impl);
386
387pub mod cast;
388mod checked;
389mod cmp;
390mod const_trait_fillers;
391mod consts;
392mod convert;
393mod endian;
394mod fmt;
395#[cfg(feature = "numtraits")]
396mod numtraits;
397mod ops;
398mod overflowing;
399mod radix;
400mod saturating;
401mod unchecked;
402mod wrapping;