Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!ucsd!helios.ee.lbl.gov!nosc!manta!psm From: psm@manta.NOSC.MIL (Scot Mcintosh) Newsgroups: comp.lang.c Subject: Re: Random long-number generator Keywords: random maxint Message-ID: <983@manta.NOSC.MIL> Date: 24 Dec 89 20:11:56 GMT References: <83943@linus.UUCP> <1486@skye.ed.ac.uk> Reply-To: psm@manta.nosc.mil.UUCP (Scot Mcintosh) Organization: Naval Ocean Systems Center, San Diego Lines: 294 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; imyq) == (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@helios.nosc.mil UUCP: {ihnp4,akgua,decvax,decwest,ucbvax}!sdscvax!nosc!psm