Middle-square method

This is an old revision of this page, as edited by Charles Matthews (talk | contribs) at 12:16, 22 February 2006 (better link). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

In mathematics, the middle-square method is a method of generating pseudorandom numbers. In practice it is not a good method, since its period is usually very short and it has some crippling weaknesses. The method was first suggested by John Von Neumann in 1946.

For example, to generate a sequence of ten-digit pseudorandom numbers, you would create a ten-digit starting value and square it. The middle ten digits of the result would be the next number in the sequence. You would then square that, and so on.

Clearly, for a generator of n-digit numbers, the period can be no longer than 10n. If the middle ten digits are all zeroes, the generator then outputs zeroes forever. If the first half of a number in the sequence is zeroes, the subsequent numbers will be decreasing to zero. While these runs of zero are easy to detect, they occur too frequently for this method to be of practical use.

Von Neumann was aware of these problems, but for his purposes the middle-square method was quick (important for use on the ENIAC), and its errors were easy to detect (when it failed, it generally failed spectacularly).


The following is a simple C++ program that generates the random numbers given an initial remainder we refer to as Zo= Xn in our case above.

#include<iostream.h>
void main()
{
  int n=0,a,c,m,Z[100];
  float U[100];
  cout<<"enter z "<<endl;
  cin>>Z[0];
  cout<<"enter a "<<endl;
  cin>>a;
  cout<<"enter c "<<endl; 
  cin>>c;
  cout<<"enter m "<<endl; 
  cin>>m;                
  cout<<"n"<<"\t"<<"Zn"<<"\t"<<"Un"<<"\t"<<endl;
  cout<<"..."<<"\t"<<"..."<<"\t"<<"..."<<"\t"<<endl;
  do {
    Z[n+1]=((Z[n]*a)+c)%m;
    if(Z[n+1]!=0)
      U[n+1]=(float)1/(Z[n+1]);
    else
      Z[n+1]=0;   

    cout<<n<<"\t"<<Z[n+1]<<"\t"<<U[n+1]<<"\t"<<endl;
    n++;
  } while(Z[n]!=Z[0]);

}

See also