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