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