Update
This program is a purposely obfuscated implementation of a spigot algorithm for the Digits of Pi from the book Pi - Unleashed and we can find the original version on page 37 of the book which is as follows:
a[52514],b,c=52514,d,e,f=1e4,g,h;main(){for(;b=c-=14;h=printf("%04d", e+d/f))for(e=d%=f;g=--b*2;d/=g)d=db+f(h?a[b]:f/5),a[b]=d%--g;}
the paper Unbounded Spigot Algorithms for the Digits of Pi does a good job in explaining the algorithm. Basically it is an implementation of this expansion:
Original
The reason it was designed this way other than to make the code impossible to comprehend and impress people escapes me but we can break down what is going on, first here:
long a[35014],b,c=35014,d,e,f=1e4,g,h;
the variables are static since they are global so all variables not explicitly initialized will be initialized to 0
. Next we have an outer for loop:
for(;(b=c-=14); h=printf("%04ld",e+d/f)
^ ^ ^
1 2 3
- Is an empty initialization and it also a null statement.
- Is subtracting
14
fromc
and assigning the value back toc
and also assigning the same value tob
. This loop will execute2500
times since35014/14
is 2501 and on the2501
th iteration the result will0
and thus false and the loop will stop. h
is being assigned the result ofprintf
which is the number of characters printed. What is being printed out is the result ofe+d/f
and always at least 4 digits and zero padded due to04
in the format specifier.
Now we have an inner for loop:
for(e=d%=f;(g=--b*2);d/=g)
^ ^ ^
1 2 3
- Initializes
e
andd
tod modulus f
. - Due to operator precedence does a pre-decrement of
b
and multiples that by2
and assigns the result tog
d
is being divided byg
and assigned the result.
Finally the body of the inner for loop:
d=d*b+f*(h?a[b]:f/5), a[b]=d%--g;
^ ^
1 2
uses both the conditional operator in 1
and comma operator in 2
. So we could at least split this into:
d = d*b+f*(h?a[b]:f/5) ; // (1)
a[b] = d%--g; // (2)
(1)
can further be broken down into:
long tmp = h ? a[b] : f/5 ; // conditional operator
d = (d * b) + f * tmp;
The conditional operator only matters during the first iteration since h
is intialized to 0
but will never be 0
again afterwards since it is always assigned a non-zero value in the outer for loop, so other then the first time h
will be assigned a[b]
.
(2)
will again due to precedence pre-decrement g
first and then evaluate d
modulus the result and assign that to a[b]
.