Random long-number generator

Scot Mcintosh psm at manta.NOSC.MIL
Mon Dec 25 07:11:56 AEST 1989


Here's a random number generator that I like.  It comes from
Knuth's Seminumerical algorithms, and has a very long period.
(2^55).  This one was written for Microsoft C.  It should
work equally well if you change the 'int's to 'long's, and
make a few adjustments in the seeding.

static unsigned xa[55];
static int j,k;

static void RandSeed()  /* Seed our random number generator */
{
    register unsigned i;
    srand(1);	   /* Seed the c library random number generator   */
    for (i=0; i<55; i++)xa[i] = rand();
    j = 23;
    k = 54;
}

unsigned Rand()  /* Generate a pseudorandom number */
{
    register unsigned x;

    x = xa[k] += xa[j];
    if (j == 0)j = 55; --j;
    if (k == 0)k = 55; --k;
    return (x);
}


/****************************************************************************************************								
*  Procedure: GS_frmq 						                                    *				    
*								                                    *
*  Remove a far item from the Queue             		                                    *
*								                                    *
*  INPUTS:           fitmq *q       - Pointer to the Queue to remove an item from	            *
*								                                    *
*  RETURNS:          fitm far *     - Pointer to the item removed from the queue	            *
*								                                    *
*  LOCAL VARIABLES:  fitmq far *fqtmp - Temporary queue item pointer	                            *
*		     fitmq far *fqtmp2- 2nd temporary queue item pointer			    *
*		     unsigned int intstat - Current processor interrupt status			    *	
*								                                    *
*  GLOBAL VARIABLES:						                                    *
*								                                    *
*  This routine removes an item from the specified queue.  The item removed is the one at the head  *
*  of the queue.                                                                       	            *
*								                                    *
****************************************************************************************************/
tMsg far *GS_frmq (q)
fitmq *q;
{    
fitm far *fqtmp; 
fitm far *fqtmp2; 
register unsigned intstat = disable();

/* GS_QueueCheck(q); */  /*DEBUG*/

    if( (q)->q_hd != (fitm far *)NULL)
        if( ((q)->q_hd)->myq != q)             /* Error if top item on q does not belong to this q */
	    FERROR("Q rem err");

    fqtmp2 = 
    ( ((fqtmp = (q)->q_hd) == ((fitm far *) NULL)) ? ((fitm far *) NULL) :\
		  ( ( (((q)->q_hd = fqtmp->i_lnk) == ((fitm far *) NULL)) ? \
		      ( ((q)->q_tl = &(q)->q_hd), (q)->q_nq-- ) : \
		      (q)->q_nq-- ), fqtmp ) ) ;
    enable(intstat);

    (fqtmp2->myq) = (fitmq *)NULL;             /* Indicate this item is no longer part of this q   */
    return (tMsg far *)fqtmp2;

}






/****************************************************************************************************								
*  Procedure: GS_faddq						                                    *				    
*								                                    *
*  Add a far item to the Queue                  		                                    *
*								                                    *
*  INPUTS:           tMsg far *i    - Pointer to the item to be added onto the queue		    *
*                    fitmq *q       - Pointer to the Queue to add an item to	                    *
*								                                    *
*  RETURNS:                                                                             	    *
*								                                    *
*  LOCAL VARIABLES:  char far *chrptr - Item pointer converted to a character pointer	            *
*		     unsigned int intstat - Current processor interrupt status			    *	
*								                                    *
*  GLOBAL VARIABLES:						                                    *
*								                                    *
*  This routine adds an item onto the specified queue.  The item is added at the tail of the queue  *
*								                                    *
****************************************************************************************************/
void GS_faddq(q,i)
    fitmq *q;
    tMsg far *i;
{
    register unsigned intstat = disable();
    char far *chrptr;

/* GS_QueueCheck(q);*/	/*DEBUG*/

     					   /* Error if this item is null or belongs to a q already */
    if(( i == (tMsg far *)NULL )|| ( (i->iob).myq != (fitmq *)NULL) )
	FERROR("Q add err");

                                           /* DEBUG ONLY-Error if item doesnt start at a valid addr*/
    chrptr = (char far *) i;
    if( !((unsigned int)(((uns long)chrptr-((uns long)(&g_MNHbufs1[0][0])))%sizeof(tMsg) == (unsigned int)NULL))/* ||
	  ((unsigned int)((uns long)chrptr-((uns long)(&g_MNHbufs2[0][0])))%sizeof(tMsg) == (unsigned int)NULL))	 */ )
		FERROR("Illegal item addr");

    (i->iob).myq = q;			   /* Mark item as belonging to this queue	           */
    ( (((fitm far*) i)->i_lnk = ((fitm far *) NULL)), \
	 (*(q)->q_tl = ((fitm far*) i)), \
	 ((q)->q_tl = &((fitm far*) i)->i_lnk), ((q)->q_nq++) );
    enable(intstat);
}

/* The following is a DEBUG routine that checks a queue for internal
   consistency
*/
void GS_QueueCheck(qp)
    fitmq *qp;
{
    fitm far *ptr =  (fitm far *)((qp)->q_hd);
    register unsigned i = 0;

    while( ptr != (fitm far *)NULL)
    {
/*	  if  ((unsigned int)(((uns long)ptr-((uns long)(&g_MNHbufs1[0][0])))%sizeof(tMsg) == (unsigned int)NULL)) ||
	     ((unsigned int)((uns long)ptr-((uns long)(&g_MNHbufs2[0][0])))%sizeof(tMsg) == (unsigned int)NULL))  
	{
*/
	    if(++i > 80)
		FERROR("Endless Q");
	    if(ptr->myq != qp)
		FERROR("Q has illegal member");
	    ptr = ptr->i_lnk;
/*	}else{

	    FERROR("Illegal fiorb addr");
	}
*/
    }

    if( i != ((qp)->q_nq) )
       FERROR("Q err");
}




/****************************************************************************************************
*												    *		
*  PROCEDURE:  GS_PostMortem   								    	    *
*												    *
*  Routine to account for all MNH buffers upon an error condition                   		    *
*												    *
*  INPUTS:											    *
*												    *
*  RETURNS:											    *
*												    *	
*  LOCAL VARIABLES:										    *
*												    *	
*  GLOBAL VARIABLES:										    *	  
*												    *		
****************************************************************************************************/

struct tbufacct
{  unsigned char g_nMbq, g_qMbq, g_nBadQ, g_qBadQ, g_nNCHistoryQueue, g_qNCHistoryQueue;
unsigned char g_nOpq, g_qOpq, g_nRrq, g_qRrq, g_nRfq, g_qRfq;
unsigned char g_nmRmq, g_qmRmq, g_nrRmq, g_qrRmq;
unsigned char g_nGWq, g_qGWq, g_nInMsgQueue, g_qInMsgQueue;
unsigned char g_nRlyMsgQueue, g_qRlyMsgQueue, g_nSelfSendQueue, g_qSelfSendQueue;
unsigned char g_nTcq, g_qTcq;
unsigned char g_nTmq, g_qTmq, g_nOcq, g_qOcq, g_nCcq, g_qCcq, g_nCiq, g_qCiq;
}ba;

fitmq g_lost;
fitmq g_invalid;

GS_PostMortem()
{ 	  
fitmq *temp;
unsigned char i;

    fclrq (&g_lost);
    fclrq (&g_invalid);
    ba.g_nMbq = 0;
    ba.g_nBadQ = 0;
    ba.g_nNCHistoryQueue = 0;
    ba.g_nOpq = 0;
    ba.g_nRrq = 0;
    ba.g_nRfq = 0;
    ba.g_nmRmq = 0;
    ba.g_nrRmq = 0;
    ba.g_nGWq = 0;
    ba.g_nInMsgQueue = 0;
    ba.g_nRlyMsgQueue = 0;
    ba.g_nSelfSendQueue = 0;
    ba.g_nTcq = 0;
    ba.g_nTmq = 0;
    ba.g_nOcq = 0;
    ba.g_nCcq = 0;
    ba.g_nCiq = 0;

    ba.g_qMbq = g_Mbq.q_nq;
    ba.g_qBadQ = g_BadQ.q_nq;
    ba.g_qNCHistoryQueue = g_NCHistoryQueue.q_nq;
    ba.g_qOpq = m_Opq.q_nq;
    ba.g_qRrq = m_Rrq.q_nq;
    ba.g_qRfq = m_Rfq.q_nq;
    ba.g_qmRmq = m_Rmq.q_nq;
    ba.g_qrRmq = r_Rmq.q_nq;
    ba.g_qInMsgQueue = n_InMsgQueue.q_nq;
    ba.g_qRlyMsgQueue = n_RlyMsgQueue.q_nq;
    ba.g_qSelfSendQueue = n_SelfSendQueue.q_nq;
    ba.g_qTcq = t_Tcq.q_nq;
    ba.g_qTmq = t_Tmq.q_nq;
    ba.g_qOcq = t_Ocq.q_nq;
    ba.g_qCcq = t_Ccq.q_nq;
    ba.g_qCiq = t_Ciq.q_nq;

    for (i=0; i<NUMBUFS/2; i++)	 
	{   
	    if ((fitmq *)(((fiorb far *)&g_MNHbufs1[i][0])->myq) == (fitmq *) &g_Mbq)
		ba.g_nMbq++;
                else
            if ((fitmq *)(((fiorb far *)&g_MNHbufs1[i][0])->myq) == (fitmq *) &g_BadQ)
		ba.g_nBadQ++;
                else
            if ((fitmq *)(((fiorb far *)&g_MNHbufs1[i][0])->myq) == (fitmq *) &g_NCHistoryQueue)
		ba.g_nNCHistoryQueue++;
                else
            if ((fitmq *)(((fiorb far *)&g_MNHbufs1[i][0])->myq) == (fitmq *) &m_Opq)  
		ba.g_nOpq++;
                else
            if ((fitmq *)(((fiorb far *)&g_MNHbufs1[i][0])->myq) == (fitmq *) &m_Rrq)
		ba.g_nRrq++;
                else
            if ((fitmq *)(((fiorb far *)&g_MNHbufs1[i][0])->myq) == (fitmq *) &m_Rfq)
		ba.g_nRfq++;
                else
            if ((fitmq *)(((fiorb far *)&g_MNHbufs1[i][0])->myq) == (fitmq *) &m_Rmq)
		ba.g_nmRmq++;
                else
            if ((fitmq *)(((fiorb far *)&g_MNHbufs1[i][0])->myq) == (fitmq *) &r_Rmq)
		ba.g_nrRmq++;
                else
            if ((fitmq *)(((fiorb far *)&g_MNHbufs1[i][0])->myq) == (fitmq *) &n_InMsgQueue)
		ba.g_nInMsgQueue++;
                else
            if ((fitmq *)(((fiorb far *)&g_MNHbufs1[i][0])->myq) == (fitmq *) &n_RlyMsgQueue)
		ba.g_nRlyMsgQueue++;
                else
            if ((fitmq *)(((fiorb far *)&g_MNHbufs1[i][0])->myq) == (fitmq *) &n_SelfSendQueue)
		ba.g_nSelfSendQueue++;
                else
            if ((fitmq *)(((fiorb far *)&g_MNHbufs1[i][0])->myq) == (fitmq *) &t_Tcq) 
		ba.g_nTcq++;
                else
            if ((fitmq *)(((fiorb far *)&g_MNHbufs1[i][0])->myq) == (fitmq *) &t_Tmq)
		ba.g_nTmq++;
                else
            if ((fitmq *)(((fiorb far *)&g_MNHbufs1[i][0])->myq) == (fitmq *) &t_Ocq)
		ba.g_nOcq++;
                else
            if ((fitmq *)(((fiorb far *)&g_MNHbufs1[i][0])->myq) == (fitmq *) &t_Ccq)
		ba.g_nCcq++;
                else
            if ((fitmq *)(((fiorb far *)&g_MNHbufs1[i][0])->myq) == (fitmq *) &t_Ciq)
		ba.g_nCiq++;
                else
            if ((fitmq *)(((fiorb far *)&g_MNHbufs1[i][0])->myq) == (fitmq *)NULL)
              { faddq (&g_lost, &g_MNHbufs1[i][0]);}
                else
              { temp = ((fitmq *)(((fiorb far *)&g_MNHbufs1[i][0])->myq));
                ((fiorb far *)&g_MNHbufs1[i][0])->myq = (fitmq *)NULL;
		faddq (&g_invalid, &g_MNHbufs1[i][0]);
                ((fiorb far *)&g_MNHbufs1[i][0])->myq = (fitmq *)temp;
	      } ;      
	}
}


-- 
----
Scot McIntosh
Internet: psm at helios.nosc.mil
UUCP:     {ihnp4,akgua,decvax,decwest,ucbvax}!sdscvax!nosc!psm



More information about the Comp.lang.c mailing list