⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 random.c

📁 newos is new operation system
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 1983, 1993 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD: src/lib/libc/stdlib/random.c,v 1.13 2000/01/27 23:06:49 jasone Exp $ * */#if defined(LIBC_SCCS) && !defined(lint)static char sccsid[] = "@(#)random.c	8.2 (Berkeley) 5/19/95";#endif /* LIBC_SCCS and not lint *///#include <sys/time.h>          /* for srandomdev() *///#include <fcntl.h>             /* for srandomdev() */#include <stdio.h>#include <stdlib.h>//#include <unistd.h>            /* for srandomdev() *//* * random.c: * * An improved random number generation package.  In addition to the standard * rand()/srand() like interface, this package also has a special state info * interface.  The initstate() routine is called with a seed, an array of * bytes, and a count of how many bytes are being passed in; this array is * then initialized to contain information for random number generation with * that much state information.  Good sizes for the amount of state * information are 32, 64, 128, and 256 bytes.  The state can be switched by * calling the setstate() routine with the same array as was initiallized * with initstate().  By default, the package runs with 128 bytes of state * information and generates far better random numbers than a linear * congruential generator.  If the amount of state information is less than * 32 bytes, a simple linear congruential R.N.G. is used. * * Internally, the state information is treated as an array of longs; the * zeroeth element of the array is the type of R.N.G. being used (small * integer); the remainder of the array is the state information for the * R.N.G.  Thus, 32 bytes of state information will give 7 longs worth of * state information, which will allow a degree seven polynomial.  (Note: * the zeroeth word of state information also has some other information * stored in it -- see setstate() for details). * * The random number generation technique is a linear feedback shift register * approach, employing trinomials (since there are fewer terms to sum up that * way).  In this approach, the least significant bit of all the numbers in * the state table will act as a linear feedback shift register, and will * have period 2^deg - 1 (where deg is the degree of the polynomial being * used, assuming that the polynomial is irreducible and primitive).  The * higher order bits will have longer periods, since their values are also * influenced by pseudo-random carries out of the lower bits.  The total * period of the generator is approximately deg*(2**deg - 1); thus doubling * the amount of state information has a vast influence on the period of the * generator.  Note: the deg*(2**deg - 1) is an approximation only good for * large deg, when the period of the shift register is the dominant factor. * With deg equal to seven, the period is actually much longer than the * 7*(2**7 - 1) predicted by this formula. * * Modified 28 December 1994 by Jacob S. Rosenberg. * The following changes have been made: * All references to the type u_int have been changed to unsigned long. * All references to type int have been changed to type long.  Other * cleanups have been made as well.  A warning for both initstate and * setstate has been inserted to the effect that on Sparc platforms * the 'arg_state' variable must be forced to begin on word boundaries. * This can be easily done by casting a long integer array to char *. * The overall logic has been left STRICTLY alone.  This software was * tested on both a VAX and Sun SpacsStation with exactly the same * results.  The new version and the original give IDENTICAL results. * The new version is somewhat faster than the original.  As the * documentation says:  "By default, the package runs with 128 bytes of * state information and generates far better random numbers than a linear * congruential generator.  If the amount of state information is less than * 32 bytes, a simple linear congruential R.N.G. is used."  For a buffer of * 128 bytes, this new version runs about 19 percent faster and for a 16 * byte buffer it is about 5 percent faster. *//* * For each of the currently supported random number generators, we have a * break value on the amount of state information (you need at least this * many bytes of state info to support this random number generator), a degree * for the polynomial (actually a trinomial) that the R.N.G. is based on, and * the separation between the two lower order coefficients of the trinomial. */#define	TYPE_0		0		/* linear congruential */#define	BREAK_0		8#define	DEG_0		0#define	SEP_0		0#define	TYPE_1		1		/* x**7 + x**3 + 1 */#define	BREAK_1		32#define	DEG_1		7#define	SEP_1		3#define	TYPE_2		2		/* x**15 + x + 1 */#define	BREAK_2		64#define	DEG_2		15#define	SEP_2		1#define	TYPE_3		3		/* x**31 + x**3 + 1 */#define	BREAK_3		128#define	DEG_3		31#define	SEP_3		3#define	TYPE_4		4		/* x**63 + x + 1 */#define	BREAK_4		256#define	DEG_4		63#define	SEP_4		1/* * Array versions of the above information to make code run faster -- * relies on fact that TYPE_i == i. */#define	MAX_TYPES	5		/* max number of types above */// not supported by NewOS right now#if 0static long degrees[MAX_TYPES] =	{ DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };static long seps [MAX_TYPES] =	{ SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };#endif/* * Initially, everything is set up as if from: * *	initstate(1, randtbl, 128); * * Note that this initialization takes advantage of the fact that srandom() * advances the front and rear pointers 10*rand_deg times, and hence the * rear pointer which starts at 0 will also end up at zero; thus the zeroeth * element of the state information, which contains info about the current * position of the rear pointer is just * *	MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3. */static long randtbl[DEG_3 + 1] = {	TYPE_3,#ifdef  USE_WEAK_SEEDING/* Historic implementation compatibility *//* The random sequences do not vary much with the seed */	0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, 0xde3b81e0, 0xdf0a6fb5,	0xf103bc02, 0x48f340fb, 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd,	0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 0xda672e2a, 0x1588ca88,	0xe369735d, 0x904f35f7, 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc,	0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 0xf5ad9d0e, 0x8999220b,	0x27fb47b9,#else   /* !USE_WEAK_SEEDING */	0x991539b1, 0x16a5bce3, 0x6774a4cd, 0x3e01511e, 0x4e508aaa, 0x61048c05,	0xf5500617, 0x846b7115, 0x6a19892c, 0x896a97af, 0xdb48f936, 0x14898454,	0x37ffd106, 0xb58bff9c, 0x59e17104, 0xcf918a49, 0x09378c83, 0x52c7a471,	0x8d293ea9, 0x1f4fc301, 0xc3db71be, 0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1,	0x19edc328, 0x87bf4bdd, 0xc9b240e5, 0xe9ee4b1b, 0x4382aee7, 0x535b6b41,	0xf3bec5da#endif  /* !USE_WEAK_SEEDING */};/* * fptr and rptr are two pointers into the state info, a front and a rear * pointer.  These two pointers are always rand_sep places aparts, as they * cycle cyclically through the state information.  (Yes, this does mean we * could get away with just one pointer, but the code for random() is more * efficient this way).  The pointers are left positioned as they would be * from the call * *	initstate(1, randtbl, 128); * * (The position of the rear pointer, rptr, is really 0 (as explained above * in the initialization of randtbl) because the state table pointer is set * to point to randtbl[1] (as explained below). */static long *fptr = &randtbl[SEP_3 + 1];static long *rptr = &randtbl[1];/* * The following things are the pointer to the state information table, the * type of the current generator, the degree of the current polynomial being * used, and the separation between the two pointers.  Note that for efficiency * of random(), we remember the first location of the state information, not * the zeroeth.  Hence it is valid to access state[-1], which is used to * store the type of the R.N.G.  Also, we remember the last location, since * this is more efficient than indexing every time to find the address of * the last element to see if the front and rear pointers have wrapped. */static long *state = &randtbl[1];static long rand_type = TYPE_3;static long rand_deg = DEG_3;static long rand_sep = SEP_3;static long *end_ptr = &randtbl[DEG_3 + 1];static inline long good_rand(long);static inline long good_rand(long x){#ifdef  USE_WEAK_SEEDING/* * Historic implementation compatibility. * The random sequences do not vary much with the seed, * even with overflowing. */	return (1103515245 * x + 12345);#else   /* !USE_WEAK_SEEDING *//* * Compute x = (7^5 * x) mod (2^31 - 1) * wihout overflowing 31 bits: *      (2^31 - 1) = 127773 * (7^5) + 2836 * From "Random number generators: good ones are hard to find", * Park and Miller, Communications of the ACM, vol. 31, no. 10, * October 1988, p. 1195. */	register long hi, lo;	hi = x / 127773;	lo = x % 127773;	x = 16807 * lo - 2836 * hi;	if (x <= 0)		x += 0x7fffffff;	return (x);#endif  /* !USE_WEAK_SEEDING */}/* * srandom: *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -