Chih-Hung Hsieh | cfc3a23 | 2020-06-10 20:13:05 -0700 | [diff] [blame] | 1 | // ZigZag endoging used for efficient transfer of signed integers |
| 2 | // https://developers.google.com/protocol-buffers/docs/encoding#types |
| 3 | |
| 4 | pub fn decode_zig_zag_32(n: u32) -> i32 { |
| 5 | ((n >> 1) as i32) ^ (-((n & 1) as i32)) |
| 6 | } |
| 7 | |
| 8 | pub fn decode_zig_zag_64(n: u64) -> i64 { |
| 9 | ((n >> 1) as i64) ^ (-((n & 1) as i64)) |
| 10 | } |
| 11 | |
| 12 | pub fn encode_zig_zag_32(n: i32) -> u32 { |
| 13 | ((n << 1) ^ (n >> 31)) as u32 |
| 14 | } |
| 15 | |
| 16 | pub fn encode_zig_zag_64(n: i64) -> u64 { |
| 17 | ((n << 1) ^ (n >> 63)) as u64 |
| 18 | } |
| 19 | |
| 20 | #[cfg(test)] |
| 21 | mod test { |
| 22 | |
| 23 | use super::decode_zig_zag_32; |
| 24 | use super::decode_zig_zag_64; |
| 25 | use super::encode_zig_zag_32; |
| 26 | use super::encode_zig_zag_64; |
| 27 | |
| 28 | #[test] |
| 29 | fn test_zig_zag() { |
| 30 | fn test_zig_zag_pair_64(decoded: i64, encoded: u64) { |
| 31 | assert_eq!(decoded, decode_zig_zag_64(encoded)); |
| 32 | assert_eq!(encoded, encode_zig_zag_64(decoded)); |
| 33 | } |
| 34 | |
| 35 | fn test_zig_zag_pair(decoded: i32, encoded: u32) { |
| 36 | assert_eq!(decoded, decode_zig_zag_32(encoded)); |
| 37 | assert_eq!(encoded, encode_zig_zag_32(decoded)); |
| 38 | test_zig_zag_pair_64(decoded as i64, encoded as u64); |
| 39 | } |
| 40 | |
| 41 | test_zig_zag_pair(0, 0); |
| 42 | test_zig_zag_pair(-1, 1); |
| 43 | test_zig_zag_pair(1, 2); |
| 44 | test_zig_zag_pair(-2, 3); |
| 45 | test_zig_zag_pair(2147483647, 4294967294); |
| 46 | test_zig_zag_pair(-2147483648, 4294967295); |
| 47 | test_zig_zag_pair_64(9223372036854775807, 18446744073709551614); |
| 48 | test_zig_zag_pair_64(-9223372036854775808, 18446744073709551615); |
| 49 | } |
| 50 | } |