pmontgom@euphemia.math.ucla.edu (Peter Montgomery) (08/02/90)
In article <9858@marque.mu.edu> yossie@marque.mu.edu (Yossie Silverman) writes: >This sort of counts. I think this source has to be the most obfuscated >piece of FORTRAN I have ever seen. No, I didn't write it. I am not even >sure, to date, how it works! :-() > >C*********************************************************************** >C PROGRAM TO COMPUTE A TABLE OF POWERS OF 2 IN AN OBSCURE MANNER >C*********************************************************************** > INTEGER N(134)/'0','1',132*'0'/,L(2)/'(133',' A1)'/,G/133/,H/266/ > DO 1 K = G, 17688 > IF(K.EQ.K/G*G)WRITE(6,L)(L(2),J=K,17689,H),(N((K-J)/G+2),J=G,K,G) > N(J-K+1)=2**24*MOD((N(J-K+1)-N(1)+(N(J-K)-N(1))/10)/2**23,10)+N(1) > 1 IF(MOD(K+1,G).EQ.0.AND.N(J/G+1).LE.N(1))K=K-G > END > The program is non-standard in at least four ways: (i) initialization on a type declaration line (ii) mixing character and integer data (N and L) (iii) assuming a specific representation for characters (i.e., arithmetic was illegal on Hollerith data) (iv) modification of a DO loop index (K) The intended meaning is probably integer G, J, K parameter (G = 133) integer N(1:G+1) data N/'0', '1', 132*'0'/ K = G do while (K .lt. G**2) if (MOD(K,G).eq.0) then write(6, '(133A1)') (' ', J = K, G**2, 2*G), * (N((K-J)/G + 2), J = G,K,G) J = (final value of J from above DO loop) end if N(J-K+1)=2**24*MOD((N(J-K+1)-N(1)+(N(J-K)-N(1))/10)/2**23,10) * +N(1) if (MOD(K+1, G).eq.0 .and. N(J/G+1) .le. N(1)) K = K - G K = K + 1 end do end Since J is constant for long periods, let's modify the loop structure so J is modified only in an outer loop. The final value of J was probably K + G (since K is a multiple of G at that point), but some old compilers may set J = K instead: K = G do while (K .lt. G**2) write(6, '(133A1)') (' ', J = K, G**2, 2*G), * (N((K-J)/G + 2), J = G,K,G) J = K + G do N(J-K+1)=2**24*MOD((N(J-K+1)-N(1)+(N(J-K)-N(1))/10)/2**23,10) * +N(1) K = K + 1 until (MOD(K,G).eq.0) if (N(J/G+1) .le. N(1)) K = K - G end do The subscripts in the inner loop are functions of J-K. Letting L = J-K, and recalling J is a multiple of G, the inner loop becomes J = K + G do L = G, 1, -1 N(L+1)=2**24*MOD((N(L+1)-N(1)+(N(L)-N(1))/10)/2**23,10)+N(1) end do K = K + G Since L >= 1, N(1) is never modified and is always '0'. And it N(L+1) is always a multiple of 2**24 more than N(1). Replacing N(i) by (N(i)-'0')/2**24 and making other simplifications gives: integer G, J, K, L parameter (G = 133) integer N(1:G+1) data N/0, 1, 132*0/ K = G do while (K .lt. G**2) write(6, '(133A1)') (' ', J = K/G, G, 2), * (N(K/G-J + 2)*2**24 + '0', J = 1,K/G) do L = G, 1, -1 N(L+1) = MOD((2**24*N(L+1)+2**24*N(L)/10)/2**23, 10) end do K = K + G if (N(K/G+1) .le. 0) K = K - G end do We can simplify (2**24*N(L+1)+2**24*N(L)/10)/2**23 to 2*N(L+1) + N(L)/5. Also replace K/G by K to get integer G, J, K, L parameter (G = 133) integer N(1:G+1) data N/0, 1, 132*0/ K = 1 do while (K .lt. G) write(6, '(133A1)') (' ', J = K,G,2), * (N(J)*2**24 + '0', J = K+1,2,-1) do L = G, 1, -1 N(L+1) = MOD(2*N(L+1) + N(L)/5, 10) end do if (N(K+2) .gt. 0) K = K + 1 end do Now the algorithm is understandable (except perhaps the write statement). K is the width of the number being written, with least significant digit in N(2). There are approximately (133-K)/2 blanks (including Fortran carriage control) followed by K digits, so the output is centered on the page. Outputs continue until K = 133 when the printer page would be full. -- Peter L. Montgomery pmontgom@MATH.UCLA.EDU Department of Mathematics, UCLA, Los Angeles, CA 90024-1555 If I spent as much time on my dissertation as I do reading news, I'd graduate.