blob: b681a6154aa100024f1d40c429860184d9d3d033 (
plain)
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
|
// TODO(tarcieri): use `const_evaluatable_checked` when stable to make generic around bits.
macro_rules! impl_split {
($(($name:ident, $bits:expr)),+) => {
$(
impl $name {
/// Split this number in half, returning its high and low components
/// respectively.
pub const fn split(&self) -> (Uint<{nlimbs!($bits) / 2}>, Uint<{nlimbs!($bits) / 2}>) {
let mut lo = [Limb::ZERO; nlimbs!($bits) / 2];
let mut hi = [Limb::ZERO; nlimbs!($bits) / 2];
let mut i = 0;
let mut j = 0;
while j < (nlimbs!($bits) / 2) {
lo[j] = self.limbs[i];
i += 1;
j += 1;
}
j = 0;
while j < (nlimbs!($bits) / 2) {
hi[j] = self.limbs[i];
i += 1;
j += 1;
}
(Uint { limbs: hi }, Uint { limbs: lo })
}
}
impl Split for $name {
type Output = Uint<{nlimbs!($bits) / 2}>;
fn split(&self) -> (Self::Output, Self::Output) {
self.split()
}
}
impl From<$name> for (Uint<{nlimbs!($bits) / 2}>, Uint<{nlimbs!($bits) / 2}>) {
fn from(num: $name) -> (Uint<{nlimbs!($bits) / 2}>, Uint<{nlimbs!($bits) / 2}>) {
num.split()
}
}
)+
};
}
#[cfg(test)]
mod tests {
use crate::{U128, U64};
#[test]
fn split() {
let (hi, lo) = U128::from_be_hex("00112233445566778899aabbccddeeff").split();
assert_eq!(hi, U64::from_u64(0x0011223344556677));
assert_eq!(lo, U64::from_u64(0x8899aabbccddeeff));
}
}
|