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