1use crate::errors::{self, option_expect};
2
3use crate::digit;
4use crate::doc;
5use crate::ExpType;
6use core::default::Default;
9
10use core::iter::{Iterator, Product, Sum};
11
12macro_rules! mod_impl {
13 ($BUint: ident, $BInt: ident, $Digit: ident) => {
14 #[doc = concat!("`", stringify!($Digit), "`")]
16 #[doc = concat!("`", stringify!($Digit), "`")]
20 #[doc = doc::arithmetic_doc!($BUint)]
23 #[derive(Clone, Copy, Hash, PartialEq, Eq)]
24 #[repr(transparent)]
25 pub struct $BUint<const N: usize> {
26 pub(crate) digits: [$Digit; N],
27 }
28
29 impl<const N: usize> $BUint<N> {
30 #[doc = doc::count_ones!(U 1024)]
31 #[must_use = doc::must_use_op!()]
32 #[inline]
33 pub const fn count_ones(self) -> ExpType {
34 let mut ones = 0;
35 let mut i = 0;
36 while i < N {
37 ones += self.digits[i].count_ones() as ExpType;
38 i += 1;
39 }
40 ones
41 }
42
43 #[doc = doc::count_zeros!(U 1024)]
44 #[must_use = doc::must_use_op!()]
45 #[inline]
46 pub const fn count_zeros(self) -> ExpType {
47 let mut zeros = 0;
48 let mut i = 0;
49 while i < N {
50 zeros += self.digits[i].count_zeros() as ExpType;
51 i += 1;
52 }
53 zeros
54 }
55
56 #[doc = doc::leading_zeros!(U 1024)]
57 #[must_use = doc::must_use_op!()]
58 #[inline]
59 pub const fn leading_zeros(self) -> ExpType {
60 let mut zeros = 0;
61 let mut i = N;
62 while i > 0 {
63 i -= 1;
64 let digit = self.digits[i];
65 zeros += digit.leading_zeros() as ExpType;
66 if digit != $Digit::MIN {
67 break;
68 }
69 }
70 zeros
71 }
72
73 #[doc = doc::trailing_zeros!(U 1024)]
74 #[must_use = doc::must_use_op!()]
75 #[inline]
76 pub const fn trailing_zeros(self) -> ExpType {
77 let mut zeros = 0;
78 let mut i = 0;
79 while i < N {
80 let digit = self.digits[i];
81 zeros += digit.trailing_zeros() as ExpType;
82 if digit != $Digit::MIN {
83 break;
84 }
85 i += 1;
86 }
87 zeros
88 }
89
90 #[doc = doc::leading_ones!(U 1024, MAX)]
91 #[must_use = doc::must_use_op!()]
92 #[inline]
93 pub const fn leading_ones(self) -> ExpType {
94 let mut ones = 0;
95 let mut i = N;
96 while i > 0 {
97 i -= 1;
98 let digit = self.digits[i];
99 ones += digit.leading_ones() as ExpType;
100 if digit != $Digit::MAX {
101 break;
102 }
103 }
104 ones
105 }
106
107 #[doc = doc::trailing_ones!(U 1024)]
108 #[must_use = doc::must_use_op!()]
109 #[inline]
110 pub const fn trailing_ones(self) -> ExpType {
111 let mut ones = 0;
112 let mut i = 0;
113 while i < N {
114 let digit = self.digits[i];
115 ones += digit.trailing_ones() as ExpType;
116 if digit != $Digit::MAX {
117 break;
118 }
119 i += 1;
120 }
121 ones
122 }
123
124 #[inline]
125 const unsafe fn rotate_digits_left(self, n: usize) -> Self {
126 let mut out = Self::ZERO;
127 let mut i = n;
128 while i < N {
129 out.digits[i] = self.digits[i - n];
130 i += 1;
131 }
132 let init_index = N - n;
133 let mut i = init_index;
134 while i < N {
135 out.digits[i - init_index] = self.digits[i];
136 i += 1;
137 }
138
139 out
140 }
141
142 #[inline]
143 const unsafe fn unchecked_rotate_left(self, rhs: ExpType) -> Self {
144 let digit_shift = (rhs >> digit::$Digit::BIT_SHIFT) as usize;
145 let bit_shift = rhs & digit::$Digit::BITS_MINUS_1;
146
147 let mut out = self.rotate_digits_left(digit_shift);
148
149 if bit_shift != 0 {
150 let carry_shift = digit::$Digit::BITS - bit_shift;
151 let mut carry = 0;
152
153 let mut i = 0;
154 while i < N {
155 let current_digit = out.digits[i];
156 out.digits[i] = (current_digit << bit_shift) | carry;
157 carry = current_digit >> carry_shift;
158 i += 1;
159 }
160 out.digits[0] |= carry;
161 }
162
163 out
164 }
165
166 const BITS_MINUS_1: ExpType = (Self::BITS - 1) as ExpType;
167
168 #[doc = doc::rotate_left!(U 256, "u")]
169 #[must_use = doc::must_use_op!()]
170 #[inline]
171 pub const fn rotate_left(self, n: ExpType) -> Self {
172 unsafe { self.unchecked_rotate_left(n & Self::BITS_MINUS_1) }
173 }
174
175 #[doc = doc::rotate_right!(U 256, "u")]
176 #[must_use = doc::must_use_op!()]
177 #[inline]
178 pub const fn rotate_right(self, n: ExpType) -> Self {
179 let n = n & Self::BITS_MINUS_1;
180 unsafe { self.unchecked_rotate_left(Self::BITS as ExpType - n) }
181 }
182
183 const N_MINUS_1: usize = N - 1;
184
185 #[doc = doc::swap_bytes!(U 256, "u")]
186 #[must_use = doc::must_use_op!()]
187 #[inline]
188 pub const fn swap_bytes(self) -> Self {
189 let mut uint = Self::ZERO;
190 let mut i = 0;
191 while i < N {
192 uint.digits[i] = self.digits[Self::N_MINUS_1 - i].swap_bytes();
193 i += 1;
194 }
195 uint
196 }
197
198 #[doc = doc::reverse_bits!(U 256, "u")]
199 #[must_use = doc::must_use_op!()]
200 #[inline]
201 pub const fn reverse_bits(self) -> Self {
202 let mut uint = Self::ZERO;
203 let mut i = 0;
204 while i < N {
205 uint.digits[i] = self.digits[Self::N_MINUS_1 - i].reverse_bits();
206 i += 1;
207 }
208 uint
209 }
210
211 #[doc = doc::pow!(U 256)]
212 #[must_use = doc::must_use_op!()]
213 #[inline]
214 pub const fn pow(self, exp: ExpType) -> Self {
215 #[cfg(debug_assertions)]
216 return option_expect!(
217 self.checked_pow(exp),
218 errors::err_msg!("attempt to calculate power with overflow")
219 );
220 #[cfg(not(debug_assertions))]
221 self.wrapping_pow(exp)
222 }
223
224 #[doc = doc::div_euclid!(U)]
225 #[must_use = doc::must_use_op!()]
226 #[inline]
227 pub const fn div_euclid(self, rhs: Self) -> Self {
228 self.wrapping_div_euclid(rhs)
229 }
230
231 #[doc = doc::rem_euclid!(U)]
232 #[must_use = doc::must_use_op!()]
233 #[inline]
234 pub const fn rem_euclid(self, rhs: Self) -> Self {
235 self.wrapping_rem_euclid(rhs)
236 }
237
238 #[doc = doc::doc_comment! {
239 U 256,
240 "Returns `true` if and only if `self == 2^k` for some integer `k`.",
241
242 "let n = " stringify!(U256) "::from(1u16 << 14);\n"
243 "assert!(n.is_power_of_two());\n"
244 "let m = " stringify!(U256) "::from(100u8);\n"
245 "assert!(!m.is_power_of_two());"
246 }]
247 #[must_use]
248 #[inline]
249 pub const fn is_power_of_two(self) -> bool {
250 let mut i = 0;
251 let mut ones = 0;
252 while i < N {
253 ones += (&self.digits)[i].count_ones();
254 if ones > 1 {
255 return false;
256 }
257 i += 1;
258 }
259 ones == 1
260 }
261
262 #[doc = doc::next_power_of_two!(U 256, "0", "ZERO")]
263 #[must_use = doc::must_use_op!()]
264 #[inline]
265 pub const fn next_power_of_two(self) -> Self {
266 #[cfg(debug_assertions)]
267 return option_expect!(
268 self.checked_next_power_of_two(),
269 errors::err_msg!("attempt to calculate next power of two with overflow")
270 );
271 #[cfg(not(debug_assertions))]
272 self.wrapping_next_power_of_two()
273 }
274
275 #[doc = doc::ilog2!(U)]
276 #[must_use = doc::must_use_op!()]
277 #[inline]
278 pub const fn ilog2(self) -> ExpType {
279 option_expect!(
280 self.checked_ilog2(),
281 errors::err_msg!(errors::non_positive_log_message!())
282 )
283 }
284
285 #[doc = doc::ilog10!(U)]
286 #[must_use = doc::must_use_op!()]
287 #[inline]
288 pub const fn ilog10(self) -> ExpType {
289 option_expect!(
290 self.checked_ilog10(),
291 errors::err_msg!(errors::non_positive_log_message!())
292 )
293 }
294
295 #[doc = doc::ilog!(U)]
296 #[must_use = doc::must_use_op!()]
297 #[inline]
298 pub const fn ilog(self, base: Self) -> ExpType {
299 if base.le(&Self::ONE) {
300 panic!("{}", errors::err_msg!(errors::invalid_log_base!()));
301 }
302 option_expect!(
303 self.checked_ilog(base),
304 errors::err_msg!(errors::non_positive_log_message!())
305 )
306 }
307
308 #[doc = doc::abs_diff!(U)]
309 #[must_use = doc::must_use_op!()]
310 #[inline]
311 pub const fn abs_diff(self, other: Self) -> Self {
312 if self.lt(&other) {
313 other.wrapping_sub(self)
314 } else {
315 self.wrapping_sub(other)
316 }
317 }
318
319 #[doc = doc::next_multiple_of!(U)]
320 #[must_use = doc::must_use_op!()]
321 #[inline]
322 pub const fn next_multiple_of(self, rhs: Self) -> Self {
323 let rem = self.wrapping_rem(rhs);
324 if rem.is_zero() {
325 self
326 } else {
327 self.add(rhs.sub(rem))
328 }
329 }
330
331 #[doc = doc::div_floor!(U)]
332 #[must_use = doc::must_use_op!()]
333 #[inline]
334 pub const fn div_floor(self, rhs: Self) -> Self {
335 self.wrapping_div(rhs)
336 }
337
338 #[doc = doc::div_ceil!(U)]
339 #[must_use = doc::must_use_op!()]
340 #[inline]
341 pub const fn div_ceil(self, rhs: Self) -> Self {
342 let (div, rem) = self.div_rem(rhs);
343 if rem.is_zero() {
344 div
345 } else {
346 div.add(Self::ONE)
347 }
348 }
349 }
350
351 impl<const N: usize> $BUint<N> {
352 #[inline]
353 pub(crate) const unsafe fn unchecked_shl_internal(self, rhs: ExpType) -> Self {
354 let mut out = $BUint::ZERO;
355 let digit_shift = (rhs >> digit::$Digit::BIT_SHIFT) as usize;
356 let bit_shift = rhs & digit::$Digit::BITS_MINUS_1;
357
358 if bit_shift != 0 {
361 let carry_shift = digit::$Digit::BITS - bit_shift;
362 let mut carry = 0;
363
364 let mut i = digit_shift;
365 while i < N {
366 let current_digit = self.digits[i - digit_shift];
367 out.digits[i] = (current_digit << bit_shift) | carry;
368 carry = current_digit >> carry_shift;
369 i += 1;
370 }
371 } else {
372 let mut i = digit_shift;
373 while i < N {
374 out.digits[i] = self.digits[i - digit_shift];
376 i += 1;
377 }
378 }
379
380 out
381 }
382
383 #[inline]
384 pub(crate) const unsafe fn unchecked_shr_pad_internal<const NEG: bool>(
385 self,
386 rhs: ExpType,
387 ) -> Self {
388 let mut out = if NEG { $BUint::MAX } else { $BUint::ZERO };
389 let digit_shift = (rhs >> digit::$Digit::BIT_SHIFT) as usize;
390 let bit_shift = rhs & digit::$Digit::BITS_MINUS_1;
391
392 let num_copies = N.saturating_sub(digit_shift); if bit_shift != 0 {
395 let carry_shift = digit::$Digit::BITS - bit_shift;
396 let mut carry = 0;
397
398 let mut i = digit_shift;
399 while i < N {
400 let index = N - 1 - i;
402 let current_digit = self.digits[index + digit_shift];
403 out.digits[index] = (current_digit >> bit_shift) | carry;
404 carry = current_digit << carry_shift;
405 i += 1;
406 }
407
408 if NEG {
409 out.digits[num_copies - 1] |= $Digit::MAX << carry_shift;
410 }
411 } else {
412 let mut i = digit_shift;
413 while i < N {
414 out.digits[i - digit_shift] = self.digits[i];
416 i += 1;
417 }
418 }
419
420 out
421 }
422
423 pub(crate) const unsafe fn unchecked_shr_internal(
424 u: $BUint<N>,
425 rhs: ExpType,
426 ) -> $BUint<N> {
427 Self::unchecked_shr_pad_internal::<false>(u, rhs)
428 }
429
430 #[doc = doc::bits!(U 256)]
431 #[must_use]
432 #[inline]
433 pub const fn bits(&self) -> ExpType {
434 Self::BITS as ExpType - self.leading_zeros()
435 }
436
437 #[doc = doc::bit!(U 256)]
438 #[must_use]
439 #[inline]
440 pub const fn bit(&self, index: ExpType) -> bool {
441 let digit = self.digits[index as usize >> digit::$Digit::BIT_SHIFT];
442 digit & (1 << (index & digit::$Digit::BITS_MINUS_1)) != 0
443 }
444
445 #[must_use]
460 #[inline]
461 pub const fn power_of_two(power: ExpType) -> Self {
462 let mut out = Self::ZERO;
463 out.digits[power as usize >> digit::$Digit::BIT_SHIFT] =
464 1 << (power & (digit::$Digit::BITS - 1));
465 out
466 }
467
468 #[must_use]
470 #[inline(always)]
471 pub const fn digits(&self) -> &[$Digit; N] {
472 &self.digits
473 }
474
475 #[must_use]
477 #[inline(always)]
478 pub const fn from_digits(digits: [$Digit; N]) -> Self {
479 Self { digits }
480 }
481
482 #[must_use]
484 #[inline(always)]
485 pub const fn from_digit(digit: $Digit) -> Self {
486 let mut out = Self::ZERO;
487 out.digits[0] = digit;
488 out
489 }
490
491 #[doc = doc::is_zero!(U 256)]
492 #[must_use]
493 #[inline]
494 pub const fn is_zero(&self) -> bool {
495 let mut i = 0;
496 while i < N {
497 if (&self.digits)[i] != 0 {
498 return false;
499 }
500 i += 1;
501 }
502 true
503 }
504
505 #[doc = doc::is_one!(U 256)]
506 #[must_use]
507 #[inline]
508 pub const fn is_one(&self) -> bool {
509 if N == 0 || self.digits[0] != 1 {
510 return false;
511 }
512 let mut i = 1;
513 while i < N {
514 if (&self.digits)[i] != 0 {
515 return false;
516 }
517 i += 1;
518 }
519 true
520 }
521
522 #[inline]
523 pub(crate) const fn last_digit_index(&self) -> usize {
524 let mut index = 0;
525 let mut i = 1;
526 while i < N {
527 if (&self.digits)[i] != 0 {
528 index = i;
529 }
530 i += 1;
531 }
532 index
533 }
534
535 #[allow(unused)]
536 #[inline]
537 fn square(self) -> Self {
538 self * self
540 }
541 }
542
543 impl<const N: usize> Default for $BUint<N> {
544 #[doc = doc::default!()]
545 #[inline]
546 fn default() -> Self {
547 Self::ZERO
548 }
549 }
550
551 impl<const N: usize> Product<Self> for $BUint<N> {
552 #[inline]
553 fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
554 iter.fold(Self::ONE, |a, b| a * b)
555 }
556 }
557
558 impl<'a, const N: usize> Product<&'a Self> for $BUint<N> {
559 #[inline]
560 fn product<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
561 iter.fold(Self::ONE, |a, b| a * b)
562 }
563 }
564
565 impl<const N: usize> Sum<Self> for $BUint<N> {
566 #[inline]
567 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
568 iter.fold(Self::ZERO, |a, b| a + b)
569 }
570 }
571
572 impl<'a, const N: usize> Sum<&'a Self> for $BUint<N> {
573 #[inline]
574 fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
575 iter.fold(Self::ZERO, |a, b| a + b)
576 }
577 }
578
579 #[cfg(any(test))]
580 impl<const N: usize> quickcheck::Arbitrary for $BUint<N> {
581 fn arbitrary(g: &mut quickcheck::Gen) -> Self {
582 let mut out = Self::ZERO;
583 for digit in out.digits.iter_mut() {
584 *digit = <$Digit as quickcheck::Arbitrary>::arbitrary(g);
585 }
586 out
587 }
588 }
589 };
590}
591
592crate::main_impl!(mod_impl);
593
594pub mod as_float;
595mod bigint_helpers;
596pub mod cast;
597mod checked;
598mod cmp;
599mod const_trait_fillers;
600mod consts;
601mod convert;
602mod endian;
603pub mod float_as;
604mod fmt;
605#[cfg(feature = "numtraits")]
606mod numtraits;
607mod ops;
608mod overflowing;
609mod radix;
610mod saturating;
611mod unchecked;
612mod wrapping;