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
//! Morton/Z-order deinterleaving of a [`U256`] into two `u128` coordinates.
use super::U256;
impl U256 {
/// Deinterleaves a [`U256`] Morton code into two `u128` coordinates.
///
/// Returns `(x, y)` where `x` contains the bits from even positions
/// (0, 2, 4, ..., 254) and `y` contains the bits from odd positions
/// (1, 3, 5, ..., 255). This is the inverse of
/// [`interleave`](U256::interleave):
/// `U256::interleave(x, y).deinterleave() == (x, y)`.
///
/// # Examples
///
/// ```
/// use cnfy_uint::u256::U256;
///
/// let (x, y) = U256::interleave(42, 99).deinterleave();
/// assert_eq!(x, 42);
/// assert_eq!(y, 99);
/// ```
#[inline]
pub const fn deinterleave(&self) -> (u128, u128) {
(self.undilate_even(), self.undilate_odd())
}
}
#[cfg(test)]
mod ai_tests {
use super::*;
/// Deinterleaving zero produces (0, 0).
#[test]
fn zero() {
assert_eq!(U256::ZERO.deinterleave(), (0, 0));
}
/// Round-trip: interleave then deinterleave recovers both coordinates.
#[test]
fn round_trip() {
let x: u128 = 0xDEAD_BEEF_CAFE_BABE_1234_5678_9ABC_DEF0;
let y: u128 = 0x0123_4567_89AB_CDEF_FEDC_BA98_7654_3210;
assert_eq!(U256::interleave(x, y).deinterleave(), (x, y));
}
/// Deinterleaving an even-only value returns (x, 0).
#[test]
fn even_only() {
let x: u128 = 0xCAFE_BABE;
let v = U256::from_u128_dilated_even(x);
assert_eq!(v.deinterleave(), (x, 0));
}
/// Deinterleaving an odd-only value returns (0, y).
#[test]
fn odd_only() {
let y: u128 = 0xDEAD_BEEF;
let v = U256::from_u128_dilated_odd(y);
assert_eq!(v.deinterleave(), (0, y));
}
/// Deinterleaving MAX gives (u128::MAX, u128::MAX).
#[test]
fn max() {
assert_eq!(U256::MAX.deinterleave(), (u128::MAX, u128::MAX));
}
/// Round-trip with both coordinates at maximum.
#[test]
fn round_trip_max() {
assert_eq!(
U256::interleave(u128::MAX, u128::MAX).deinterleave(),
(u128::MAX, u128::MAX),
);
}
}