Skip to main content

osom_lib_numbers/
zigzag.rs

1//! Holds helpers for encoding and decoding numbers using the zigzag encoding.
2//!
3//! The zigzag encoding converts signed integers to unsigned integers and vice versa.
4//!
5//! * Positive signed integers are multiplied by `2`.
6//! * Negative signed integers are multiplied by `-2` and `1` is subtracted.
7//! * The final result is then converted to an unsigned integer.
8
9/// Encodes a 32-bit signed integer to a 32-bit unsigned integer using the zigzag encoding.
10#[inline]
11#[must_use]
12pub const fn zigzag_encode32(value: i32) -> u32 {
13    ((value << 1) ^ (value >> 31)).cast_unsigned()
14}
15
16/// Decodes a 32-bit unsigned integer to a 32-bit signed integer using the zigzag encoding.
17#[inline]
18#[must_use]
19pub const fn zigzag_decode32(value: u32) -> i32 {
20    (value >> 1).cast_signed() ^ -(value & 1).cast_signed()
21}
22
23/// Encodes a 64-bit signed integer to a 64-bit unsigned integer using the zigzag encoding.
24#[inline]
25#[must_use]
26pub const fn zigzag_encode64(value: i64) -> u64 {
27    ((value << 1) ^ (value >> 63)).cast_unsigned()
28}
29
30/// Decodes a 64-bit unsigned integer to a 64-bit signed integer using the zigzag encoding.
31#[inline]
32#[must_use]
33pub const fn zigzag_decode64(value: u64) -> i64 {
34    (value >> 1).cast_signed() ^ -(value & 1).cast_signed()
35}
36
37/// Encodes a 128-bit signed integer to a 128-bit unsigned integer using the zigzag encoding.
38#[inline]
39#[must_use]
40pub const fn zigzag_encode128(value: i128) -> u128 {
41    ((value << 1) ^ (value >> 127)).cast_unsigned()
42}
43
44/// Decodes a 128-bit unsigned integer to a 128-bit signed integer using the zigzag encoding.
45#[inline]
46#[must_use]
47pub const fn zigzag_decode128(value: u128) -> i128 {
48    (value >> 1).cast_signed() ^ -(value & 1).cast_signed()
49}