uint/
uint.rs

1// Copyright 2020 Parity Technologies
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9// Code derived from original work by Andrew Poelstra <apoelstra@wpsoftware.net>
10
11// Rust Bitcoin Library
12// Written in 2014 by
13//	   Andrew Poelstra <apoelstra@wpsoftware.net>
14//
15// To the extent possible under law, the author(s) have dedicated all
16// copyright and related and neighboring rights to this software to
17// the public domain worldwide. This software is distributed without
18// any warranty.
19//
20// You should have received a copy of the CC0 Public Domain Dedication
21// along with this software.
22// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
23//
24
25//! Big unsigned integer types.
26//!
27//! Implementation of a various large-but-fixed sized unsigned integer types.
28//! The functions here are designed to be fast. There are optional `x86_64`
29//! implementations for even more speed, hidden behind the `x64_arithmetic`
30//! feature flag.
31
32use core::fmt;
33
34/// A list of error categories encountered when parsing numbers.
35#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
36#[non_exhaustive]
37pub enum FromStrRadixErrKind {
38	/// A character in the input string is not valid for the given radix.
39	InvalidCharacter,
40
41	/// The input length is not valid for the given radix.
42	InvalidLength,
43
44	/// The given radix is not supported.
45	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/// The error type for parsing numbers from strings.
64#[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	/// Returns the corresponding `FromStrRadixErrKind` for this error.
77	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/// Conversion from decimal string error
131#[derive(Debug, PartialEq, Eq)]
132pub enum FromDecStrErr {
133	/// Char not from range 0-9
134	InvalidCharacter,
135	/// Value does not fit into type
136	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		// `unroll!` is recursive, but doesn’t use `$crate::unroll`, so we need to ensure that it
225		// is in scope unqualified.
226		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		// The safety of this is enforced by the compiler
314		let ret: [[u64; $n_words]; 2] = unsafe { $crate::core_::mem::transmute(ret) };
315
316		// The compiler WILL NOT inline this if you remove this annotation.
317		#[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				/// Low 2 words (u128)
498				#[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				/// Conversion to u128 with overflow checking
505				///
506				/// # Panics
507				///
508				/// Panics if the number is larger than 2^128.
509				#[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		/// Little-endian large integer type
554		#[repr(C)]
555		$(#[$attr])*
556		#[derive(Copy, Clone, Eq, PartialEq, Hash)]
557		$visibility struct $name (pub [u64; $n_words]);
558
559		/// Get a reference to the underlying little-endian words.
560		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			/// Maximum value.
576			pub const MAX: $name = $name([u64::max_value(); $n_words]);
577
578			/// Converts a string slice in a given base to an integer. Only supports radixes of 10
579			/// and 16.
580			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			/// Convert from a decimal string.
591			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			/// Conversion to u32
611			#[inline]
612			pub const fn low_u32(&self) -> u32 {
613				let &$name(ref arr) = self;
614				arr[0] as u32
615			}
616
617			/// Low word (u64)
618			#[inline]
619			pub const fn low_u64(&self) -> u64 {
620				let &$name(ref arr) = self;
621				arr[0]
622			}
623
624			/// Conversion to u32 with overflow checking
625			///
626			/// # Panics
627			///
628			/// Panics if the number is larger than 2^32.
629			#[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			/// Conversion to u64 with overflow checking
639			///
640			/// # Panics
641			///
642			/// Panics if the number is larger than u64::max_value().
643			#[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			/// Conversion to usize with overflow checking
653			///
654			/// # Panics
655			///
656			/// Panics if the number is larger than usize::max_value().
657			#[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			/// Whether this is zero.
667			#[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			// Whether this fits u64.
676			#[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			/// Return the least number of bits needed to represent the number
685			#[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			/// Return if specific bit is set.
695			///
696			/// # Panics
697			///
698			/// Panics if `index` exceeds the bit width of the number.
699			#[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			/// Returns the number of leading zeros in the binary representation of self.
706			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			/// Returns the number of trailing zeros in the binary representation of self.
721			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			/// Return specific byte. Byte 0 is the least significant value (ie~ little endian).
736			///
737			/// # Panics
738			///
739			/// Panics if `index` exceeds the byte width of the number.
740			#[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			/// Convert to big-endian bytes.
747			#[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			/// Write to the slice in big-endian format.
755			#[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			/// Convert to little-endian bytes.
765			#[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			/// Create `10**n` as this type.
783			///
784			/// # Panics
785			///
786			/// Panics if the result overflows the type.
787			#[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			/// Zero (additive identity) of this type.
796			#[inline]
797			pub const fn zero() -> Self {
798				Self([0; $n_words])
799			}
800
801			/// One (multiplicative identity) of this type.
802			#[inline]
803			pub const fn one() -> Self {
804				let mut words = [0; $n_words];
805				words[0] = 1u64;
806				Self(words)
807			}
808
809			/// The maximum value which can be inhabited by this type.
810			#[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				// carry
832				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			// See Knuth, TAOCP, Volume 2, section 4.3.1, Algorithm D.
859			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				// D1.
863				// Make sure 64th bit in v's highest word is set.
864				// If we shift both self and v, it won't affect the quotient
865				// and the remainder will only need to be shifted back.
866				let shift = v.0[n - 1].leading_zeros();
867				v <<= shift;
868				// u will store the remainder (shifted)
869				let mut u = self.full_shl(shift);
870
871				// quotient
872				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				// D2. D7.
877				// iterate from m downto 0
878				for j in (0..=m).rev() {
879					let u_jn = u[j + n];
880
881					// D3.
882					// q_hat is our guess for the j-th quotient digit
883					// q_hat = min(b - 1, (u_{j+n} * b + u_{j+n-1}) / v_{n-1})
884					// b = 1 << WORD_BITS
885					// Theorem B: q_hat >= q_j >= q_hat - 2
886					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						// this loop takes at most 2 iterations
889						loop {
890							// check if q_hat * v_{n-2} > b * r_hat + u_{j+n-2}
891							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							// then iterate till it doesn't hold
896							q_hat -= 1;
897							let (new_r_hat, overflow) = r_hat.overflowing_add(v_n_1);
898							r_hat = new_r_hat;
899							// if r_hat overflowed, we're done
900							if overflow {
901								break;
902							}
903						}
904						q_hat
905					} else {
906						// here q_hat >= q_j >= q_hat - 1
907						u64::max_value()
908					};
909
910					// ex. 20:
911					// since q_hat * v_{n-2} <= b * r_hat + u_{j+n-2},
912					// either q_hat == q_j, or q_hat == q_j + 1
913
914					// D4.
915					// let's assume optimistically q_hat == q_j
916					// subtract (q_hat * v) from u[j..]
917					let q_hat_v = v.full_mul_u64(q_hat);
918					// u[j..] -= q_hat_v;
919					let c = Self::sub_slice(&mut u[j..], &q_hat_v[..n + 1]);
920
921					// D6.
922					// actually, q_hat == q_j + 1 and u[j..] has overflowed
923					// highly unlikely ~ (1 / 2^63)
924					if c {
925						q_hat -= 1;
926						// add v to u[j..]
927						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					// D5.
932					q.0[j] = q_hat;
933				}
934
935				// D8.
936				let remainder = Self::full_shr(u, shift);
937
938				(q, remainder)
939			}
940
941			// Returns the least number of words needed to represent the nonzero number
942			fn words(bits: usize) -> usize {
943				debug_assert!(bits > 0);
944				1 + (bits - 1) / Self::WORD_BITS
945			}
946
947			/// Returns a pair `(self / other, self % other)`.
948			///
949			/// # Panics
950			///
951			/// Panics if `other` is zero.
952			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				// Early return in case we are dividing by a larger number than us
961				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			/// Compute the highest `n` such that `n * n <= self`.
979			pub fn integer_sqrt(&self) -> Self {
980				let one = Self::one();
981				if self <= &one {
982					return *self;
983				}
984
985				// the implementation is based on:
986				// https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division
987
988				// Set the initial guess to something higher than √self.
989				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			/// Fast exponentiation by squaring
1001			/// https://en.wikipedia.org/wiki/Exponentiation_by_squaring
1002			///
1003			/// # Panics
1004			///
1005			/// Panics if the result overflows the type.
1006			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						// to reduce odd number by 1 we should just clear the last bit
1024						n.0[$n_words-1] &= (!0u64)>>1;
1025						n >>= 1usize;
1026					}
1027				}
1028				x * y
1029			}
1030
1031			/// Fast exponentiation by squaring. Returns result and overflow flag.
1032			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			/// Checked exponentiation. Returns `None` if overflow occurred.
1058			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			/// Addition which overflows and returns a flag if it does.
1066			#[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			/// Addition which saturates at the maximum value (Self::MAX).
1078			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			/// Checked addition. Returns `None` if overflow occurred.
1086			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			/// Subtraction which underflows and returns a flag if it does.
1094			#[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			/// Subtraction which saturates at zero.
1106			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			/// Checked subtraction. Returns `None` if overflow occurred.
1114			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			/// Computes the absolute difference between self and other.
1122			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			/// Multiply with overflow, returning a flag if it does.
1131			#[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			/// Multiplication which saturates at the maximum value..
1137			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			/// Checked multiplication. Returns `None` if overflow occurred.
1145			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			/// Checked division. Returns `None` if `other == 0`.
1153			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			/// Checked modulus. Returns `None` if `other == 0`.
1162			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			/// Negation with overflow.
1171			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			/// Checked negation. Returns `None` unless `self == 0`.
1180			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			/// Overflowing multiplication by u64.
1241			/// Returns the result and carry.
1242			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			/// Converts from big endian representation bytes in memory.
1255			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			/// Converts from little endian representation bytes in memory.
1271			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				// special case.
1289				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						// nibble < 16
1299						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							// nibble is `'0'..'9' 'a'..'f' 'A'..'F'` because nibble < 16
1306							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				// sequence of `'0'..'9' 'a'..'f' 'A'..'F'` chars is guaranteed to be a valid UTF8 string
1318				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		// all other impls
1423		$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				// shift
1572				for i in word_shift..$n_words {
1573					ret[i] = original[i - word_shift] << bit_shift;
1574				}
1575				// carry
1576				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				// shift
1609				for i in word_shift..$n_words {
1610					ret[i - word_shift] = original[i] >> bit_shift;
1611				}
1612
1613				// Carry
1614				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				// sequence of `'0'..'9'` chars is guaranteed to be a valid UTF8 string
1677				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					// Prepend '0' by overlaying our value on a scratch buffer filled with '0' characters.
1718					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		// `$n_words * 8` because macro expects bytes and
1738		// uints use 64 bit (8 byte) words
1739		$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				// make it more likely to generate smaller numbers that
1753				// don't use up the full $n_bytes
1754				let range =
1755					// 10% chance to generate number that uses up to $n_bytes
1756					if p < 10 {
1757						$n_bytes
1758					// 10% chance to generate number that uses up to $n_bytes / 2
1759					} else if p < 20 {
1760						$n_bytes / 2
1761					// 80% chance to generate number that uses up to $n_bytes / 5
1762					} 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}