1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
//! Integer remainder via the [`Rem`] trait.
use super::U256;
use core::ops::Rem;
/// Integer remainder of two 256-bit unsigned integers.
///
/// Returns `self % rhs` (the remainder after integer division). Delegates
/// to [`U256::div_rem`] and returns only the remainder.
///
/// # Panics
///
/// Loops indefinitely if `rhs` is zero.
///
/// # Examples
///
/// ```
/// use cnfy_uint::u256::U256;
///
/// let a = U256::from_be_limbs([0, 0, 0, 10]);
/// let b = U256::from_be_limbs([0, 0, 0, 3]);
/// assert_eq!(a % b, U256::from_be_limbs([0, 0, 0, 1]));
/// ```
impl Rem for U256 {
type Output = U256;
#[inline]
fn rem(self, rhs: U256) -> U256 {
self.div_rem(&rhs).1
}
}
#[cfg(test)]
mod ai_tests {
use super::*;
/// 10 % 3 = 1.
#[test]
fn ten_mod_three() {
let a = U256::from_be_limbs([0, 0, 0, 10]);
let b = U256::from_be_limbs([0, 0, 0, 3]);
assert_eq!(a % b, U256::from_be_limbs([0, 0, 0, 1]));
}
/// 8 % 2 = 0 (exact division).
#[test]
fn exact_division() {
let a = U256::from_be_limbs([0, 0, 0, 8]);
let b = U256::from_be_limbs([0, 0, 0, 2]);
assert_eq!(a % b, U256::ZERO);
}
/// Remainder by one is always zero.
#[test]
fn mod_by_one() {
let a = U256::from_be_limbs([0x1234, 0x5678, 0x9ABC, 0xDEF0]);
assert_eq!(a % U256::ONE, U256::ZERO);
}
/// Self mod self is zero.
#[test]
fn self_mod() {
let a = U256::from_be_limbs([0x1234, 0x5678, 0x9ABC, 0xDEF0]);
assert_eq!(a % a, U256::ZERO);
}
/// Dividend smaller than divisor yields the dividend.
#[test]
fn smaller_dividend() {
let a = U256::from_be_limbs([0, 0, 0, 3]);
let b = U256::from_be_limbs([0, 0, 0, 10]);
assert_eq!(a % b, a);
}
/// MAX % 2 = 1 (MAX is odd).
#[test]
fn max_mod_two() {
let two = U256::from_be_limbs([0, 0, 0, 2]);
assert_eq!(U256::MAX % two, U256::ONE);
}
/// Consistency: (a / b) * b + (a % b) == a.
#[test]
fn div_rem_consistency() {
let a = U256::from_be_limbs([0x1234, 0x5678, 0x9ABC, 0xDEF0]);
let b = U256::from_be_limbs([0, 0, 0x1111, 0x2222]);
let q = a / b;
let r = a % b;
assert_eq!(q.mul_mod(&b, &U256::MAX) + r, a);
}
}