1use core::fmt;
33
34#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
36#[non_exhaustive]
37pub enum FromStrRadixErrKind {
38 InvalidCharacter,
40
41 InvalidLength,
43
44 UnsupportedRadix,
46}
47
48#[derive(Debug)]
49enum FromStrRadixErrSrc {
50 Hex(FromHexError),
51 Dec(FromDecStrErr),
52}
53
54impl fmt::Display for FromStrRadixErrSrc {
55 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56 match self {
57 FromStrRadixErrSrc::Dec(d) => write!(f, "{}", d),
58 FromStrRadixErrSrc::Hex(h) => write!(f, "{}", h),
59 }
60 }
61}
62
63#[derive(Debug)]
65pub struct FromStrRadixErr {
66 kind: FromStrRadixErrKind,
67 source: Option<FromStrRadixErrSrc>,
68}
69
70impl FromStrRadixErr {
71 #[doc(hidden)]
72 pub fn unsupported() -> Self {
73 Self { kind: FromStrRadixErrKind::UnsupportedRadix, source: None }
74 }
75
76 pub fn kind(&self) -> FromStrRadixErrKind {
78 self.kind
79 }
80}
81
82impl fmt::Display for FromStrRadixErr {
83 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
84 if let Some(ref src) = self.source {
85 return write!(f, "{}", src);
86 }
87
88 match self.kind {
89 FromStrRadixErrKind::UnsupportedRadix => write!(f, "the given radix is not supported"),
90 FromStrRadixErrKind::InvalidCharacter => write!(f, "input contains an invalid character"),
91 FromStrRadixErrKind::InvalidLength => write!(f, "length not supported for radix or type"),
92 }
93 }
94}
95
96#[cfg(feature = "std")]
97impl std::error::Error for FromStrRadixErr {
98 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
99 match self.source {
100 Some(FromStrRadixErrSrc::Dec(ref d)) => Some(d),
101 Some(FromStrRadixErrSrc::Hex(ref h)) => Some(h),
102 None => None,
103 }
104 }
105}
106
107impl From<FromDecStrErr> for FromStrRadixErr {
108 fn from(e: FromDecStrErr) -> Self {
109 let kind = match e {
110 FromDecStrErr::InvalidCharacter => FromStrRadixErrKind::InvalidCharacter,
111 FromDecStrErr::InvalidLength => FromStrRadixErrKind::InvalidLength,
112 };
113
114 Self { kind, source: Some(FromStrRadixErrSrc::Dec(e)) }
115 }
116}
117
118impl From<FromHexError> for FromStrRadixErr {
119 fn from(e: FromHexError) -> Self {
120 let kind = match e.inner {
121 hex::FromHexError::InvalidHexCharacter { .. } => FromStrRadixErrKind::InvalidCharacter,
122 hex::FromHexError::InvalidStringLength => FromStrRadixErrKind::InvalidLength,
123 hex::FromHexError::OddLength => FromStrRadixErrKind::InvalidLength,
124 };
125
126 Self { kind, source: Some(FromStrRadixErrSrc::Hex(e)) }
127 }
128}
129
130#[derive(Debug, PartialEq)]
132pub enum FromDecStrErr {
133 InvalidCharacter,
135 InvalidLength,
137}
138
139impl fmt::Display for FromDecStrErr {
140 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141 write!(
142 f,
143 "{}",
144 match self {
145 FromDecStrErr::InvalidCharacter => "a character is not in the range 0-9",
146 FromDecStrErr::InvalidLength => "the number is too large for the type",
147 }
148 )
149 }
150}
151
152#[cfg(feature = "std")]
153impl std::error::Error for FromDecStrErr {}
154
155#[derive(Debug)]
156pub struct FromHexError {
157 inner: hex::FromHexError,
158}
159
160impl fmt::Display for FromHexError {
161 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
162 write!(f, "{}", self.inner)
163 }
164}
165
166#[cfg(feature = "std")]
167impl std::error::Error for FromHexError {
168 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
169 Some(&self.inner)
170 }
171}
172
173#[doc(hidden)]
174impl From<hex::FromHexError> for FromHexError {
175 fn from(inner: hex::FromHexError) -> Self {
176 Self { inner }
177 }
178}
179
180#[macro_export]
181#[doc(hidden)]
182macro_rules! impl_map_from {
183 ($thing:ident, $from:ty, $to:ty) => {
184 impl From<$from> for $thing {
185 fn from(value: $from) -> $thing {
186 From::from(value as $to)
187 }
188 }
189 };
190}
191
192#[macro_export]
193#[doc(hidden)]
194macro_rules! impl_try_from_for_primitive {
195 ($from:ident, $to:ty) => {
196 impl $crate::core_::convert::TryFrom<$from> for $to {
197 type Error = &'static str;
198
199 #[inline]
200 fn try_from(u: $from) -> $crate::core_::result::Result<$to, &'static str> {
201 let $from(arr) = u;
202 if !u.fits_word() || arr[0] > <$to>::max_value() as u64 {
203 Err(concat!("integer overflow when casting to ", stringify!($to)))
204 } else {
205 Ok(arr[0] as $to)
206 }
207 }
208 }
209 };
210}
211
212#[macro_export]
213#[doc(hidden)]
214macro_rules! uint_overflowing_binop {
215 ($name:ident, $n_words: tt, $self_expr: expr, $other: expr, $fn:expr) => {{
216 use $crate::core_ as core;
217 let $name(ref me) = $self_expr;
218 let $name(ref you) = $other;
219
220 let mut ret = [0u64; $n_words];
221 let mut carry = 0u64;
222 $crate::static_assertions::const_assert!(core::isize::MAX as usize / core::mem::size_of::<u64>() > $n_words);
223
224 use $crate::unroll;
227 unroll! {
228 for i in 0..$n_words {
229 use core::ptr;
230
231 if carry != 0 {
232 let (res1, overflow1) = ($fn)(me[i], you[i]);
233 let (res2, overflow2) = ($fn)(res1, carry);
234
235 ret[i] = res2;
236 carry = (overflow1 as u8 + overflow2 as u8) as u64;
237 } else {
238 let (res, overflow) = ($fn)(me[i], you[i]);
239
240 ret[i] = res;
241 carry = overflow as u64;
242 }
243 }
244 }
245
246 ($name(ret), carry > 0)
247 }};
248}
249
250#[macro_export]
251#[doc(hidden)]
252macro_rules! uint_full_mul_reg {
253 ($name:ident, 8, $self_expr:expr, $other:expr) => {
254 $crate::uint_full_mul_reg!($name, 8, $self_expr, $other, |a, b| a != 0 || b != 0);
255 };
256 ($name:ident, $n_words:tt, $self_expr:expr, $other:expr) => {
257 $crate::uint_full_mul_reg!($name, $n_words, $self_expr, $other, |_, _| true);
258 };
259 ($name:ident, $n_words:tt, $self_expr:expr, $other:expr, $check:expr) => {{
260 {
261 #![allow(unused_assignments)]
262
263 let $name(ref me) = $self_expr;
264 let $name(ref you) = $other;
265 let mut ret = [0u64; $n_words * 2];
266
267 use $crate::unroll;
268 unroll! {
269 for i in 0..$n_words {
270 let mut carry = 0u64;
271 let b = you[i];
272
273 unroll! {
274 for j in 0..$n_words {
275 if $check(me[j], carry) {
276 let a = me[j];
277
278 let (hi, low) = Self::split_u128(a as u128 * b as u128);
279
280 let overflow = {
281 let existing_low = &mut ret[i + j];
282 let (low, o) = low.overflowing_add(*existing_low);
283 *existing_low = low;
284 o
285 };
286
287 carry = {
288 let existing_hi = &mut ret[i + j + 1];
289 let hi = hi + overflow as u64;
290 let (hi, o0) = hi.overflowing_add(carry);
291 let (hi, o1) = hi.overflowing_add(*existing_hi);
292 *existing_hi = hi;
293
294 (o0 | o1) as u64
295 }
296 }
297 }
298 }
299 }
300 }
301
302 ret
303 }
304 }};
305}
306
307#[macro_export]
308#[doc(hidden)]
309macro_rules! uint_overflowing_mul {
310 ($name:ident, $n_words: tt, $self_expr: expr, $other: expr) => {{
311 let ret: [u64; $n_words * 2] = $crate::uint_full_mul_reg!($name, $n_words, $self_expr, $other);
312
313 let ret: [[u64; $n_words]; 2] = unsafe { $crate::core_::mem::transmute(ret) };
315
316 #[inline(always)]
318 fn any_nonzero(arr: &[u64; $n_words]) -> bool {
319 use $crate::unroll;
320 unroll! {
321 for i in 0..$n_words {
322 if arr[i] != 0 {
323 return true;
324 }
325 }
326 }
327
328 false
329 }
330
331 ($name(ret[0]), any_nonzero(&ret[1]))
332 }};
333}
334
335#[macro_export]
336#[doc(hidden)]
337macro_rules! overflowing {
338 ($op: expr, $overflow: expr) => {{
339 let (overflow_x, overflow_overflow) = $op;
340 $overflow |= overflow_overflow;
341 overflow_x
342 }};
343 ($op: expr) => {{
344 let (overflow_x, _overflow_overflow) = $op;
345 overflow_x
346 }};
347}
348
349#[macro_export]
350#[doc(hidden)]
351macro_rules! panic_on_overflow {
352 ($name: expr) => {
353 if $name {
354 panic!("arithmetic operation overflow")
355 }
356 };
357}
358
359#[macro_export]
360#[doc(hidden)]
361macro_rules! impl_mul_from {
362 ($name: ty, $other: ident) => {
363 impl $crate::core_::ops::Mul<$other> for $name {
364 type Output = $name;
365
366 fn mul(self, other: $other) -> $name {
367 let bignum: $name = other.into();
368 let (result, overflow) = self.overflowing_mul(bignum);
369 $crate::panic_on_overflow!(overflow);
370 result
371 }
372 }
373
374 impl<'a> $crate::core_::ops::Mul<&'a $other> for $name {
375 type Output = $name;
376
377 fn mul(self, other: &'a $other) -> $name {
378 let bignum: $name = (*other).into();
379 let (result, overflow) = self.overflowing_mul(bignum);
380 $crate::panic_on_overflow!(overflow);
381 result
382 }
383 }
384
385 impl<'a> $crate::core_::ops::Mul<&'a $other> for &'a $name {
386 type Output = $name;
387
388 fn mul(self, other: &'a $other) -> $name {
389 let bignum: $name = (*other).into();
390 let (result, overflow) = self.overflowing_mul(bignum);
391 $crate::panic_on_overflow!(overflow);
392 result
393 }
394 }
395
396 impl<'a> $crate::core_::ops::Mul<$other> for &'a $name {
397 type Output = $name;
398
399 fn mul(self, other: $other) -> $name {
400 let bignum: $name = other.into();
401 let (result, overflow) = self.overflowing_mul(bignum);
402 $crate::panic_on_overflow!(overflow);
403 result
404 }
405 }
406
407 impl $crate::core_::ops::MulAssign<$other> for $name {
408 fn mul_assign(&mut self, other: $other) {
409 let result = *self * other;
410 *self = result
411 }
412 }
413 };
414}
415
416#[macro_export]
417#[doc(hidden)]
418macro_rules! impl_mul_for_primitive {
419 ($name: ty, $other: ident) => {
420 impl $crate::core_::ops::Mul<$other> for $name {
421 type Output = $name;
422
423 fn mul(self, other: $other) -> $name {
424 let (result, carry) = self.overflowing_mul_u64(other as u64);
425 $crate::panic_on_overflow!(carry > 0);
426 result
427 }
428 }
429
430 impl<'a> $crate::core_::ops::Mul<&'a $other> for $name {
431 type Output = $name;
432
433 fn mul(self, other: &'a $other) -> $name {
434 let (result, carry) = self.overflowing_mul_u64(*other as u64);
435 $crate::panic_on_overflow!(carry > 0);
436 result
437 }
438 }
439
440 impl<'a> $crate::core_::ops::Mul<&'a $other> for &'a $name {
441 type Output = $name;
442
443 fn mul(self, other: &'a $other) -> $name {
444 let (result, carry) = self.overflowing_mul_u64(*other as u64);
445 $crate::panic_on_overflow!(carry > 0);
446 result
447 }
448 }
449
450 impl<'a> $crate::core_::ops::Mul<$other> for &'a $name {
451 type Output = $name;
452
453 fn mul(self, other: $other) -> $name {
454 let (result, carry) = self.overflowing_mul_u64(other as u64);
455 $crate::panic_on_overflow!(carry > 0);
456 result
457 }
458 }
459
460 impl $crate::core_::ops::MulAssign<$other> for $name {
461 fn mul_assign(&mut self, other: $other) {
462 let result = *self * (other as u64);
463 *self = result
464 }
465 }
466 };
467}
468
469#[macro_export]
470macro_rules! construct_uint {
471 ( $(#[$attr:meta])* $visibility:vis struct $name:ident (1); ) => {
472 $crate::construct_uint!{ @construct $(#[$attr])* $visibility struct $name (1); }
473 };
474
475 ( $(#[$attr:meta])* $visibility:vis struct $name:ident ( $n_words:tt ); ) => {
476 $crate::construct_uint! { @construct $(#[$attr])* $visibility struct $name ($n_words); }
477
478 impl $crate::core_::convert::From<u128> for $name {
479 fn from(value: u128) -> $name {
480 let mut ret = [0; $n_words];
481 ret[0] = value as u64;
482 ret[1] = (value >> 64) as u64;
483 $name(ret)
484 }
485 }
486
487 impl $crate::core_::convert::From<i128> for $name {
488 fn from(value: i128) -> $name {
489 match value >= 0 {
490 true => From::from(value as u128),
491 false => { panic!("Unsigned integer can't be created from negative value"); }
492 }
493 }
494 }
495
496 impl $name {
497 #[inline]
499 pub const fn low_u128(&self) -> u128 {
500 let &$name(ref arr) = self;
501 ((arr[1] as u128) << 64) + arr[0] as u128
502 }
503
504 #[inline]
510 pub fn as_u128(&self) -> u128 {
511 let &$name(ref arr) = self;
512 for i in 2..$n_words {
513 if arr[i] != 0 {
514 panic!("Integer overflow when casting to u128")
515 }
516
517 }
518 self.low_u128()
519 }
520 }
521
522 impl $crate::core_::convert::TryFrom<$name> for u128 {
523 type Error = &'static str;
524
525 #[inline]
526 fn try_from(u: $name) -> $crate::core_::result::Result<u128, &'static str> {
527 let $name(arr) = u;
528 for i in 2..$n_words {
529 if arr[i] != 0 {
530 return Err("integer overflow when casting to u128");
531 }
532 }
533 Ok(((arr[1] as u128) << 64) + arr[0] as u128)
534 }
535 }
536
537 impl $crate::core_::convert::TryFrom<$name> for i128 {
538 type Error = &'static str;
539
540 #[inline]
541 fn try_from(u: $name) -> $crate::core_::result::Result<i128, &'static str> {
542 let err_str = "integer overflow when casting to i128";
543 let i = u128::try_from(u).map_err(|_| err_str)?;
544 if i > i128::max_value() as u128 {
545 Err(err_str)
546 } else {
547 Ok(i as i128)
548 }
549 }
550 }
551 };
552 ( @construct $(#[$attr:meta])* $visibility:vis struct $name:ident ( $n_words:tt ); ) => {
553 #[repr(C)]
555 $(#[$attr])*
556 #[derive(Copy, Clone, Eq, PartialEq, Hash)]
557 $visibility struct $name (pub [u64; $n_words]);
558
559 impl AsRef<[u64]> for $name {
561 #[inline]
562 fn as_ref(&self) -> &[u64] {
563 &self.0
564 }
565 }
566
567 impl<'a> From<&'a $name> for $name {
568 fn from(x: &'a $name) -> $name {
569 *x
570 }
571 }
572
573 impl $name {
574 const WORD_BITS: usize = 64;
575 pub const MAX: $name = $name([u64::max_value(); $n_words]);
577
578 pub fn from_str_radix(txt: &str, radix: u32) -> Result<Self, $crate::FromStrRadixErr> {
581 let parsed = match radix {
582 10 => Self::from_dec_str(txt)?,
583 16 => core::str::FromStr::from_str(txt)?,
584 _ => return Err($crate::FromStrRadixErr::unsupported()),
585 };
586
587 Ok(parsed)
588 }
589
590 pub fn from_dec_str(value: &str) -> $crate::core_::result::Result<Self, $crate::FromDecStrErr> {
592 let mut res = Self::default();
593 for b in value.bytes().map(|b| b.wrapping_sub(b'0')) {
594 if b > 9 {
595 return Err($crate::FromDecStrErr::InvalidCharacter)
596 }
597 let (r, overflow) = res.overflowing_mul_u64(10);
598 if overflow > 0 {
599 return Err($crate::FromDecStrErr::InvalidLength);
600 }
601 let (r, overflow) = r.overflowing_add(b.into());
602 if overflow {
603 return Err($crate::FromDecStrErr::InvalidLength);
604 }
605 res = r;
606 }
607 Ok(res)
608 }
609
610 #[inline]
612 pub const fn low_u32(&self) -> u32 {
613 let &$name(ref arr) = self;
614 arr[0] as u32
615 }
616
617 #[inline]
619 pub const fn low_u64(&self) -> u64 {
620 let &$name(ref arr) = self;
621 arr[0]
622 }
623
624 #[inline]
630 pub fn as_u32(&self) -> u32 {
631 let &$name(ref arr) = self;
632 if !self.fits_word() || arr[0] > u32::max_value() as u64 {
633 panic!("Integer overflow when casting to u32")
634 }
635 self.as_u64() as u32
636 }
637
638 #[inline]
644 pub fn as_u64(&self) -> u64 {
645 let &$name(ref arr) = self;
646 if !self.fits_word() {
647 panic!("Integer overflow when casting to u64")
648 }
649 arr[0]
650 }
651
652 #[inline]
658 pub fn as_usize(&self) -> usize {
659 let &$name(ref arr) = self;
660 if !self.fits_word() || arr[0] > usize::max_value() as u64 {
661 panic!("Integer overflow when casting to usize")
662 }
663 arr[0] as usize
664 }
665
666 #[inline]
668 pub const fn is_zero(&self) -> bool {
669 let &$name(ref arr) = self;
670 let mut i = 0;
671 while i < $n_words { if arr[i] != 0 { return false; } else { i += 1; } }
672 return true;
673 }
674
675 #[inline]
677 fn fits_word(&self) -> bool {
678 let &$name(ref arr) = self;
679 for i in 1..$n_words { if arr[i] != 0 { return false; } }
680 return true;
681 }
682
683
684 #[inline]
686 pub fn bits(&self) -> usize {
687 let &$name(ref arr) = self;
688 for i in 1..$n_words {
689 if arr[$n_words - i] > 0 { return (0x40 * ($n_words - i + 1)) - arr[$n_words - i].leading_zeros() as usize; }
690 }
691 0x40 - arr[0].leading_zeros() as usize
692 }
693
694 #[inline]
700 pub const fn bit(&self, index: usize) -> bool {
701 let &$name(ref arr) = self;
702 arr[index / 64] & (1 << (index % 64)) != 0
703 }
704
705 pub fn leading_zeros(&self) -> u32 {
707 let mut r = 0;
708 for i in 0..$n_words {
709 let w = self.0[$n_words - i - 1];
710 if w == 0 {
711 r += 64;
712 } else {
713 r += w.leading_zeros();
714 break;
715 }
716 }
717 r
718 }
719
720 pub fn trailing_zeros(&self) -> u32 {
722 let mut r = 0;
723 for i in 0..$n_words {
724 let w = self.0[i];
725 if w == 0 {
726 r += 64;
727 } else {
728 r += w.trailing_zeros();
729 break;
730 }
731 }
732 r
733 }
734
735 #[inline]
741 pub const fn byte(&self, index: usize) -> u8 {
742 let &$name(ref arr) = self;
743 (arr[index / 8] >> (((index % 8)) * 8)) as u8
744 }
745
746 #[inline]
748 pub fn to_big_endian(&self, bytes: &mut [u8]) {
749 use $crate::byteorder::{ByteOrder, BigEndian};
750 debug_assert!($n_words * 8 == bytes.len());
751 for i in 0..$n_words {
752 BigEndian::write_u64(&mut bytes[8 * i..], self.0[$n_words - i - 1]);
753 }
754 }
755
756 #[inline]
758 pub fn to_little_endian(&self, bytes: &mut [u8]) {
759 use $crate::byteorder::{ByteOrder, LittleEndian};
760 debug_assert!($n_words * 8 == bytes.len());
761 for i in 0..$n_words {
762 LittleEndian::write_u64(&mut bytes[8 * i..], self.0[i]);
763 }
764 }
765
766
767 #[inline]
773 pub fn exp10(n: usize) -> Self {
774 match n {
775 0 => Self::from(1u64),
776 _ => Self::exp10(n - 1) * 10u32
777 }
778 }
779
780 #[inline]
782 pub const fn zero() -> Self {
783 Self([0; $n_words])
784 }
785
786 #[inline]
788 pub const fn one() -> Self {
789 let mut words = [0; $n_words];
790 words[0] = 1u64;
791 Self(words)
792 }
793
794 #[inline]
796 pub const fn max_value() -> Self {
797 Self::MAX
798 }
799
800 fn full_shl(self, shift: u32) -> [u64; $n_words + 1] {
801 debug_assert!(shift < Self::WORD_BITS as u32);
802 let mut u = [0u64; $n_words + 1];
803 let u_lo = self.0[0] << shift;
804 let u_hi = self >> (Self::WORD_BITS as u32 - shift);
805 u[0] = u_lo;
806 u[1..].copy_from_slice(&u_hi.0[..]);
807 u
808 }
809
810 fn full_shr(u: [u64; $n_words + 1], shift: u32) -> Self {
811 debug_assert!(shift < Self::WORD_BITS as u32);
812 let mut res = Self::zero();
813 for i in 0..$n_words {
814 res.0[i] = u[i] >> shift;
815 }
816 if shift > 0 {
818 for i in 1..=$n_words {
819 res.0[i - 1] |= u[i] << (Self::WORD_BITS as u32 - shift);
820 }
821 }
822 res
823 }
824
825 fn full_mul_u64(self, by: u64) -> [u64; $n_words + 1] {
826 let (prod, carry) = self.overflowing_mul_u64(by);
827 let mut res = [0u64; $n_words + 1];
828 res[..$n_words].copy_from_slice(&prod.0[..]);
829 res[$n_words] = carry;
830 res
831 }
832
833 fn div_mod_small(mut self, other: u64) -> (Self, Self) {
834 let mut rem = 0u64;
835 self.0.iter_mut().rev().for_each(|d| {
836 let (q, r) = Self::div_mod_word(rem, *d, other);
837 *d = q;
838 rem = r;
839 });
840 (self, rem.into())
841 }
842
843 fn div_mod_knuth(self, mut v: Self, n: usize, m: usize) -> (Self, Self) {
845 debug_assert!(self.bits() >= v.bits() && !v.fits_word());
846 debug_assert!(n + m <= $n_words);
847 let shift = v.0[n - 1].leading_zeros();
852 v <<= shift;
853 let mut u = self.full_shl(shift);
855
856 let mut q = Self::zero();
858 let v_n_1 = v.0[n - 1];
859 let v_n_2 = v.0[n - 2];
860
861 for j in (0..=m).rev() {
864 let u_jn = u[j + n];
865
866 let mut q_hat = if u_jn < v_n_1 {
872 let (mut q_hat, mut r_hat) = Self::div_mod_word(u_jn, u[j + n - 1], v_n_1);
873 loop {
875 let (hi, lo) = Self::split_u128(u128::from(q_hat) * u128::from(v_n_2));
877 if (hi, lo) <= (r_hat, u[j + n - 2]) {
878 break;
879 }
880 q_hat -= 1;
882 let (new_r_hat, overflow) = r_hat.overflowing_add(v_n_1);
883 r_hat = new_r_hat;
884 if overflow {
886 break;
887 }
888 }
889 q_hat
890 } else {
891 u64::max_value()
893 };
894
895 let q_hat_v = v.full_mul_u64(q_hat);
903 let c = Self::sub_slice(&mut u[j..], &q_hat_v[..n + 1]);
905
906 if c {
910 q_hat -= 1;
911 let c = Self::add_slice(&mut u[j..], &v.0[..n]);
913 u[j + n] = u[j + n].wrapping_add(u64::from(c));
914 }
915
916 q.0[j] = q_hat;
918 }
919
920 let remainder = Self::full_shr(u, shift);
922
923 (q, remainder)
924 }
925
926 fn words(bits: usize) -> usize {
928 debug_assert!(bits > 0);
929 1 + (bits - 1) / Self::WORD_BITS
930 }
931
932 pub fn div_mod(mut self, mut other: Self) -> (Self, Self) {
938 use $crate::core_::cmp::Ordering;
939
940 let my_bits = self.bits();
941 let your_bits = other.bits();
942
943 assert!(your_bits != 0, "division by zero");
944
945 if my_bits < your_bits {
947 return (Self::zero(), self);
948 }
949
950 if your_bits <= Self::WORD_BITS {
951 return self.div_mod_small(other.low_u64());
952 }
953
954 let (n, m) = {
955 let my_words = Self::words(my_bits);
956 let your_words = Self::words(your_bits);
957 (your_words, my_words - your_words)
958 };
959
960 self.div_mod_knuth(other, n, m)
961 }
962
963 pub fn integer_sqrt(&self) -> Self {
965 let one = Self::one();
966 if self <= &one {
967 return *self;
968 }
969
970 let shift: u32 = (self.bits() as u32 + 1) / 2;
975 let mut x_prev = one << shift;
976 loop {
977 let x = (x_prev + self / x_prev) >> 1;
978 if x >= x_prev {
979 return x_prev;
980 }
981 x_prev = x;
982 }
983 }
984
985 pub fn pow(self, expon: Self) -> Self {
992 if expon.is_zero() {
993 return Self::one()
994 }
995 let is_even = |x : &Self| x.low_u64() & 1 == 0;
996
997 let u_one = Self::one();
998 let mut y = u_one;
999 let mut n = expon;
1000 let mut x = self;
1001 while n > u_one {
1002 if is_even(&n) {
1003 x = x * x;
1004 n = n >> 1usize;
1005 } else {
1006 y = x * y;
1007 x = x * x;
1008 n.0[$n_words-1] = n.0[$n_words-1] & ((!0u64)>>1);
1010 n = n >> 1usize;
1011 }
1012 }
1013 x * y
1014 }
1015
1016 pub fn overflowing_pow(self, expon: Self) -> (Self, bool) {
1018 if expon.is_zero() { return (Self::one(), false) }
1019
1020 let is_even = |x : &Self| x.low_u64() & 1 == 0;
1021
1022 let u_one = Self::one();
1023 let mut y = u_one;
1024 let mut n = expon;
1025 let mut x = self;
1026 let mut overflow = false;
1027
1028 while n > u_one {
1029 if is_even(&n) {
1030 x = $crate::overflowing!(x.overflowing_mul(x), overflow);
1031 n = n >> 1usize;
1032 } else {
1033 y = $crate::overflowing!(x.overflowing_mul(y), overflow);
1034 x = $crate::overflowing!(x.overflowing_mul(x), overflow);
1035 n = (n - u_one) >> 1usize;
1036 }
1037 }
1038 let res = $crate::overflowing!(x.overflowing_mul(y), overflow);
1039 (res, overflow)
1040 }
1041
1042 pub fn checked_pow(self, expon: $name) -> Option<$name> {
1044 match self.overflowing_pow(expon) {
1045 (_, true) => None,
1046 (val, _) => Some(val),
1047 }
1048 }
1049
1050 #[inline(always)]
1052 pub fn overflowing_add(self, other: $name) -> ($name, bool) {
1053 $crate::uint_overflowing_binop!(
1054 $name,
1055 $n_words,
1056 self,
1057 other,
1058 u64::overflowing_add
1059 )
1060 }
1061
1062 pub fn saturating_add(self, other: $name) -> $name {
1064 match self.overflowing_add(other) {
1065 (_, true) => $name::MAX,
1066 (val, false) => val,
1067 }
1068 }
1069
1070 pub fn checked_add(self, other: $name) -> Option<$name> {
1072 match self.overflowing_add(other) {
1073 (_, true) => None,
1074 (val, _) => Some(val),
1075 }
1076 }
1077
1078 #[inline(always)]
1080 pub fn overflowing_sub(self, other: $name) -> ($name, bool) {
1081 $crate::uint_overflowing_binop!(
1082 $name,
1083 $n_words,
1084 self,
1085 other,
1086 u64::overflowing_sub
1087 )
1088 }
1089
1090 pub fn saturating_sub(self, other: $name) -> $name {
1092 match self.overflowing_sub(other) {
1093 (_, true) => $name::zero(),
1094 (val, false) => val,
1095 }
1096 }
1097
1098 pub fn checked_sub(self, other: $name) -> Option<$name> {
1100 match self.overflowing_sub(other) {
1101 (_, true) => None,
1102 (val, _) => Some(val),
1103 }
1104 }
1105
1106 pub fn abs_diff(self, other: $name) -> $name {
1108 if self > other {
1109 self.overflowing_sub(other).0
1110 } else {
1111 other.overflowing_sub(self).0
1112 }
1113 }
1114
1115 #[inline(always)]
1117 pub fn overflowing_mul(self, other: $name) -> ($name, bool) {
1118 $crate::uint_overflowing_mul!($name, $n_words, self, other)
1119 }
1120
1121 pub fn saturating_mul(self, other: $name) -> $name {
1123 match self.overflowing_mul(other) {
1124 (_, true) => $name::MAX,
1125 (val, false) => val,
1126 }
1127 }
1128
1129 pub fn checked_mul(self, other: $name) -> Option<$name> {
1131 match self.overflowing_mul(other) {
1132 (_, true) => None,
1133 (val, _) => Some(val),
1134 }
1135 }
1136
1137 pub fn checked_div(self, other: $name) -> Option<$name> {
1139 if other.is_zero() {
1140 None
1141 } else {
1142 Some(self / other)
1143 }
1144 }
1145
1146 pub fn checked_rem(self, other: $name) -> Option<$name> {
1148 if other.is_zero() {
1149 None
1150 } else {
1151 Some(self % other)
1152 }
1153 }
1154
1155 pub fn overflowing_neg(self) -> ($name, bool) {
1157 if self.is_zero() {
1158 (self, false)
1159 } else {
1160 (!self + 1, true)
1161 }
1162 }
1163
1164 pub fn checked_neg(self) -> Option<$name> {
1166 match self.overflowing_neg() {
1167 (_, true) => None,
1168 (zero, false) => Some(zero),
1169 }
1170 }
1171
1172 #[inline(always)]
1173 fn div_mod_word(hi: u64, lo: u64, y: u64) -> (u64, u64) {
1174 debug_assert!(hi < y);
1175 let x = (u128::from(hi) << 64) + u128::from(lo);
1176 let y = u128::from(y);
1177 ((x / y) as u64, (x % y) as u64)
1178 }
1179
1180 #[inline(always)]
1181 fn add_slice(a: &mut [u64], b: &[u64]) -> bool {
1182 Self::binop_slice(a, b, u64::overflowing_add)
1183 }
1184
1185 #[inline(always)]
1186 fn sub_slice(a: &mut [u64], b: &[u64]) -> bool {
1187 Self::binop_slice(a, b, u64::overflowing_sub)
1188 }
1189
1190 #[inline(always)]
1191 fn binop_slice(a: &mut [u64], b: &[u64], binop: impl Fn(u64, u64) -> (u64, bool) + Copy) -> bool {
1192 let mut c = false;
1193 a.iter_mut().zip(b.iter()).for_each(|(x, y)| {
1194 let (res, carry) = Self::binop_carry(*x, *y, c, binop);
1195 *x = res;
1196 c = carry;
1197 });
1198 c
1199 }
1200
1201 #[inline(always)]
1202 fn binop_carry(a: u64, b: u64, c: bool, binop: impl Fn(u64, u64) -> (u64, bool)) -> (u64, bool) {
1203 let (res1, overflow1) = b.overflowing_add(u64::from(c));
1204 let (res2, overflow2) = binop(a, res1);
1205 (res2, overflow1 || overflow2)
1206 }
1207
1208 #[inline(always)]
1209 const fn mul_u64(a: u64, b: u64, carry: u64) -> (u64, u64) {
1210 let (hi, lo) = Self::split_u128(a as u128 * b as u128 + carry as u128);
1211 (lo, hi)
1212 }
1213
1214 #[inline(always)]
1215 const fn split(a: u64) -> (u64, u64) {
1216 (a >> 32, a & 0xFFFF_FFFF)
1217 }
1218
1219 #[inline(always)]
1220 const fn split_u128(a: u128) -> (u64, u64) {
1221 ((a >> 64) as _, (a & 0xFFFFFFFFFFFFFFFF) as _)
1222 }
1223
1224
1225 fn overflowing_mul_u64(mut self, other: u64) -> (Self, u64) {
1228 let mut carry = 0u64;
1229
1230 for d in self.0.iter_mut() {
1231 let (res, c) = Self::mul_u64(*d, other, carry);
1232 *d = res;
1233 carry = c;
1234 }
1235
1236 (self, carry)
1237 }
1238
1239 pub fn from_big_endian(slice: &[u8]) -> Self {
1241 use $crate::byteorder::{ByteOrder, BigEndian};
1242 assert!($n_words * 8 >= slice.len());
1243
1244 let mut padded = [0u8; $n_words * 8];
1245 padded[$n_words * 8 - slice.len() .. $n_words * 8].copy_from_slice(&slice);
1246
1247 let mut ret = [0; $n_words];
1248 for i in 0..$n_words {
1249 ret[$n_words - i - 1] = BigEndian::read_u64(&padded[8 * i..]);
1250 }
1251
1252 $name(ret)
1253 }
1254
1255 pub fn from_little_endian(slice: &[u8]) -> Self {
1257 use $crate::byteorder::{ByteOrder, LittleEndian};
1258 assert!($n_words * 8 >= slice.len());
1259
1260 let mut padded = [0u8; $n_words * 8];
1261 padded[0..slice.len()].copy_from_slice(&slice);
1262
1263 let mut ret = [0; $n_words];
1264 for i in 0..$n_words {
1265 ret[i] = LittleEndian::read_u64(&padded[8 * i..]);
1266 }
1267
1268 $name(ret)
1269 }
1270
1271 fn fmt_hex(&self, f: &mut $crate::core_::fmt::Formatter, is_lower: bool) -> $crate::core_::fmt::Result {
1272 let &$name(ref data) = self;
1273 if self.is_zero() {
1275 return f.pad_integral(true, "0x", "0");
1276 }
1277
1278 let mut latch = false;
1279 let mut buf = [0_u8; $n_words * 16];
1280 let mut i = 0;
1281 for ch in data.iter().rev() {
1282 for x in 0..16 {
1283 let nibble = (ch & (15u64 << ((15 - x) * 4) as u64)) >> (((15 - x) * 4) as u64);
1285 if !latch {
1286 latch = nibble != 0;
1287 }
1288
1289 if latch {
1290 let nibble = match nibble {
1292 0..=9 => nibble as u8 + b'0',
1293 _ if is_lower => nibble as u8 - 10 + b'a',
1294 _ => nibble as u8 - 10 + b'A',
1295 };
1296 buf[i] = nibble;
1297 i += 1;
1298 }
1299 }
1300 }
1301
1302 let s = unsafe {
1304 $crate::core_::str::from_utf8_unchecked(&buf[0..i])
1305 };
1306 f.pad_integral(true, "0x", s)
1307 }
1308 }
1309
1310 impl $crate::core_::convert::From<$name> for [u8; $n_words * 8] {
1311 fn from(number: $name) -> Self {
1312 let mut arr = [0u8; $n_words * 8];
1313 number.to_big_endian(&mut arr);
1314 arr
1315 }
1316 }
1317
1318 impl $crate::core_::convert::From<[u8; $n_words * 8]> for $name {
1319 fn from(bytes: [u8; $n_words * 8]) -> Self {
1320 Self::from(&bytes)
1321 }
1322 }
1323
1324 impl<'a> $crate::core_::convert::From<&'a [u8; $n_words * 8]> for $name {
1325 fn from(bytes: &[u8; $n_words * 8]) -> Self {
1326 Self::from(&bytes[..])
1327 }
1328 }
1329
1330 impl $crate::core_::default::Default for $name {
1331 fn default() -> Self {
1332 $name::zero()
1333 }
1334 }
1335
1336 impl $crate::core_::convert::From<u64> for $name {
1337 fn from(value: u64) -> $name {
1338 let mut ret = [0; $n_words];
1339 ret[0] = value;
1340 $name(ret)
1341 }
1342 }
1343
1344 $crate::impl_map_from!($name, u8, u64);
1345 $crate::impl_map_from!($name, u16, u64);
1346 $crate::impl_map_from!($name, u32, u64);
1347 $crate::impl_map_from!($name, usize, u64);
1348
1349 impl $crate::core_::convert::From<i64> for $name {
1350 fn from(value: i64) -> $name {
1351 match value >= 0 {
1352 true => From::from(value as u64),
1353 false => { panic!("Unsigned integer can't be created from negative value"); }
1354 }
1355 }
1356 }
1357
1358 $crate::impl_map_from!($name, i8, i64);
1359 $crate::impl_map_from!($name, i16, i64);
1360 $crate::impl_map_from!($name, i32, i64);
1361 $crate::impl_map_from!($name, isize, i64);
1362
1363 impl<'a> $crate::core_::convert::From<&'a [u8]> for $name {
1365 fn from(bytes: &[u8]) -> $name {
1366 Self::from_big_endian(bytes)
1367 }
1368 }
1369
1370 $crate::impl_try_from_for_primitive!($name, u8);
1371 $crate::impl_try_from_for_primitive!($name, u16);
1372 $crate::impl_try_from_for_primitive!($name, u32);
1373 $crate::impl_try_from_for_primitive!($name, usize);
1374 $crate::impl_try_from_for_primitive!($name, u64);
1375 $crate::impl_try_from_for_primitive!($name, i8);
1376 $crate::impl_try_from_for_primitive!($name, i16);
1377 $crate::impl_try_from_for_primitive!($name, i32);
1378 $crate::impl_try_from_for_primitive!($name, isize);
1379 $crate::impl_try_from_for_primitive!($name, i64);
1380
1381 impl<T> $crate::core_::ops::Add<T> for $name where T: Into<$name> {
1382 type Output = $name;
1383
1384 fn add(self, other: T) -> $name {
1385 let (result, overflow) = self.overflowing_add(other.into());
1386 $crate::panic_on_overflow!(overflow);
1387 result
1388 }
1389 }
1390
1391 impl<'a, T> $crate::core_::ops::Add<T> for &'a $name where T: Into<$name> {
1392 type Output = $name;
1393
1394 fn add(self, other: T) -> $name {
1395 *self + other
1396 }
1397 }
1398
1399 impl $crate::core_::ops::AddAssign<$name> for $name {
1400 fn add_assign(&mut self, other: $name) {
1401 let (result, overflow) = self.overflowing_add(other);
1402 $crate::panic_on_overflow!(overflow);
1403 *self = result
1404 }
1405 }
1406
1407 impl<T> $crate::core_::ops::Sub<T> for $name where T: Into<$name> {
1408 type Output = $name;
1409
1410 #[inline]
1411 fn sub(self, other: T) -> $name {
1412 let (result, overflow) = self.overflowing_sub(other.into());
1413 $crate::panic_on_overflow!(overflow);
1414 result
1415 }
1416 }
1417
1418 impl<'a, T> $crate::core_::ops::Sub<T> for &'a $name where T: Into<$name> {
1419 type Output = $name;
1420
1421 fn sub(self, other: T) -> $name {
1422 *self - other
1423 }
1424 }
1425
1426 impl $crate::core_::ops::SubAssign<$name> for $name {
1427 fn sub_assign(&mut self, other: $name) {
1428 let (result, overflow) = self.overflowing_sub(other);
1429 $crate::panic_on_overflow!(overflow);
1430 *self = result
1431 }
1432 }
1433
1434 $crate::impl_mul_from!($name, $name);
1436 $crate::impl_mul_for_primitive!($name, u8);
1437 $crate::impl_mul_for_primitive!($name, u16);
1438 $crate::impl_mul_for_primitive!($name, u32);
1439 $crate::impl_mul_for_primitive!($name, u64);
1440 $crate::impl_mul_for_primitive!($name, usize);
1441 $crate::impl_mul_for_primitive!($name, i8);
1442 $crate::impl_mul_for_primitive!($name, i16);
1443 $crate::impl_mul_for_primitive!($name, i32);
1444 $crate::impl_mul_for_primitive!($name, i64);
1445 $crate::impl_mul_for_primitive!($name, isize);
1446
1447 impl<T> $crate::core_::ops::Div<T> for $name where T: Into<$name> {
1448 type Output = $name;
1449
1450 fn div(self, other: T) -> $name {
1451 let other: Self = other.into();
1452 self.div_mod(other).0
1453 }
1454 }
1455
1456 impl<'a, T> $crate::core_::ops::Div<T> for &'a $name where T: Into<$name> {
1457 type Output = $name;
1458
1459 fn div(self, other: T) -> $name {
1460 *self / other
1461 }
1462 }
1463
1464 impl<T> $crate::core_::ops::DivAssign<T> for $name where T: Into<$name> {
1465 fn div_assign(&mut self, other: T) {
1466 *self = *self / other.into();
1467 }
1468 }
1469
1470 impl<T> $crate::core_::ops::Rem<T> for $name where T: Into<$name> + Copy {
1471 type Output = $name;
1472
1473 fn rem(self, other: T) -> $name {
1474 let mut sub_copy = self;
1475 sub_copy %= other;
1476 sub_copy
1477 }
1478 }
1479
1480 impl<'a, T> $crate::core_::ops::Rem<T> for &'a $name where T: Into<$name> + Copy {
1481 type Output = $name;
1482
1483 fn rem(self, other: T) -> $name {
1484 *self % other
1485 }
1486 }
1487
1488 impl<T> $crate::core_::ops::RemAssign<T> for $name where T: Into<$name> + Copy {
1489 fn rem_assign(&mut self, other: T) {
1490 let other: Self = other.into();
1491 let rem = self.div_mod(other).1;
1492 *self = rem;
1493 }
1494 }
1495
1496 impl $crate::core_::ops::BitAnd<$name> for $name {
1497 type Output = $name;
1498
1499 #[inline]
1500 fn bitand(self, other: $name) -> $name {
1501 let $name(ref arr1) = self;
1502 let $name(ref arr2) = other;
1503 let mut ret = [0u64; $n_words];
1504 for i in 0..$n_words {
1505 ret[i] = arr1[i] & arr2[i];
1506 }
1507 $name(ret)
1508 }
1509 }
1510
1511 impl $crate::core_::ops::BitAndAssign<$name> for $name {
1512 fn bitand_assign(&mut self, rhs: $name) {
1513 *self = *self & rhs;
1514 }
1515 }
1516
1517 impl $crate::core_::ops::BitXor<$name> for $name {
1518 type Output = $name;
1519
1520 #[inline]
1521 fn bitxor(self, other: $name) -> $name {
1522 let $name(ref arr1) = self;
1523 let $name(ref arr2) = other;
1524 let mut ret = [0u64; $n_words];
1525 for i in 0..$n_words {
1526 ret[i] = arr1[i] ^ arr2[i];
1527 }
1528 $name(ret)
1529 }
1530 }
1531
1532 impl $crate::core_::ops::BitXorAssign<$name> for $name {
1533 fn bitxor_assign(&mut self, rhs: $name) {
1534 *self = *self ^ rhs;
1535 }
1536 }
1537
1538 impl $crate::core_::ops::BitOr<$name> for $name {
1539 type Output = $name;
1540
1541 #[inline]
1542 fn bitor(self, other: $name) -> $name {
1543 let $name(ref arr1) = self;
1544 let $name(ref arr2) = other;
1545 let mut ret = [0u64; $n_words];
1546 for i in 0..$n_words {
1547 ret[i] = arr1[i] | arr2[i];
1548 }
1549 $name(ret)
1550 }
1551 }
1552
1553 impl $crate::core_::ops::BitOrAssign<$name> for $name {
1554 fn bitor_assign(&mut self, rhs: $name) {
1555 *self = *self | rhs;
1556 }
1557 }
1558
1559 impl $crate::core_::ops::Not for $name {
1560 type Output = $name;
1561
1562 #[inline]
1563 fn not(self) -> $name {
1564 let $name(ref arr) = self;
1565 let mut ret = [0u64; $n_words];
1566 for i in 0..$n_words {
1567 ret[i] = !arr[i];
1568 }
1569 $name(ret)
1570 }
1571 }
1572
1573 impl<T> $crate::core_::ops::Shl<T> for $name where T: Into<$name> {
1574 type Output = $name;
1575
1576 fn shl(self, shift: T) -> $name {
1577 let shift = shift.into().as_usize();
1578 let $name(ref original) = self;
1579 let mut ret = [0u64; $n_words];
1580 let word_shift = shift / 64;
1581 let bit_shift = shift % 64;
1582
1583 for i in word_shift..$n_words {
1585 ret[i] = original[i - word_shift] << bit_shift;
1586 }
1587 if bit_shift > 0 {
1589 for i in word_shift+1..$n_words {
1590 ret[i] += original[i - 1 - word_shift] >> (64 - bit_shift);
1591 }
1592 }
1593 $name(ret)
1594 }
1595 }
1596
1597 impl<'a, T> $crate::core_::ops::Shl<T> for &'a $name where T: Into<$name> {
1598 type Output = $name;
1599 fn shl(self, shift: T) -> $name {
1600 *self << shift
1601 }
1602 }
1603
1604 impl<T> $crate::core_::ops::ShlAssign<T> for $name where T: Into<$name> {
1605 fn shl_assign(&mut self, shift: T) {
1606 *self = *self << shift;
1607 }
1608 }
1609
1610 impl<T> $crate::core_::ops::Shr<T> for $name where T: Into<$name> {
1611 type Output = $name;
1612
1613 fn shr(self, shift: T) -> $name {
1614 let shift = shift.into().as_usize();
1615 let $name(ref original) = self;
1616 let mut ret = [0u64; $n_words];
1617 let word_shift = shift / 64;
1618 let bit_shift = shift % 64;
1619
1620 for i in word_shift..$n_words {
1622 ret[i - word_shift] = original[i] >> bit_shift;
1623 }
1624
1625 if bit_shift > 0 {
1627 for i in word_shift+1..$n_words {
1628 ret[i - word_shift - 1] += original[i] << (64 - bit_shift);
1629 }
1630 }
1631
1632 $name(ret)
1633 }
1634 }
1635
1636 impl<'a, T> $crate::core_::ops::Shr<T> for &'a $name where T: Into<$name> {
1637 type Output = $name;
1638 fn shr(self, shift: T) -> $name {
1639 *self >> shift
1640 }
1641 }
1642
1643 impl<T> $crate::core_::ops::ShrAssign<T> for $name where T: Into<$name> {
1644 fn shr_assign(&mut self, shift: T) {
1645 *self = *self >> shift;
1646 }
1647 }
1648
1649 impl $crate::core_::cmp::Ord for $name {
1650 fn cmp(&self, other: &$name) -> $crate::core_::cmp::Ordering {
1651 self.as_ref().iter().rev().cmp(other.as_ref().iter().rev())
1652 }
1653 }
1654
1655 impl $crate::core_::cmp::PartialOrd for $name {
1656 fn partial_cmp(&self, other: &$name) -> Option<$crate::core_::cmp::Ordering> {
1657 Some(self.cmp(other))
1658 }
1659 }
1660
1661 impl $crate::core_::fmt::Debug for $name {
1662 fn fmt(&self, f: &mut $crate::core_::fmt::Formatter) -> $crate::core_::fmt::Result {
1663 $crate::core_::fmt::Display::fmt(self, f)
1664 }
1665 }
1666
1667 impl $crate::core_::fmt::Display for $name {
1668 fn fmt(&self, f: &mut $crate::core_::fmt::Formatter) -> $crate::core_::fmt::Result {
1669 if self.is_zero() {
1670 return $crate::core_::write!(f, "0");
1671 }
1672
1673 let mut buf = [0_u8; $n_words*20];
1674 let mut i = buf.len() - 1;
1675 let mut current = *self;
1676 let ten = $name::from(10);
1677
1678 loop {
1679 let digit = (current % ten).low_u64() as u8;
1680 buf[i] = digit + b'0';
1681 current = current / ten;
1682 if current.is_zero() {
1683 break;
1684 }
1685 i -= 1;
1686 }
1687
1688 let s = unsafe {
1690 $crate::core_::str::from_utf8_unchecked(&buf[i..])
1691 };
1692 f.pad_integral(true, "", s)
1693 }
1694 }
1695
1696 impl $crate::core_::fmt::LowerHex for $name {
1697 fn fmt(&self, f: &mut $crate::core_::fmt::Formatter) -> $crate::core_::fmt::Result {
1698 self.fmt_hex(f, true)
1699 }
1700 }
1701
1702 impl $crate::core_::fmt::UpperHex for $name {
1703 fn fmt(&self, f: &mut $crate::core_::fmt::Formatter) -> $crate::core_::fmt::Result {
1704 self.fmt_hex(f, false)
1705 }
1706 }
1707
1708 impl $crate::core_::str::FromStr for $name {
1709 type Err = $crate::FromHexError;
1710
1711 fn from_str(value: &str) -> $crate::core_::result::Result<$name, Self::Err> {
1712 let value = value.strip_prefix("0x").unwrap_or(value);
1713 const BYTES_LEN: usize = $n_words * 8;
1714 const MAX_ENCODED_LEN: usize = BYTES_LEN * 2;
1715
1716 let mut bytes = [0_u8; BYTES_LEN];
1717
1718 let encoded = value.as_bytes();
1719
1720 if encoded.len() > MAX_ENCODED_LEN {
1721 return Err($crate::hex::FromHexError::InvalidStringLength.into());
1722 }
1723
1724 if encoded.len() % 2 == 0 {
1725 let out = &mut bytes[BYTES_LEN - encoded.len() / 2..];
1726
1727 $crate::hex::decode_to_slice(encoded, out).map_err(Self::Err::from)?;
1728 } else {
1729 let mut s = [b'0'; MAX_ENCODED_LEN];
1731 s[MAX_ENCODED_LEN - encoded.len()..].copy_from_slice(encoded);
1732 let encoded = &s[MAX_ENCODED_LEN - encoded.len() - 1..];
1733
1734 let out = &mut bytes[BYTES_LEN - encoded.len() / 2..];
1735
1736 $crate::hex::decode_to_slice(encoded, out).map_err(Self::Err::from)?;
1737 }
1738
1739 let bytes_ref: &[u8] = &bytes;
1740 Ok(From::from(bytes_ref))
1741 }
1742 }
1743
1744 impl $crate::core_::convert::From<&'static str> for $name {
1745 fn from(s: &'static str) -> Self {
1746 s.parse().unwrap()
1747 }
1748 }
1749
1750 $crate::impl_quickcheck_arbitrary_for_uint!($name, ($n_words * 8));
1753 $crate::impl_arbitrary_for_uint!($name, ($n_words * 8));
1754 }
1755}
1756
1757#[cfg(feature = "quickcheck")]
1758#[macro_export]
1759#[doc(hidden)]
1760macro_rules! impl_quickcheck_arbitrary_for_uint {
1761 ($uint: ty, $n_bytes: tt) => {
1762 impl $crate::quickcheck::Arbitrary for $uint {
1763 fn arbitrary(g: &mut $crate::quickcheck::Gen) -> Self {
1764 let p = usize::arbitrary(g) % 100;
1765 let range =
1768 if p < 10 {
1770 $n_bytes
1771 } else if p < 20 {
1773 $n_bytes / 2
1774 } else {
1776 $n_bytes / 5
1777 };
1778
1779 let range = $crate::core_::cmp::max(range, 1);
1780 let size: usize = usize::arbitrary(g) % range;
1781
1782 let res: [u8; $n_bytes] = $crate::core_::array::from_fn(|i| {
1783 if i > size {
1784 0
1785 } else {
1786 u8::arbitrary(g)
1787 }
1788 });
1789
1790 res.as_ref().into()
1791 }
1792 }
1793 };
1794}
1795
1796#[cfg(not(feature = "quickcheck"))]
1797#[macro_export]
1798#[doc(hidden)]
1799macro_rules! impl_quickcheck_arbitrary_for_uint {
1800 ($uint: ty, $n_bytes: tt) => {};
1801}
1802
1803#[cfg(feature = "arbitrary")]
1804#[macro_export]
1805#[doc(hidden)]
1806macro_rules! impl_arbitrary_for_uint {
1807 ($uint: ty, $n_bytes: tt) => {
1808 impl $crate::arbitrary::Arbitrary<'_> for $uint {
1809 fn arbitrary(u: &mut $crate::arbitrary::Unstructured<'_>) -> $crate::arbitrary::Result<Self> {
1810 let mut res = [0u8; $n_bytes];
1811 u.fill_buffer(&mut res)?;
1812 Ok(Self::from(res))
1813 }
1814 }
1815 };
1816}
1817
1818#[cfg(not(feature = "arbitrary"))]
1819#[macro_export]
1820#[doc(hidden)]
1821macro_rules! impl_arbitrary_for_uint {
1822 ($uint: ty, $n_bytes: tt) => {};
1823}