Skip to main content

oxihuman_core/
gray_code.rs

1// Copyright (C) 2026 COOLJAPAN OU (Team KitaSan)
2// SPDX-License-Identifier: Apache-2.0
3#![allow(dead_code)]
4
5pub fn to_gray(n: u32) -> u32 {
6    n ^ (n >> 1)
7}
8
9pub fn from_gray(mut g: u32) -> u32 {
10    let mut mask = g >> 1;
11    while mask != 0 {
12        g ^= mask;
13        mask >>= 1;
14    }
15    g
16}
17
18pub fn gray_distance(a: u32, b: u32) -> u32 {
19    (a ^ b).count_ones()
20}
21
22pub fn gray_next(g: u32) -> u32 {
23    to_gray(from_gray(g).wrapping_add(1))
24}
25
26pub fn gray_prev(g: u32) -> u32 {
27    to_gray(from_gray(g).wrapping_sub(1))
28}
29
30pub fn gray_bits(g: u32) -> u32 {
31    g.count_ones()
32}
33
34#[cfg(test)]
35mod tests {
36    use super::*;
37
38    #[test]
39    fn gray_roundtrip() {
40        /* encoding then decoding returns original value */
41        for n in 0u32..=15 {
42            assert_eq!(from_gray(to_gray(n)), n);
43        }
44    }
45
46    #[test]
47    fn consecutive_gray_differ_by_one_bit() {
48        /* adjacent Gray codes differ by exactly 1 bit */
49        for n in 0u32..=14 {
50            let diff = to_gray(n) ^ to_gray(n + 1);
51            assert_eq!(diff.count_ones(), 1);
52        }
53    }
54
55    #[test]
56    fn gray_distance_self() {
57        /* distance from a code to itself is zero */
58        assert_eq!(gray_distance(0b101, 0b101), 0);
59    }
60
61    #[test]
62    fn gray_next_advances() {
63        /* gray_next increments the binary value by 1 */
64        let g = to_gray(5);
65        assert_eq!(gray_next(g), to_gray(6));
66    }
67
68    #[test]
69    fn gray_prev_decrements() {
70        /* gray_prev decrements the binary value by 1 */
71        let g = to_gray(5);
72        assert_eq!(gray_prev(g), to_gray(4));
73    }
74
75    #[test]
76    fn gray_bits_count() {
77        /* gray_bits counts set bits */
78        assert_eq!(gray_bits(0b1010), 2);
79    }
80
81    #[test]
82    fn to_gray_zero() {
83        /* zero maps to zero */
84        assert_eq!(to_gray(0), 0);
85    }
86}