1
// This file is part of Substrate.
2

            
3
// Copyright (C) Parity Technologies (UK) Ltd.
4
// SPDX-License-Identifier: Apache-2.0
5

            
6
// Licensed under the Apache License, Version 2.0 (the "License");
7
// you may not use this file except in compliance with the License.
8
// You may obtain a copy of the License at
9
//
10
// 	http://www.apache.org/licenses/LICENSE-2.0
11
//
12
// Unless required by applicable law or agreed to in writing, software
13
// distributed under the License is distributed on an "AS IS" BASIS,
14
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
// See the License for the specific language governing permissions and
16
// limitations under the License.
17

            
18
//! Infinite precision unsigned integer for substrate runtime.
19

            
20
use alloc::{vec, vec::Vec};
21
use codec::{Decode, Encode};
22
use core::{cell::RefCell, cmp::Ordering, ops};
23
use num_traits::{One, Zero};
24

            
25
// A sensible value for this would be half of the dword size of the host machine. Since the
26
// runtime is compiled to 32bit webassembly, using 32 and 64 for single and double respectively
27
// should yield the most performance.
28

            
29
/// Representation of a single limb.
30
pub type Single = u32;
31
/// Representation of two limbs.
32
pub type Double = u64;
33
/// Difference in the number of bits of [`Single`] and [`Double`].
34
const SHIFT: usize = 32;
35
/// short form of _Base_. Analogous to the value 10 in base-10 decimal numbers.
36
const B: Double = Single::max_value() as Double + 1;
37

            
38
static_assertions::const_assert!(
39
	core::mem::size_of::<Double>() - core::mem::size_of::<Single>() == SHIFT / 8
40
);
41

            
42
/// Splits a [`Double`] limb number into a tuple of two [`Single`] limb numbers.
43
pub fn split(a: Double) -> (Single, Single) {
44
	let al = a as Single;
45
	let ah = (a >> SHIFT) as Single;
46
	(ah, al)
47
}
48

            
49
/// Assumed as a given primitive.
50
///
51
/// Multiplication of two singles, which at most yields 1 double.
52
pub fn mul_single(a: Single, b: Single) -> Double {
53
	let a: Double = a.into();
54
	let b: Double = b.into();
55
	a * b
56
}
57

            
58
/// Assumed as a given primitive.
59
///
60
/// Addition of two singles, which at most takes a single limb of result and a carry,
61
/// returned as a tuple respectively.
62
pub fn add_single(a: Single, b: Single) -> (Single, Single) {
63
	let a: Double = a.into();
64
	let b: Double = b.into();
65
	let q = a + b;
66
	let (carry, r) = split(q);
67
	(r, carry)
68
}
69

            
70
/// Assumed as a given primitive.
71
///
72
/// Division of double by a single limb. Always returns a double limb of quotient and a single
73
/// limb of remainder.
74
fn div_single(a: Double, b: Single) -> (Double, Single) {
75
	let b: Double = b.into();
76
	let q = a / b;
77
	let r = a % b;
78
	// both conversions are trivially safe.
79
	(q, r as Single)
80
}
81

            
82
/// Simple wrapper around an infinitely large integer, represented as limbs of [`Single`].
83
#[derive(Encode, Decode, Clone, Default)]
84
pub struct BigUint {
85
	/// digits (limbs) of this number (sorted as msb -> lsb).
86
	pub(crate) digits: Vec<Single>,
87
}
88

            
89
impl BigUint {
90
	/// Create a new instance with `size` limbs. This prevents any number with zero limbs to be
91
	/// created.
92
	///
93
	/// The behavior of the type is undefined with zero limbs.
94
	pub fn with_capacity(size: usize) -> Self {
95
		Self { digits: vec![0; size.max(1)] }
96
	}
97

            
98
	/// Raw constructor from custom limbs. If `limbs` is empty, `Zero::zero()` implementation is
99
	/// used.
100
	pub fn from_limbs(limbs: &[Single]) -> Self {
101
		if !limbs.is_empty() {
102
			Self { digits: limbs.to_vec() }
103
		} else {
104
			Zero::zero()
105
		}
106
	}
107

            
108
	/// Number of limbs.
109
	pub fn len(&self) -> usize {
110
		self.digits.len()
111
	}
112

            
113
	/// A naive getter for limb at `index`. Note that the order is lsb -> msb.
114
	///
115
	/// #### Panics
116
	///
117
	/// This panics if index is out of range.
118
	pub fn get(&self, index: usize) -> Single {
119
		self.digits[self.len() - 1 - index]
120
	}
121

            
122
	/// A naive getter for limb at `index`. Note that the order is lsb -> msb.
123
	pub fn checked_get(&self, index: usize) -> Option<Single> {
124
		let i = self.len().checked_sub(1)?;
125
		let j = i.checked_sub(index)?;
126
		self.digits.get(j).cloned()
127
	}
128

            
129
	/// A naive setter for limb at `index`. Note that the order is lsb -> msb.
130
	///
131
	/// #### Panics
132
	///
133
	/// This panics if index is out of range.
134
	pub fn set(&mut self, index: usize, value: Single) {
135
		let len = self.digits.len();
136
		self.digits[len - 1 - index] = value;
137
	}
138

            
139
	/// returns the least significant limb of the number.
140
	///
141
	/// #### Panics
142
	///
143
	/// While the constructor of the type prevents this, this can panic if `self` has no digits.
144
	pub fn lsb(&self) -> Single {
145
		self.digits[self.len() - 1]
146
	}
147

            
148
	/// returns the most significant limb of the number.
149
	///
150
	/// #### Panics
151
	///
152
	/// While the constructor of the type prevents this, this can panic if `self` has no digits.
153
	pub fn msb(&self) -> Single {
154
		self.digits[0]
155
	}
156

            
157
	/// Strips zeros from the left side (the most significant limbs) of `self`, if any.
158
	pub fn lstrip(&mut self) {
159
		// by definition, a big-int number should never have leading zero limbs. This function
160
		// has the ability to cause this. There is nothing to do if the number already has 1
161
		// limb only. call it a day and return.
162
		if self.len().is_zero() {
163
			return
164
		}
165
		let index = self.digits.iter().position(|&elem| elem != 0).unwrap_or(self.len() - 1);
166

            
167
		if index > 0 {
168
			self.digits = self.digits[index..].to_vec()
169
		}
170
	}
171

            
172
	/// Zero-pad `self` from left to reach `size` limbs. Will not make any difference if `self`
173
	/// is already bigger than `size` limbs.
174
	pub fn lpad(&mut self, size: usize) {
175
		let n = self.len();
176
		if n >= size {
177
			return
178
		}
179
		let pad = size - n;
180
		let mut new_digits = (0..pad).map(|_| 0).collect::<Vec<Single>>();
181
		new_digits.extend(self.digits.iter());
182
		self.digits = new_digits;
183
	}
184

            
185
	/// Adds `self` with `other`. self and other do not have to have any particular size. Given
186
	/// that the `n = max{size(self), size(other)}`, it will produce a number with `n + 1`
187
	/// limbs.
188
	///
189
	/// This function does not strip the output and returns the original allocated `n + 1`
190
	/// limbs. The caller may strip the output if desired.
191
	///
192
	/// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4.
193
	pub fn add(self, other: &Self) -> Self {
194
		let n = self.len().max(other.len());
195
		let mut k: Double = 0;
196
		let mut w = Self::with_capacity(n + 1);
197

            
198
		for j in 0..n {
199
			let u = Double::from(self.checked_get(j).unwrap_or(0));
200
			let v = Double::from(other.checked_get(j).unwrap_or(0));
201
			let s = u + v + k;
202
			// proof: any number % B will fit into `Single`.
203
			w.set(j, (s % B) as Single);
204
			k = s / B;
205
		}
206
		// k is always 0 or 1.
207
		w.set(n, k as Single);
208
		w
209
	}
210

            
211
	/// Subtracts `other` from `self`. self and other do not have to have any particular size.
212
	/// Given that the `n = max{size(self), size(other)}`, it will produce a number of size `n`.
213
	///
214
	/// If `other` is bigger than `self`, `Err(B - borrow)` is returned.
215
	///
216
	/// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4.
217
	pub fn sub(self, other: &Self) -> Result<Self, Self> {
218
		let n = self.len().max(other.len());
219
		let mut k = 0;
220
		let mut w = Self::with_capacity(n);
221
		for j in 0..n {
222
			let s = {
223
				let u = Double::from(self.checked_get(j).unwrap_or(0));
224
				let v = Double::from(other.checked_get(j).unwrap_or(0));
225

            
226
				if let Some(v2) = u.checked_sub(v).and_then(|v1| v1.checked_sub(k)) {
227
					// no borrow is needed. u - v - k can be computed as-is
228
					let t = v2;
229
					k = 0;
230

            
231
					t
232
				} else {
233
					// borrow is needed. Add a `B` to u, before subtracting.
234
					// PROOF: addition: `u + B < 2*B`, thus can fit in double.
235
					// PROOF: subtraction: if `u - v - k < 0`, then `u + B - v - k < B`.
236
					// NOTE: the order of operations is critical to ensure underflow won't happen.
237
					let t = u + B - v - k;
238
					k = 1;
239

            
240
					t
241
				}
242
			};
243
			w.set(j, s as Single);
244
		}
245

            
246
		if k.is_zero() {
247
			Ok(w)
248
		} else {
249
			Err(w)
250
		}
251
	}
252

            
253
	/// Multiplies n-limb number `self` with m-limb number `other`.
254
	///
255
	/// The resulting number will always have `n + m` limbs.
256
	///
257
	/// This function does not strip the output and returns the original allocated `n + m`
258
	/// limbs. The caller may strip the output if desired.
259
	///
260
	/// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4.
261
	pub fn mul(self, other: &Self) -> Self {
262
		let n = self.len();
263
		let m = other.len();
264
		let mut w = Self::with_capacity(m + n);
265

            
266
		for j in 0..n {
267
			if self.get(j) == 0 {
268
				// Note: `with_capacity` allocates with 0. Explicitly set j + m to zero if
269
				// otherwise.
270
				continue
271
			}
272

            
273
			let mut k = 0;
274
			for i in 0..m {
275
				// PROOF: (B−1) × (B−1) + (B−1) + (B−1) = B^2 −1 < B^2. addition is safe.
276
				let t = mul_single(self.get(j), other.get(i)) +
277
					Double::from(w.get(i + j)) +
278
					Double::from(k);
279
				w.set(i + j, (t % B) as Single);
280
				// PROOF: (B^2 - 1) / B < B. conversion is safe.
281
				k = (t / B) as Single;
282
			}
283
			w.set(j + m, k);
284
		}
285
		w
286
	}
287

            
288
	/// Divides `self` by a single limb `other`. This can be used in cases where the original
289
	/// division cannot work due to the divisor (`other`) being just one limb.
290
	///
291
	/// Invariant: `other` cannot be zero.
292
	pub fn div_unit(self, mut other: Single) -> Self {
293
		other = other.max(1);
294
		let n = self.len();
295
		let mut out = Self::with_capacity(n);
296
		let mut r: Single = 0;
297
		// PROOF: (B-1) * B + (B-1) still fits in double
298
		let with_r = |x: Single, r: Single| Double::from(r) * B + Double::from(x);
299
		for d in (0..n).rev() {
300
			let (q, rr) = div_single(with_r(self.get(d), r), other);
301
			out.set(d, q as Single);
302
			r = rr;
303
		}
304
		out
305
	}
306

            
307
	/// Divides an `n + m` limb self by a `n` limb `other`. The result is a `m + 1` limb
308
	/// quotient and a `n` limb remainder, if enabled by passing `true` in `rem` argument, both
309
	/// in the form of an option's `Ok`.
310
	///
311
	/// - requires `other` to be stripped and have no leading zeros.
312
	/// - requires `self` to be stripped and have no leading zeros.
313
	/// - requires `other` to have at least two limbs.
314
	/// - requires `self` to have a greater length compared to `other`.
315
	///
316
	/// All arguments are examined without being stripped for the above conditions. If any of
317
	/// the above fails, `None` is returned.`
318
	///
319
	/// Taken from "The Art of Computer Programming" by D.E. Knuth, vol 2, chapter 4.
320
	pub fn div(self, other: &Self, rem: bool) -> Option<(Self, Self)> {
321
		if other.len() <= 1 || other.msb() == 0 || self.msb() == 0 || self.len() <= other.len() {
322
			return None
323
		}
324
		let n = other.len();
325
		let m = self.len() - n;
326

            
327
		let mut q = Self::with_capacity(m + 1);
328
		let mut r = Self::with_capacity(n);
329

            
330
		// PROOF: 0 <= normalizer_bits < SHIFT 0 <= normalizer < B. all conversions are
331
		// safe.
332
		let normalizer_bits = other.msb().leading_zeros() as Single;
333
		let normalizer = 2_u32.pow(normalizer_bits as u32) as Single;
334

            
335
		// step D1.
336
		let mut self_norm = self.mul(&Self::from(normalizer));
337
		let mut other_norm = other.clone().mul(&Self::from(normalizer));
338

            
339
		// defensive only; the mul implementation should always create this.
340
		self_norm.lpad(n + m + 1);
341
		other_norm.lstrip();
342

            
343
		// step D2.
344
		for j in (0..=m).rev() {
345
			// step D3.0 Find an estimate of q[j], named qhat.
346
			let (qhat, rhat) = {
347
				// PROOF: this always fits into `Double`. In the context of Single = u8, and
348
				// Double = u16, think of 255 * 256 + 255 which is just u16::MAX.
349
				let dividend =
350
					Double::from(self_norm.get(j + n)) * B + Double::from(self_norm.get(j + n - 1));
351
				let divisor = other_norm.get(n - 1);
352
				div_single(dividend, divisor)
353
			};
354

            
355
			// D3.1 test qhat
356
			// replace qhat and rhat with RefCells. This helps share state with the closure
357
			let qhat = RefCell::new(qhat);
358
			let rhat = RefCell::new(Double::from(rhat));
359

            
360
			let test = || {
361
				// decrease qhat if it is bigger than the base (B)
362
				let qhat_local = *qhat.borrow();
363
				let rhat_local = *rhat.borrow();
364
				let predicate_1 = qhat_local >= B;
365
				let predicate_2 = {
366
					let lhs = qhat_local * Double::from(other_norm.get(n - 2));
367
					let rhs = B * rhat_local + Double::from(self_norm.get(j + n - 2));
368
					lhs > rhs
369
				};
370
				if predicate_1 || predicate_2 {
371
					*qhat.borrow_mut() -= 1;
372
					*rhat.borrow_mut() += Double::from(other_norm.get(n - 1));
373
					true
374
				} else {
375
					false
376
				}
377
			};
378

            
379
			test();
380
			while (*rhat.borrow() as Double) < B {
381
				if !test() {
382
					break
383
				}
384
			}
385

            
386
			let qhat = qhat.into_inner();
387
			// we don't need rhat anymore. just let it go out of scope when it does.
388

            
389
			// step D4
390
			let lhs = Self { digits: (j..=j + n).rev().map(|d| self_norm.get(d)).collect() };
391
			let rhs = other_norm.clone().mul(&Self::from(qhat));
392

            
393
			let maybe_sub = lhs.sub(&rhs);
394
			let mut negative = false;
395
			let sub = match maybe_sub {
396
				Ok(t) => t,
397
				Err(t) => {
398
					negative = true;
399
					t
400
				},
401
			};
402
			(j..=j + n).for_each(|d| {
403
				self_norm.set(d, sub.get(d - j));
404
			});
405

            
406
			// step D5
407
			// PROOF: the `test()` specifically decreases qhat until it is below `B`. conversion
408
			// is safe.
409
			q.set(j, qhat as Single);
410

            
411
			// step D6: add back if negative happened.
412
			if negative {
413
				q.set(j, q.get(j) - 1);
414
				let u = Self { digits: (j..=j + n).rev().map(|d| self_norm.get(d)).collect() };
415
				let r = other_norm.clone().add(&u);
416
				(j..=j + n).rev().for_each(|d| {
417
					self_norm.set(d, r.get(d - j));
418
				})
419
			}
420
		}
421

            
422
		// if requested, calculate remainder.
423
		if rem {
424
			// undo the normalization.
425
			if normalizer_bits > 0 {
426
				let s = SHIFT as u32;
427
				let nb = normalizer_bits;
428
				for d in 0..n - 1 {
429
					let v = self_norm.get(d) >> nb | self_norm.get(d + 1).overflowing_shl(s - nb).0;
430
					r.set(d, v);
431
				}
432
				r.set(n - 1, self_norm.get(n - 1) >> normalizer_bits);
433
			} else {
434
				r = self_norm;
435
			}
436
		}
437

            
438
		Some((q, r))
439
	}
440
}
441

            
442
impl core::fmt::Debug for BigUint {
443
	#[cfg(feature = "std")]
444
	fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
445
		write!(
446
			f,
447
			"BigUint {{ {:?} ({:?})}}",
448
			self.digits,
449
			u128::try_from(self.clone()).unwrap_or(0),
450
		)
451
	}
452

            
453
	#[cfg(not(feature = "std"))]
454
	fn fmt(&self, _: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
455
		Ok(())
456
	}
457
}
458

            
459
impl PartialEq for BigUint {
460
	fn eq(&self, other: &Self) -> bool {
461
		self.cmp(other) == Ordering::Equal
462
	}
463
}
464

            
465
impl Eq for BigUint {}
466

            
467
impl Ord for BigUint {
468
	fn cmp(&self, other: &Self) -> Ordering {
469
		let lhs_first = self.digits.iter().position(|&e| e != 0);
470
		let rhs_first = other.digits.iter().position(|&e| e != 0);
471

            
472
		match (lhs_first, rhs_first) {
473
			// edge cases that should not happen. This basically means that one or both were
474
			// zero.
475
			(None, None) => Ordering::Equal,
476
			(Some(_), None) => Ordering::Greater,
477
			(None, Some(_)) => Ordering::Less,
478
			(Some(lhs_idx), Some(rhs_idx)) => {
479
				let lhs = &self.digits[lhs_idx..];
480
				let rhs = &other.digits[rhs_idx..];
481
				let len_cmp = lhs.len().cmp(&rhs.len());
482
				match len_cmp {
483
					Ordering::Equal => lhs.cmp(rhs),
484
					_ => len_cmp,
485
				}
486
			},
487
		}
488
	}
489
}
490

            
491
impl PartialOrd for BigUint {
492
	fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
493
		Some(self.cmp(other))
494
	}
495
}
496

            
497
impl ops::Add for BigUint {
498
	type Output = Self;
499
	fn add(self, rhs: Self) -> Self::Output {
500
		self.add(&rhs)
501
	}
502
}
503

            
504
impl ops::Sub for BigUint {
505
	type Output = Self;
506
	fn sub(self, rhs: Self) -> Self::Output {
507
		self.sub(&rhs).unwrap_or_else(|e| e)
508
	}
509
}
510

            
511
impl ops::Mul for BigUint {
512
	type Output = Self;
513
	fn mul(self, rhs: Self) -> Self::Output {
514
		self.mul(&rhs)
515
	}
516
}
517

            
518
impl Zero for BigUint {
519
	fn zero() -> Self {
520
		Self { digits: vec![Zero::zero()] }
521
	}
522

            
523
	fn is_zero(&self) -> bool {
524
		self.digits.iter().all(|d| d.is_zero())
525
	}
526
}
527

            
528
impl One for BigUint {
529
	fn one() -> Self {
530
		Self { digits: vec![Single::one()] }
531
	}
532
}
533

            
534
macro_rules! impl_try_from_number_for {
535
	($([$type:ty, $len:expr]),+) => {
536
		$(
537
			impl TryFrom<BigUint> for $type {
538
				type Error = &'static str;
539
				fn try_from(mut value: BigUint) -> Result<$type, Self::Error> {
540
					value.lstrip();
541
					let error_message = concat!("cannot fit a number into ", stringify!($type));
542
					if value.len() * SHIFT > $len {
543
						Err(error_message)
544
					} else {
545
						let mut acc: $type = Zero::zero();
546
						for (i, d) in value.digits.iter().rev().cloned().enumerate() {
547
							let d: $type = d.into();
548
							acc += d << (SHIFT * i);
549
						}
550
						Ok(acc)
551
					}
552
				}
553
			}
554
		)*
555
	};
556
}
557
// can only be implemented for sizes bigger than two limb.
558
impl_try_from_number_for!([u128, 128], [u64, 64]);
559

            
560
macro_rules! impl_from_for_smaller_than_word {
561
	($($type:ty),+) => {
562
		$(impl From<$type> for BigUint {
563
			fn from(a: $type) -> Self {
564
				Self { digits: vec! [a.into()] }
565
			}
566
		})*
567
	}
568
}
569
impl_from_for_smaller_than_word!(u8, u16, u32);
570

            
571
impl From<u64> for BigUint {
572
	fn from(a: Double) -> Self {
573
		let (ah, al) = split(a);
574
		Self { digits: vec![ah, al] }
575
	}
576
}
577

            
578
impl From<u128> for BigUint {
579
	fn from(a: u128) -> Self {
580
		crate::helpers_128bit::to_big_uint(a)
581
	}
582
}
583

            
584
#[cfg(test)]
585
pub mod tests {
586
	use super::*;
587

            
588
	fn with_limbs(n: usize) -> BigUint {
589
		BigUint { digits: vec![1; n] }
590
	}
591

            
592
	#[test]
593
	fn split_works() {
594
		let a = SHIFT / 2;
595
		let b = SHIFT * 3 / 2;
596
		let num: Double = 1 << a | 1 << b;
597
		assert_eq!(num, 0x_0001_0000_0001_0000);
598
		assert_eq!(split(num), (1 << a, 1 << a));
599

            
600
		let a = SHIFT / 2 + 4;
601
		let b = SHIFT / 2 - 4;
602
		let num: Double = 1 << (SHIFT + a) | 1 << b;
603
		assert_eq!(num, 0x_0010_0000_0000_1000);
604
		assert_eq!(split(num), (1 << a, 1 << b));
605
	}
606

            
607
	#[test]
608
	fn strip_works() {
609
		let mut a = BigUint::from_limbs(&[0, 1, 0]);
610
		a.lstrip();
611
		assert_eq!(a.digits, vec![1, 0]);
612

            
613
		let mut a = BigUint::from_limbs(&[0, 0, 1]);
614
		a.lstrip();
615
		assert_eq!(a.digits, vec![1]);
616

            
617
		let mut a = BigUint::from_limbs(&[0, 0]);
618
		a.lstrip();
619
		assert_eq!(a.digits, vec![0]);
620

            
621
		let mut a = BigUint::from_limbs(&[0, 0, 0]);
622
		a.lstrip();
623
		assert_eq!(a.digits, vec![0]);
624
	}
625

            
626
	#[test]
627
	fn lpad_works() {
628
		let mut a = BigUint::from_limbs(&[0, 1, 0]);
629
		a.lpad(2);
630
		assert_eq!(a.digits, vec![0, 1, 0]);
631

            
632
		let mut a = BigUint::from_limbs(&[0, 1, 0]);
633
		a.lpad(3);
634
		assert_eq!(a.digits, vec![0, 1, 0]);
635

            
636
		let mut a = BigUint::from_limbs(&[0, 1, 0]);
637
		a.lpad(4);
638
		assert_eq!(a.digits, vec![0, 0, 1, 0]);
639
	}
640

            
641
	#[test]
642
	fn equality_works() {
643
		assert_eq!(BigUint { digits: vec![1, 2, 3] } == BigUint { digits: vec![1, 2, 3] }, true);
644
		assert_eq!(BigUint { digits: vec![3, 2, 3] } == BigUint { digits: vec![1, 2, 3] }, false);
645
		assert_eq!(BigUint { digits: vec![0, 1, 2, 3] } == BigUint { digits: vec![1, 2, 3] }, true);
646
	}
647

            
648
	#[test]
649
	fn ordering_works() {
650
		assert!(BigUint { digits: vec![0] } < BigUint { digits: vec![1] });
651
		assert!(BigUint { digits: vec![0] } == BigUint { digits: vec![0] });
652
		assert!(BigUint { digits: vec![] } == BigUint { digits: vec![0] });
653
		assert!(BigUint { digits: vec![] } == BigUint { digits: vec![] });
654
		assert!(BigUint { digits: vec![] } < BigUint { digits: vec![1] });
655

            
656
		assert!(BigUint { digits: vec![1, 2, 3] } == BigUint { digits: vec![1, 2, 3] });
657
		assert!(BigUint { digits: vec![0, 1, 2, 3] } == BigUint { digits: vec![1, 2, 3] });
658

            
659
		assert!(BigUint { digits: vec![1, 2, 4] } > BigUint { digits: vec![1, 2, 3] });
660
		assert!(BigUint { digits: vec![0, 1, 2, 4] } > BigUint { digits: vec![1, 2, 3] });
661
		assert!(BigUint { digits: vec![1, 2, 1, 0] } > BigUint { digits: vec![1, 2, 3] });
662

            
663
		assert!(BigUint { digits: vec![0, 1, 2, 1] } < BigUint { digits: vec![1, 2, 3] });
664
	}
665

            
666
	#[test]
667
	fn can_try_build_numbers_from_types() {
668
		assert_eq!(u64::try_from(with_limbs(1)).unwrap(), 1);
669
		assert_eq!(u64::try_from(with_limbs(2)).unwrap(), u32::MAX as u64 + 2);
670
		assert_eq!(u64::try_from(with_limbs(3)).unwrap_err(), "cannot fit a number into u64");
671
		assert_eq!(u128::try_from(with_limbs(3)).unwrap(), u32::MAX as u128 + u64::MAX as u128 + 3);
672
	}
673

            
674
	#[test]
675
	fn zero_works() {
676
		assert_eq!(BigUint::zero(), BigUint { digits: vec![0] });
677
		assert_eq!(BigUint { digits: vec![0, 1, 0] }.is_zero(), false);
678
		assert_eq!(BigUint { digits: vec![0, 0, 0] }.is_zero(), true);
679

            
680
		let a = BigUint::zero();
681
		let b = BigUint::zero();
682
		let c = a * b;
683
		assert_eq!(c.digits, vec![0, 0]);
684
	}
685

            
686
	#[test]
687
	fn sub_negative_works() {
688
		assert_eq!(
689
			BigUint::from(10 as Single).sub(&BigUint::from(5 as Single)).unwrap(),
690
			BigUint::from(5 as Single)
691
		);
692
		assert_eq!(
693
			BigUint::from(10 as Single).sub(&BigUint::from(10 as Single)).unwrap(),
694
			BigUint::from(0 as Single)
695
		);
696
		assert_eq!(
697
			BigUint::from(10 as Single).sub(&BigUint::from(13 as Single)).unwrap_err(),
698
			BigUint::from((B - 3) as Single),
699
		);
700
	}
701

            
702
	#[test]
703
	fn mul_always_appends_one_digit() {
704
		let a = BigUint::from(10 as Single);
705
		let b = BigUint::from(4 as Single);
706
		assert_eq!(a.len(), 1);
707
		assert_eq!(b.len(), 1);
708

            
709
		let n = a.mul(&b);
710

            
711
		assert_eq!(n.len(), 2);
712
		assert_eq!(n.digits, vec![0, 40]);
713
	}
714

            
715
	#[test]
716
	fn div_conditions_work() {
717
		let a = BigUint { digits: vec![2] };
718
		let b = BigUint { digits: vec![1, 2] };
719
		let c = BigUint { digits: vec![1, 1, 2] };
720
		let d = BigUint { digits: vec![0, 2] };
721
		let e = BigUint { digits: vec![0, 1, 1, 2] };
722
		let f = BigUint { digits: vec![7, 8] };
723

            
724
		assert!(a.clone().div(&b, true).is_none());
725
		assert!(c.clone().div(&a, true).is_none());
726
		assert!(c.clone().div(&d, true).is_none());
727
		assert!(e.clone().div(&a, true).is_none());
728

            
729
		assert!(f.clone().div(&b, true).is_none());
730
		assert!(c.clone().div(&b, true).is_some());
731
	}
732

            
733
	#[test]
734
	fn div_unit_works() {
735
		let a = BigUint { digits: vec![100] };
736
		let b = BigUint { digits: vec![1, 100] };
737
		let c = BigUint { digits: vec![14, 28, 100] };
738

            
739
		assert_eq!(a.clone().div_unit(1), a);
740
		assert_eq!(a.clone().div_unit(0), a);
741
		assert_eq!(a.clone().div_unit(2), BigUint::from(50 as Single));
742
		assert_eq!(a.clone().div_unit(7), BigUint::from(14 as Single));
743

            
744
		assert_eq!(b.clone().div_unit(1), b);
745
		assert_eq!(b.clone().div_unit(0), b);
746
		assert_eq!(b.clone().div_unit(2), BigUint::from(((B + 100) / 2) as Single));
747
		assert_eq!(b.clone().div_unit(7), BigUint::from(((B + 100) / 7) as Single));
748

            
749
		assert_eq!(c.clone().div_unit(1), c);
750
		assert_eq!(c.clone().div_unit(0), c);
751
		assert_eq!(c.clone().div_unit(2), BigUint { digits: vec![7, 14, 50] });
752
		assert_eq!(c.clone().div_unit(7), BigUint { digits: vec![2, 4, 14] });
753
	}
754
}