1pub fn zigzag_encode(n: i64, type_bits: u8) -> u64 {
6 ((n << 1) ^ (n >> (u32::from(type_bits) - 1))) as u64
7}
8
9pub fn zigzag_decode(n: u64) -> i64 {
11 ((n >> 1) as i64) ^ -((n & 1) as i64)
12}
13
14#[cfg(test)]
15mod tests {
16 use super::*;
17
18 #[test]
19 fn encode_mapping() {
20 assert_eq!(zigzag_encode(0, 64), 0);
21 assert_eq!(zigzag_encode(-1, 64), 1);
22 assert_eq!(zigzag_encode(1, 64), 2);
23 assert_eq!(zigzag_encode(-2, 64), 3);
24 assert_eq!(zigzag_encode(2, 64), 4);
25 assert_eq!(zigzag_encode(i64::MIN, 64), u64::MAX);
26 assert_eq!(zigzag_encode(i64::MAX, 64), u64::MAX - 1);
27 }
28
29 #[test]
30 fn round_trip_i32_range() {
31 for &v in &[0i64, 1, -1, 127, -128, i32::MIN as i64, i32::MAX as i64] {
32 let encoded = zigzag_encode(v, 32);
33 let decoded = zigzag_decode(encoded);
34 assert_eq!(decoded, v, "round-trip failed for {v}");
35 }
36 }
37
38 #[test]
39 fn encode_32bit_width() {
40 assert_eq!(zigzag_encode(-1, 32), 1);
41 assert_eq!(zigzag_encode(1, 32), 2);
42 }
43}