the formula for calculating nth gray code is :
(n-1) XOR (floor((n-1)/2))
(Source: wikipedia)
I encoded it as:
int gray(int n)
{
n--;
return n ^ (n >> 1);
}
Can someone explain how the above formula works, or possibly its deriviation?
The Wikipedia entry you refer to explains the equation in a very circuitous manner.
However, it helps to start with this:
In other words,
Gn(m) & 2^n-1
is eitherGn-1(m & 2^n-1)
or~Gn-1(m & 2^n-1)
. For example,G(3) & 1
is eitherG(1)
or~G(1)
. Now, we know thatGn(m) & 2^n-1
will be the reflected (bitwise inverse) ifm
is greater than2^n-1
.In other words:
Working out the math in its entirety, you get
(m ^ (m >> 1))
for the zero-based Gray code.If you look at binary counting sequence, you note, that neighboring codes differ at several last bits (with no holes), so if you xor them, pattern of several trailing 1's appear. Also, when you shift numbers right, xors also will be shifted right: (A xor B)>>N == A>>N xor B>>N.
Original Xor results and shifted results differ in single bit (i marked them by dot above). This means that if you xor them, you'll get pattern with 1 bit set. So,
As xor gives us 1s in differing bits, it proves, what neighbouring codes differ only in single bit, and that's main property of Gray code we want to get.
So for completeness, whould be proven, that N can be restored from its N ^ (N>>1) value: knowing n'th bit of code we can restore n-1'th bit using xor.
Starting from largest bit (it is xored with 0) thus we can restore whole number.
Prove by induction.
Hint: The
1<<k
th to(1<<(k+1))-1
th values are twice the1<<(k-1)
th to(1<<k)-1
th values, plus either zero or one.Edit: That was way too confusing. What I really mean is,
gray(2*n)
andgray(2*n+1)
are2*gray(n)
and2*gray(n)+1
in some order.Incrementing a number, when you look at it bitwise, flips all trailing ones to zeros and the last zero to one. That's a whole lot of bits flipped, and the purpose of Gray code is to make it exactly one. This transformation makes both numbers (before and after increment) equal on all the bits being flipped, except the highest one.
Before:
After:
n ^ (n >> 1)
is easier to compute but it seems that only changing the trailing011..1
to010..0
(i.e. zeroing the whole trailing block of 1's except the highest 1) and10..0
to11..0
(i.e flipping the highest 0 in the trailing 0's) is enough to obtain a Gray code.