Exploring Gray Code – The Oddball Sibling of Binary
Tags: programming, computerscience, graphics, opengl
Published: 2023-05-25 13:45:00

So hopefully we're all familiar with binary. Just in case, here's a review:

![Binary Counting](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/10krn3wyxova9de2m3nv.png)


That's the standard way of counting in binary. And for computers, this is a perfectly logical and optimal system. Its the way most numbers on our computer work.[*](https://en.wikipedia.org/wiki/Two%27s_complement)

But what if we had to manually track the bits ourselves using, say, a series of heavy switches to store a counter, like counting people who enter a store? Let's take a look at our hypothetical counter:

![Binary Switches 0](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jekok68ba4m6kl7kc802.png)


After some period of time, we've had several people come in. So by now, we have 7 people: Here it is stored in binary with our counter.

![Binary Counting 7](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7wi802ar5c3kji9xjvyh.png)


Suddenly we hear the bell ding; someone else has entered the store. So we should increase the counter to eight:

![Binary Counting 8](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cnz5o51hwp5vj42sdzjv.png)



But man - that was hard! The effort required to flip multiple switches can quickly become overwhelming as the count increases. You might wonder if there's a more efficient method - and there is. It's called Gray Code.

Gray Code is an alternative binary numeral system where two successive values differ in only one bit, which means flipping just one switch to go from one value to the next. Here's what counting from 0 to 7 looks like in Gray Code:

![Gray Code 0 to 7](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1egaubw1x0xlfop8z85v.png)


Hopefully you were able to see the pattern - each time we flip the switch furthest to the right that will give us a combination we haven't used. You can read more about Gray Code [here](https://en.wikipedia.org/wiki/Gray_code#Constructing_an_n-bit_Gray_code).

You might think that converting to and from Gray Code would be complicated - but thankfully some really smart people have created some clever algorithms that make it relatively straight forward. Here they are:

![Binary to gray pseudocode](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yrlb5kbg1fl3ucewg5n6.png)




![Gray to binary pseudocode](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xyd7scps59fg2sslc7vz.png)






And that's how all we need!

Now, let's have some fun with Gray Code! As I demonstrated in my last [article](https://dev.to/max_feige/demystifying-bitwise-operators-a-visual-perspective-38kl), you can create interesting images using the bit representation of numbers. Let's see how different bitwise operators - AND, OR, XOR - behave when applied to Gray Code:

<small>Note: These are stretched a bit in the x direction, and I tend to like them that way. If you want to see the square images, resizing the images should give you something indistinguishable. </small>

First we can compare normal binary to gray code.


<figure>
<img src = "https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1rliixm6yg56he5qw6o2.png"></img>
<figcaption>Binary gradient based on x coordinate</figcaption>
</figure>

<figure> 
<img src = "https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l4kaib9w93lph5r7e3a9.png"></img>
<figcaption>Gray code gradient based on x coordinate</figcaption>




Now lets look at our bitwise operators. We'll consider two cases: First we convert our numbers to gray code, perform the bitwise operator, then convert them back to decimal.


<figure>
<img src = "https://dev-to-uploads.s3.amazonaws.com/uploads/articles/edn6fhf76r5p3sk8n6ti.png">
<figcaption>Normal OR</figcaption>
</figure>

<figure>
<img src = "https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pcgglk0fyeldu82iazgj.png"></img>
<figcaption>Normal AND</figcaption>
</figure>


<figure>
<img src = "https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bkn1rmkdsnrv7hy2lz3x.png"</img>
<figcaption>Normal XOR</figcaption>
</figure>

You might notice something peculiar about the image showcasing the Normal XOR operation. The apparent 'blockiness' isn't a result of image artifact compression or a mistake - it's actually an intriguing characteristic that arises from the Gray Code representation!


What's even more fascinating is that this Normal Gray Code XOR operation yields a result entirely equivalent to the binary XOR operation. This might seem counter-intuitive - I encourage you to take a look at the previous code and see if you can solve this puzzle. Unpacking these mysteries is part of what makings coding so exciting!


Now let's consider the concept of "casting". By casting, I mean performing our operation in Gray Code but not converting the numbers back to binary. While not typically used, this process can generate some fascinating patterns:

<small>Inspired by this famous [algorithm](https://en.wikipedia.org/wiki/Fast_inverse_square_root)</small>

<figure>
<img src = "https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xk23ch2xuycik9ch6168.png"></img>
<figcaption>Casted OR</figcaption>
</figure>


<figure>
<img src = "https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vhn6paiih5fx87svdlx9.png"</img>
<figcaption>Casted AND</figcaption>
</figure>


<figure> 
<img src = "https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3o58ybcecl4uty6ca78d.png"></img>
<figcaption>Casted XOR</figcaption>
</figure>


I find these patterns absolutely captivating. The process of casting in Gray Code produces an effect reminiscent of layering transparent images, creating a captivating visual representation of this weird binary sibling.