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, Eq)]
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) -> [u8; $n_words * 8] {
749 let mut bytes = [0u8; $n_words * 8];
750 self.write_as_big_endian(&mut bytes);
751 bytes
752 }
753
754 #[inline]
756 pub fn write_as_big_endian(&self, bytes: &mut [u8]) {
757 use $crate::byteorder::{ByteOrder, BigEndian};
758 debug_assert!($n_words * 8 == bytes.len());
759 for i in 0..$n_words {
760 BigEndian::write_u64(&mut bytes[8 * i..], self.0[$n_words - i - 1]);
761 }
762 }
763
764 #[inline]
766 pub fn to_little_endian(&self) -> [u8; $n_words * 8] {
767 let mut bytes = [0u8; $n_words * 8];
768 self.write_as_little_endian(&mut bytes);
769 bytes
770 }
771
772 #[inline]
773 pub fn write_as_little_endian(&self, bytes: &mut [u8]) {
774 use $crate::byteorder::{ByteOrder, LittleEndian};
775 debug_assert!($n_words * 8 == bytes.len());
776 for i in 0..$n_words {
777 LittleEndian::write_u64(&mut bytes[8 * i..], self.0[i]);
778 }
779 }
780
781
782 #[inline]
788 pub fn exp10(n: usize) -> Self {
789 match n {
790 0 => Self::from(1u64),
791 _ => Self::exp10(n - 1) * 10u32
792 }
793 }
794
795 #[inline]
797 pub const fn zero() -> Self {
798 Self([0; $n_words])
799 }
800
801 #[inline]
803 pub const fn one() -> Self {
804 let mut words = [0; $n_words];
805 words[0] = 1u64;
806 Self(words)
807 }
808
809 #[inline]
811 pub const fn max_value() -> Self {
812 Self::MAX
813 }
814
815 fn full_shl(self, shift: u32) -> [u64; $n_words + 1] {
816 debug_assert!(shift < Self::WORD_BITS as u32);
817 let mut u = [0u64; $n_words + 1];
818 let u_lo = self.0[0] << shift;
819 let u_hi = self >> (Self::WORD_BITS as u32 - shift);
820 u[0] = u_lo;
821 u[1..].copy_from_slice(&u_hi.0[..]);
822 u
823 }
824
825 fn full_shr(u: [u64; $n_words + 1], shift: u32) -> Self {
826 debug_assert!(shift < Self::WORD_BITS as u32);
827 let mut res = Self::zero();
828 for i in 0..$n_words {
829 res.0[i] = u[i] >> shift;
830 }
831 if shift > 0 {
833 for i in 1..=$n_words {
834 res.0[i - 1] |= u[i] << (Self::WORD_BITS as u32 - shift);
835 }
836 }
837 res
838 }
839
840 fn full_mul_u64(self, by: u64) -> [u64; $n_words + 1] {
841 let (prod, carry) = self.overflowing_mul_u64(by);
842 let mut res = [0u64; $n_words + 1];
843 res[..$n_words].copy_from_slice(&prod.0[..]);
844 res[$n_words] = carry;
845 res
846 }
847
848 fn div_mod_small(mut self, other: u64) -> (Self, Self) {
849 let mut rem = 0u64;
850 self.0.iter_mut().rev().for_each(|d| {
851 let (q, r) = Self::div_mod_word(rem, *d, other);
852 *d = q;
853 rem = r;
854 });
855 (self, rem.into())
856 }
857
858 fn div_mod_knuth(self, mut v: Self, n: usize, m: usize) -> (Self, Self) {
860 debug_assert!(self.bits() >= v.bits() && !v.fits_word());
861 debug_assert!(n + m <= $n_words);
862 let shift = v.0[n - 1].leading_zeros();
867 v <<= shift;
868 let mut u = self.full_shl(shift);
870
871 let mut q = Self::zero();
873 let v_n_1 = v.0[n - 1];
874 let v_n_2 = v.0[n - 2];
875
876 for j in (0..=m).rev() {
879 let u_jn = u[j + n];
880
881 let mut q_hat = if u_jn < v_n_1 {
887 let (mut q_hat, mut r_hat) = Self::div_mod_word(u_jn, u[j + n - 1], v_n_1);
888 loop {
890 let (hi, lo) = Self::split_u128(u128::from(q_hat) * u128::from(v_n_2));
892 if (hi, lo) <= (r_hat, u[j + n - 2]) {
893 break;
894 }
895 q_hat -= 1;
897 let (new_r_hat, overflow) = r_hat.overflowing_add(v_n_1);
898 r_hat = new_r_hat;
899 if overflow {
901 break;
902 }
903 }
904 q_hat
905 } else {
906 u64::max_value()
908 };
909
910 let q_hat_v = v.full_mul_u64(q_hat);
918 let c = Self::sub_slice(&mut u[j..], &q_hat_v[..n + 1]);
920
921 if c {
925 q_hat -= 1;
926 let c = Self::add_slice(&mut u[j..], &v.0[..n]);
928 u[j + n] = u[j + n].wrapping_add(u64::from(c));
929 }
930
931 q.0[j] = q_hat;
933 }
934
935 let remainder = Self::full_shr(u, shift);
937
938 (q, remainder)
939 }
940
941 fn words(bits: usize) -> usize {
943 debug_assert!(bits > 0);
944 1 + (bits - 1) / Self::WORD_BITS
945 }
946
947 pub fn div_mod(mut self, mut other: Self) -> (Self, Self) {
953 use $crate::core_::cmp::Ordering;
954
955 let my_bits = self.bits();
956 let your_bits = other.bits();
957
958 assert!(your_bits != 0, "division by zero");
959
960 if my_bits < your_bits {
962 return (Self::zero(), self);
963 }
964
965 if your_bits <= Self::WORD_BITS {
966 return self.div_mod_small(other.low_u64());
967 }
968
969 let (n, m) = {
970 let my_words = Self::words(my_bits);
971 let your_words = Self::words(your_bits);
972 (your_words, my_words - your_words)
973 };
974
975 self.div_mod_knuth(other, n, m)
976 }
977
978 pub fn integer_sqrt(&self) -> Self {
980 let one = Self::one();
981 if self <= &one {
982 return *self;
983 }
984
985 let shift: u32 = (self.bits() as u32 + 1) / 2;
990 let mut x_prev = one << shift;
991 loop {
992 let x = (x_prev + self / x_prev) >> 1;
993 if x >= x_prev {
994 return x_prev;
995 }
996 x_prev = x;
997 }
998 }
999
1000 pub fn pow(self, expon: Self) -> Self {
1007 if expon.is_zero() {
1008 return Self::one()
1009 }
1010 let is_even = |x : &Self| x.low_u64() & 1 == 0;
1011
1012 let u_one = Self::one();
1013 let mut y = u_one;
1014 let mut n = expon;
1015 let mut x = self;
1016 while n > u_one {
1017 if is_even(&n) {
1018 x = x * x;
1019 n >>= 1usize;
1020 } else {
1021 y = x * y;
1022 x = x * x;
1023 n.0[$n_words-1] &= (!0u64)>>1;
1025 n >>= 1usize;
1026 }
1027 }
1028 x * y
1029 }
1030
1031 pub fn overflowing_pow(self, expon: Self) -> (Self, bool) {
1033 if expon.is_zero() { return (Self::one(), false) }
1034
1035 let is_even = |x : &Self| x.low_u64() & 1 == 0;
1036
1037 let u_one = Self::one();
1038 let mut y = u_one;
1039 let mut n = expon;
1040 let mut x = self;
1041 let mut overflow = false;
1042
1043 while n > u_one {
1044 if is_even(&n) {
1045 x = $crate::overflowing!(x.overflowing_mul(x), overflow);
1046 n >>= 1usize;
1047 } else {
1048 y = $crate::overflowing!(x.overflowing_mul(y), overflow);
1049 x = $crate::overflowing!(x.overflowing_mul(x), overflow);
1050 n = (n - u_one) >> 1usize;
1051 }
1052 }
1053 let res = $crate::overflowing!(x.overflowing_mul(y), overflow);
1054 (res, overflow)
1055 }
1056
1057 pub fn checked_pow(self, expon: $name) -> Option<$name> {
1059 match self.overflowing_pow(expon) {
1060 (_, true) => None,
1061 (val, _) => Some(val),
1062 }
1063 }
1064
1065 #[inline(always)]
1067 pub fn overflowing_add(self, other: $name) -> ($name, bool) {
1068 $crate::uint_overflowing_binop!(
1069 $name,
1070 $n_words,
1071 self,
1072 other,
1073 u64::overflowing_add
1074 )
1075 }
1076
1077 pub fn saturating_add(self, other: $name) -> $name {
1079 match self.overflowing_add(other) {
1080 (_, true) => $name::MAX,
1081 (val, false) => val,
1082 }
1083 }
1084
1085 pub fn checked_add(self, other: $name) -> Option<$name> {
1087 match self.overflowing_add(other) {
1088 (_, true) => None,
1089 (val, _) => Some(val),
1090 }
1091 }
1092
1093 #[inline(always)]
1095 pub fn overflowing_sub(self, other: $name) -> ($name, bool) {
1096 $crate::uint_overflowing_binop!(
1097 $name,
1098 $n_words,
1099 self,
1100 other,
1101 u64::overflowing_sub
1102 )
1103 }
1104
1105 pub fn saturating_sub(self, other: $name) -> $name {
1107 match self.overflowing_sub(other) {
1108 (_, true) => $name::zero(),
1109 (val, false) => val,
1110 }
1111 }
1112
1113 pub fn checked_sub(self, other: $name) -> Option<$name> {
1115 match self.overflowing_sub(other) {
1116 (_, true) => None,
1117 (val, _) => Some(val),
1118 }
1119 }
1120
1121 pub fn abs_diff(self, other: $name) -> $name {
1123 if self > other {
1124 self.overflowing_sub(other).0
1125 } else {
1126 other.overflowing_sub(self).0
1127 }
1128 }
1129
1130 #[inline(always)]
1132 pub fn overflowing_mul(self, other: $name) -> ($name, bool) {
1133 $crate::uint_overflowing_mul!($name, $n_words, self, other)
1134 }
1135
1136 pub fn saturating_mul(self, other: $name) -> $name {
1138 match self.overflowing_mul(other) {
1139 (_, true) => $name::MAX,
1140 (val, false) => val,
1141 }
1142 }
1143
1144 pub fn checked_mul(self, other: $name) -> Option<$name> {
1146 match self.overflowing_mul(other) {
1147 (_, true) => None,
1148 (val, _) => Some(val),
1149 }
1150 }
1151
1152 pub fn checked_div(self, other: $name) -> Option<$name> {
1154 if other.is_zero() {
1155 None
1156 } else {
1157 Some(self / other)
1158 }
1159 }
1160
1161 pub fn checked_rem(self, other: $name) -> Option<$name> {
1163 if other.is_zero() {
1164 None
1165 } else {
1166 Some(self % other)
1167 }
1168 }
1169
1170 pub fn overflowing_neg(self) -> ($name, bool) {
1172 if self.is_zero() {
1173 (self, false)
1174 } else {
1175 (!self + 1, true)
1176 }
1177 }
1178
1179 pub fn checked_neg(self) -> Option<$name> {
1181 match self.overflowing_neg() {
1182 (_, true) => None,
1183 (zero, false) => Some(zero),
1184 }
1185 }
1186
1187 #[inline(always)]
1188 fn div_mod_word(hi: u64, lo: u64, y: u64) -> (u64, u64) {
1189 debug_assert!(hi < y);
1190 let x = (u128::from(hi) << 64) + u128::from(lo);
1191 let y = u128::from(y);
1192 ((x / y) as u64, (x % y) as u64)
1193 }
1194
1195 #[inline(always)]
1196 fn add_slice(a: &mut [u64], b: &[u64]) -> bool {
1197 Self::binop_slice(a, b, u64::overflowing_add)
1198 }
1199
1200 #[inline(always)]
1201 fn sub_slice(a: &mut [u64], b: &[u64]) -> bool {
1202 Self::binop_slice(a, b, u64::overflowing_sub)
1203 }
1204
1205 #[inline(always)]
1206 fn binop_slice(a: &mut [u64], b: &[u64], binop: impl Fn(u64, u64) -> (u64, bool) + Copy) -> bool {
1207 let mut c = false;
1208 a.iter_mut().zip(b.iter()).for_each(|(x, y)| {
1209 let (res, carry) = Self::binop_carry(*x, *y, c, binop);
1210 *x = res;
1211 c = carry;
1212 });
1213 c
1214 }
1215
1216 #[inline(always)]
1217 fn binop_carry(a: u64, b: u64, c: bool, binop: impl Fn(u64, u64) -> (u64, bool)) -> (u64, bool) {
1218 let (res1, overflow1) = b.overflowing_add(u64::from(c));
1219 let (res2, overflow2) = binop(a, res1);
1220 (res2, overflow1 || overflow2)
1221 }
1222
1223 #[inline(always)]
1224 const fn mul_u64(a: u64, b: u64, carry: u64) -> (u64, u64) {
1225 let (hi, lo) = Self::split_u128(a as u128 * b as u128 + carry as u128);
1226 (lo, hi)
1227 }
1228
1229 #[inline(always)]
1230 const fn split(a: u64) -> (u64, u64) {
1231 (a >> 32, a & 0xFFFF_FFFF)
1232 }
1233
1234 #[inline(always)]
1235 const fn split_u128(a: u128) -> (u64, u64) {
1236 ((a >> 64) as _, (a & 0xFFFFFFFFFFFFFFFF) as _)
1237 }
1238
1239
1240 fn overflowing_mul_u64(mut self, other: u64) -> (Self, u64) {
1243 let mut carry = 0u64;
1244
1245 for d in self.0.iter_mut() {
1246 let (res, c) = Self::mul_u64(*d, other, carry);
1247 *d = res;
1248 carry = c;
1249 }
1250
1251 (self, carry)
1252 }
1253
1254 pub fn from_big_endian(slice: &[u8]) -> Self {
1256 use $crate::byteorder::{ByteOrder, BigEndian};
1257 assert!($n_words * 8 >= slice.len());
1258
1259 let mut padded = [0u8; $n_words * 8];
1260 padded[$n_words * 8 - slice.len() .. $n_words * 8].copy_from_slice(&slice);
1261
1262 let mut ret = [0; $n_words];
1263 for i in 0..$n_words {
1264 ret[$n_words - i - 1] = BigEndian::read_u64(&padded[8 * i..]);
1265 }
1266
1267 $name(ret)
1268 }
1269
1270 pub fn from_little_endian(slice: &[u8]) -> Self {
1272 use $crate::byteorder::{ByteOrder, LittleEndian};
1273 assert!($n_words * 8 >= slice.len());
1274
1275 let mut padded = [0u8; $n_words * 8];
1276 padded[0..slice.len()].copy_from_slice(&slice);
1277
1278 let mut ret = [0; $n_words];
1279 for i in 0..$n_words {
1280 ret[i] = LittleEndian::read_u64(&padded[8 * i..]);
1281 }
1282
1283 $name(ret)
1284 }
1285
1286 fn fmt_hex(&self, f: &mut $crate::core_::fmt::Formatter, is_lower: bool) -> $crate::core_::fmt::Result {
1287 let &$name(ref data) = self;
1288 if self.is_zero() {
1290 return f.pad_integral(true, "0x", "0");
1291 }
1292
1293 let mut latch = false;
1294 let mut buf = [0_u8; $n_words * 16];
1295 let mut i = 0;
1296 for ch in data.iter().rev() {
1297 for x in 0..16 {
1298 let nibble = (ch & (15u64 << ((15 - x) * 4) as u64)) >> (((15 - x) * 4) as u64);
1300 if !latch {
1301 latch = nibble != 0;
1302 }
1303
1304 if latch {
1305 let nibble = match nibble {
1307 0..=9 => nibble as u8 + b'0',
1308 _ if is_lower => nibble as u8 - 10 + b'a',
1309 _ => nibble as u8 - 10 + b'A',
1310 };
1311 buf[i] = nibble;
1312 i += 1;
1313 }
1314 }
1315 }
1316
1317 let s = unsafe {
1319 $crate::core_::str::from_utf8_unchecked(&buf[0..i])
1320 };
1321 f.pad_integral(true, "0x", s)
1322 }
1323 }
1324
1325 impl $crate::core_::default::Default for $name {
1326 fn default() -> Self {
1327 $name::zero()
1328 }
1329 }
1330
1331 impl $crate::core_::convert::From<u64> for $name {
1332 fn from(value: u64) -> $name {
1333 let mut ret = [0; $n_words];
1334 ret[0] = value;
1335 $name(ret)
1336 }
1337 }
1338
1339 $crate::impl_map_from!($name, u8, u64);
1340 $crate::impl_map_from!($name, u16, u64);
1341 $crate::impl_map_from!($name, u32, u64);
1342 $crate::impl_map_from!($name, usize, u64);
1343
1344 impl $crate::core_::convert::From<i64> for $name {
1345 fn from(value: i64) -> $name {
1346 match value >= 0 {
1347 true => From::from(value as u64),
1348 false => { panic!("Unsigned integer can't be created from negative value"); }
1349 }
1350 }
1351 }
1352
1353 $crate::impl_map_from!($name, i8, i64);
1354 $crate::impl_map_from!($name, i16, i64);
1355 $crate::impl_map_from!($name, i32, i64);
1356 $crate::impl_map_from!($name, isize, i64);
1357
1358 $crate::impl_try_from_for_primitive!($name, u8);
1359 $crate::impl_try_from_for_primitive!($name, u16);
1360 $crate::impl_try_from_for_primitive!($name, u32);
1361 $crate::impl_try_from_for_primitive!($name, usize);
1362 $crate::impl_try_from_for_primitive!($name, u64);
1363 $crate::impl_try_from_for_primitive!($name, i8);
1364 $crate::impl_try_from_for_primitive!($name, i16);
1365 $crate::impl_try_from_for_primitive!($name, i32);
1366 $crate::impl_try_from_for_primitive!($name, isize);
1367 $crate::impl_try_from_for_primitive!($name, i64);
1368
1369 impl<T> $crate::core_::ops::Add<T> for $name where T: Into<$name> {
1370 type Output = $name;
1371
1372 fn add(self, other: T) -> $name {
1373 let (result, overflow) = self.overflowing_add(other.into());
1374 $crate::panic_on_overflow!(overflow);
1375 result
1376 }
1377 }
1378
1379 impl<'a, T> $crate::core_::ops::Add<T> for &'a $name where T: Into<$name> {
1380 type Output = $name;
1381
1382 fn add(self, other: T) -> $name {
1383 *self + other
1384 }
1385 }
1386
1387 impl $crate::core_::ops::AddAssign<$name> for $name {
1388 fn add_assign(&mut self, other: $name) {
1389 let (result, overflow) = self.overflowing_add(other);
1390 $crate::panic_on_overflow!(overflow);
1391 *self = result
1392 }
1393 }
1394
1395 impl<T> $crate::core_::ops::Sub<T> for $name where T: Into<$name> {
1396 type Output = $name;
1397
1398 #[inline]
1399 fn sub(self, other: T) -> $name {
1400 let (result, overflow) = self.overflowing_sub(other.into());
1401 $crate::panic_on_overflow!(overflow);
1402 result
1403 }
1404 }
1405
1406 impl<'a, T> $crate::core_::ops::Sub<T> for &'a $name where T: Into<$name> {
1407 type Output = $name;
1408
1409 fn sub(self, other: T) -> $name {
1410 *self - other
1411 }
1412 }
1413
1414 impl $crate::core_::ops::SubAssign<$name> for $name {
1415 fn sub_assign(&mut self, other: $name) {
1416 let (result, overflow) = self.overflowing_sub(other);
1417 $crate::panic_on_overflow!(overflow);
1418 *self = result
1419 }
1420 }
1421
1422 $crate::impl_mul_from!($name, $name);
1424 $crate::impl_mul_for_primitive!($name, u8);
1425 $crate::impl_mul_for_primitive!($name, u16);
1426 $crate::impl_mul_for_primitive!($name, u32);
1427 $crate::impl_mul_for_primitive!($name, u64);
1428 $crate::impl_mul_for_primitive!($name, usize);
1429 $crate::impl_mul_for_primitive!($name, i8);
1430 $crate::impl_mul_for_primitive!($name, i16);
1431 $crate::impl_mul_for_primitive!($name, i32);
1432 $crate::impl_mul_for_primitive!($name, i64);
1433 $crate::impl_mul_for_primitive!($name, isize);
1434
1435 impl<T> $crate::core_::ops::Div<T> for $name where T: Into<$name> {
1436 type Output = $name;
1437
1438 fn div(self, other: T) -> $name {
1439 let other: Self = other.into();
1440 self.div_mod(other).0
1441 }
1442 }
1443
1444 impl<'a, T> $crate::core_::ops::Div<T> for &'a $name where T: Into<$name> {
1445 type Output = $name;
1446
1447 fn div(self, other: T) -> $name {
1448 *self / other
1449 }
1450 }
1451
1452 impl<T> $crate::core_::ops::DivAssign<T> for $name where T: Into<$name> {
1453 fn div_assign(&mut self, other: T) {
1454 *self = *self / other.into();
1455 }
1456 }
1457
1458 impl<T> $crate::core_::ops::Rem<T> for $name where T: Into<$name> + Copy {
1459 type Output = $name;
1460
1461 fn rem(self, other: T) -> $name {
1462 let mut sub_copy = self;
1463 sub_copy %= other;
1464 sub_copy
1465 }
1466 }
1467
1468 impl<'a, T> $crate::core_::ops::Rem<T> for &'a $name where T: Into<$name> + Copy {
1469 type Output = $name;
1470
1471 fn rem(self, other: T) -> $name {
1472 *self % other
1473 }
1474 }
1475
1476 impl<T> $crate::core_::ops::RemAssign<T> for $name where T: Into<$name> + Copy {
1477 fn rem_assign(&mut self, other: T) {
1478 let other: Self = other.into();
1479 let rem = self.div_mod(other).1;
1480 *self = rem;
1481 }
1482 }
1483
1484 impl $crate::core_::ops::BitAnd<$name> for $name {
1485 type Output = $name;
1486
1487 #[inline]
1488 fn bitand(self, other: $name) -> $name {
1489 let $name(ref arr1) = self;
1490 let $name(ref arr2) = other;
1491 let mut ret = [0u64; $n_words];
1492 for i in 0..$n_words {
1493 ret[i] = arr1[i] & arr2[i];
1494 }
1495 $name(ret)
1496 }
1497 }
1498
1499 impl $crate::core_::ops::BitAndAssign<$name> for $name {
1500 fn bitand_assign(&mut self, rhs: $name) {
1501 *self = *self & rhs;
1502 }
1503 }
1504
1505 impl $crate::core_::ops::BitXor<$name> for $name {
1506 type Output = $name;
1507
1508 #[inline]
1509 fn bitxor(self, other: $name) -> $name {
1510 let $name(ref arr1) = self;
1511 let $name(ref arr2) = other;
1512 let mut ret = [0u64; $n_words];
1513 for i in 0..$n_words {
1514 ret[i] = arr1[i] ^ arr2[i];
1515 }
1516 $name(ret)
1517 }
1518 }
1519
1520 impl $crate::core_::ops::BitXorAssign<$name> for $name {
1521 fn bitxor_assign(&mut self, rhs: $name) {
1522 *self = *self ^ rhs;
1523 }
1524 }
1525
1526 impl $crate::core_::ops::BitOr<$name> for $name {
1527 type Output = $name;
1528
1529 #[inline]
1530 fn bitor(self, other: $name) -> $name {
1531 let $name(ref arr1) = self;
1532 let $name(ref arr2) = other;
1533 let mut ret = [0u64; $n_words];
1534 for i in 0..$n_words {
1535 ret[i] = arr1[i] | arr2[i];
1536 }
1537 $name(ret)
1538 }
1539 }
1540
1541 impl $crate::core_::ops::BitOrAssign<$name> for $name {
1542 fn bitor_assign(&mut self, rhs: $name) {
1543 *self = *self | rhs;
1544 }
1545 }
1546
1547 impl $crate::core_::ops::Not for $name {
1548 type Output = $name;
1549
1550 #[inline]
1551 fn not(self) -> $name {
1552 let $name(ref arr) = self;
1553 let mut ret = [0u64; $n_words];
1554 for i in 0..$n_words {
1555 ret[i] = !arr[i];
1556 }
1557 $name(ret)
1558 }
1559 }
1560
1561 impl<T> $crate::core_::ops::Shl<T> for $name where T: Into<$name> {
1562 type Output = $name;
1563
1564 fn shl(self, shift: T) -> $name {
1565 let shift = shift.into().as_usize();
1566 let $name(ref original) = self;
1567 let mut ret = [0u64; $n_words];
1568 let word_shift = shift / 64;
1569 let bit_shift = shift % 64;
1570
1571 for i in word_shift..$n_words {
1573 ret[i] = original[i - word_shift] << bit_shift;
1574 }
1575 if bit_shift > 0 {
1577 for i in word_shift+1..$n_words {
1578 ret[i] += original[i - 1 - word_shift] >> (64 - bit_shift);
1579 }
1580 }
1581 $name(ret)
1582 }
1583 }
1584
1585 impl<'a, T> $crate::core_::ops::Shl<T> for &'a $name where T: Into<$name> {
1586 type Output = $name;
1587 fn shl(self, shift: T) -> $name {
1588 *self << shift
1589 }
1590 }
1591
1592 impl<T> $crate::core_::ops::ShlAssign<T> for $name where T: Into<$name> {
1593 fn shl_assign(&mut self, shift: T) {
1594 *self = *self << shift;
1595 }
1596 }
1597
1598 impl<T> $crate::core_::ops::Shr<T> for $name where T: Into<$name> {
1599 type Output = $name;
1600
1601 fn shr(self, shift: T) -> $name {
1602 let shift = shift.into().as_usize();
1603 let $name(ref original) = self;
1604 let mut ret = [0u64; $n_words];
1605 let word_shift = shift / 64;
1606 let bit_shift = shift % 64;
1607
1608 for i in word_shift..$n_words {
1610 ret[i - word_shift] = original[i] >> bit_shift;
1611 }
1612
1613 if bit_shift > 0 {
1615 for i in word_shift+1..$n_words {
1616 ret[i - word_shift - 1] += original[i] << (64 - bit_shift);
1617 }
1618 }
1619
1620 $name(ret)
1621 }
1622 }
1623
1624 impl<'a, T> $crate::core_::ops::Shr<T> for &'a $name where T: Into<$name> {
1625 type Output = $name;
1626 fn shr(self, shift: T) -> $name {
1627 *self >> shift
1628 }
1629 }
1630
1631 impl<T> $crate::core_::ops::ShrAssign<T> for $name where T: Into<$name> {
1632 fn shr_assign(&mut self, shift: T) {
1633 *self = *self >> shift;
1634 }
1635 }
1636
1637 impl $crate::core_::cmp::Ord for $name {
1638 fn cmp(&self, other: &$name) -> $crate::core_::cmp::Ordering {
1639 self.as_ref().iter().rev().cmp(other.as_ref().iter().rev())
1640 }
1641 }
1642
1643 impl $crate::core_::cmp::PartialOrd for $name {
1644 fn partial_cmp(&self, other: &$name) -> Option<$crate::core_::cmp::Ordering> {
1645 Some(self.cmp(other))
1646 }
1647 }
1648
1649 impl $crate::core_::fmt::Debug for $name {
1650 fn fmt(&self, f: &mut $crate::core_::fmt::Formatter) -> $crate::core_::fmt::Result {
1651 $crate::core_::fmt::Display::fmt(self, f)
1652 }
1653 }
1654
1655 impl $crate::core_::fmt::Display for $name {
1656 fn fmt(&self, f: &mut $crate::core_::fmt::Formatter) -> $crate::core_::fmt::Result {
1657 if self.is_zero() {
1658 return $crate::core_::write!(f, "0");
1659 }
1660
1661 let mut buf = [0_u8; $n_words*20];
1662 let mut i = buf.len() - 1;
1663 let mut current = *self;
1664 let ten = $name::from(10);
1665
1666 loop {
1667 let digit = (current % ten).low_u64() as u8;
1668 buf[i] = digit + b'0';
1669 current /= ten;
1670 if current.is_zero() {
1671 break;
1672 }
1673 i -= 1;
1674 }
1675
1676 let s = unsafe {
1678 $crate::core_::str::from_utf8_unchecked(&buf[i..])
1679 };
1680 f.pad_integral(true, "", s)
1681 }
1682 }
1683
1684 impl $crate::core_::fmt::LowerHex for $name {
1685 fn fmt(&self, f: &mut $crate::core_::fmt::Formatter) -> $crate::core_::fmt::Result {
1686 self.fmt_hex(f, true)
1687 }
1688 }
1689
1690 impl $crate::core_::fmt::UpperHex for $name {
1691 fn fmt(&self, f: &mut $crate::core_::fmt::Formatter) -> $crate::core_::fmt::Result {
1692 self.fmt_hex(f, false)
1693 }
1694 }
1695
1696 impl $crate::core_::str::FromStr for $name {
1697 type Err = $crate::FromHexError;
1698
1699 fn from_str(value: &str) -> $crate::core_::result::Result<$name, Self::Err> {
1700 let value = value.strip_prefix("0x").unwrap_or(value);
1701 const BYTES_LEN: usize = $n_words * 8;
1702 const MAX_ENCODED_LEN: usize = BYTES_LEN * 2;
1703
1704 let mut bytes = [0_u8; BYTES_LEN];
1705
1706 let encoded = value.as_bytes();
1707
1708 if encoded.len() > MAX_ENCODED_LEN {
1709 return Err($crate::hex::FromHexError::InvalidStringLength.into());
1710 }
1711
1712 if encoded.len() % 2 == 0 {
1713 let out = &mut bytes[BYTES_LEN - encoded.len() / 2..];
1714
1715 $crate::hex::decode_to_slice(encoded, out).map_err(Self::Err::from)?;
1716 } else {
1717 let mut s = [b'0'; MAX_ENCODED_LEN];
1719 s[MAX_ENCODED_LEN - encoded.len()..].copy_from_slice(encoded);
1720 let encoded = &s[MAX_ENCODED_LEN - encoded.len() - 1..];
1721
1722 let out = &mut bytes[BYTES_LEN - encoded.len() / 2..];
1723
1724 $crate::hex::decode_to_slice(encoded, out).map_err(Self::Err::from)?;
1725 }
1726
1727 Ok(Self::from_big_endian(&bytes))
1728 }
1729 }
1730
1731 impl $crate::core_::convert::From<&'static str> for $name {
1732 fn from(s: &'static str) -> Self {
1733 s.parse().unwrap()
1734 }
1735 }
1736
1737 $crate::impl_quickcheck_arbitrary_for_uint!($name, ($n_words * 8));
1740 $crate::impl_arbitrary_for_uint!($name, ($n_words * 8));
1741 }
1742}
1743
1744#[cfg(feature = "quickcheck")]
1745#[macro_export]
1746#[doc(hidden)]
1747macro_rules! impl_quickcheck_arbitrary_for_uint {
1748 ($uint: ty, $n_bytes: tt) => {
1749 impl $crate::quickcheck::Arbitrary for $uint {
1750 fn arbitrary(g: &mut $crate::quickcheck::Gen) -> Self {
1751 let p = usize::arbitrary(g) % 100;
1752 let range =
1755 if p < 10 {
1757 $n_bytes
1758 } else if p < 20 {
1760 $n_bytes / 2
1761 } else {
1763 $n_bytes / 5
1764 };
1765
1766 let range = $crate::core_::cmp::max(range, 1);
1767 let size: usize = usize::arbitrary(g) % range;
1768
1769 let res: [u8; $n_bytes] = $crate::core_::array::from_fn(|i| {
1770 if i > size {
1771 0
1772 } else {
1773 u8::arbitrary(g)
1774 }
1775 });
1776
1777 Self::from_big_endian(res.as_ref())
1778 }
1779 }
1780 };
1781}
1782
1783#[cfg(not(feature = "quickcheck"))]
1784#[macro_export]
1785#[doc(hidden)]
1786macro_rules! impl_quickcheck_arbitrary_for_uint {
1787 ($uint: ty, $n_bytes: tt) => {};
1788}
1789
1790#[cfg(feature = "arbitrary")]
1791#[macro_export]
1792#[doc(hidden)]
1793macro_rules! impl_arbitrary_for_uint {
1794 ($uint: ty, $n_bytes: tt) => {
1795 impl $crate::arbitrary::Arbitrary<'_> for $uint {
1796 fn arbitrary(u: &mut $crate::arbitrary::Unstructured<'_>) -> $crate::arbitrary::Result<Self> {
1797 let mut res = [0u8; $n_bytes];
1798 u.fill_buffer(&mut res)?;
1799 Ok(Self::from_big_endian(&res))
1800 }
1801 }
1802 };
1803}
1804
1805#[cfg(not(feature = "arbitrary"))]
1806#[macro_export]
1807#[doc(hidden)]
1808macro_rules! impl_arbitrary_for_uint {
1809 ($uint: ty, $n_bytes: tt) => {};
1810}