[Python-checkins] python/dist/src/Modules _randommodule.c,1.6,1.7

rhettinger at users.sourceforge.net rhettinger at users.sourceforge.net
Sun Oct 5 05:09:17 EDT 2003


Update of /cvsroot/python/python/dist/src/Modules
In directory sc8-pr-cvs1:/tmp/cvs-serv30780/Modules

Modified Files:
	_randommodule.c 
Log Message:
SF bug #812202:  randint is always even

* Added C coded getrandbits(k) method that runs in linear time.
* Call the new method from randrange() for ranges >= 2**53.
* Adds a warning for generators not defining getrandbits() whenever they
  have a call to randrange() with too large of a population.



Index: _randommodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/_randommodule.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** _randommodule.c	23 May 2003 03:55:41 -0000	1.6
--- _randommodule.c	5 Oct 2003 09:09:15 -0000	1.7
***************
*** 436,439 ****
--- 436,480 ----
  
  static PyObject *
+ random_getrandbits(RandomObject *self, PyObject *args)
+ {
+ 	int k, i, bytes;
+ 	unsigned long r;
+ 	unsigned char *bytearray;
+ 	PyObject *result;
+ 
+ 	if (!PyArg_ParseTuple(args, "i:getrandbits", &k))
+ 		return NULL;
+ 
+ 	if (k <= 0) {
+ 		PyErr_SetString(PyExc_ValueError,
+ 				"number of bits must be greater than zero");
+ 		return NULL;
+ 	}
+ 
+ 	bytes = ((k - 1) / 32 + 1) * 4;
+ 	bytearray = (unsigned char *)PyMem_Malloc(bytes);
+ 	if (bytearray == NULL) {
+ 		PyErr_NoMemory();
+ 		return NULL;
+ 	}
+ 
+ 	/* Fill-out whole words, byte-by-byte to avoid endianness issues */
+ 	for (i=0 ; i<bytes ; i+=4, k-=32) {
+ 		r = genrand_int32(self);
+ 		if (k < 32)
+ 			r >>= (32 - k);
+ 		bytearray[i+0] = (unsigned char)r;
+ 		bytearray[i+1] = (unsigned char)(r >> 8);
+ 		bytearray[i+2] = (unsigned char)(r >> 16);
+ 		bytearray[i+3] = (unsigned char)(r >> 24);
+ 	}
+ 
+ 	/* little endian order to match bytearray assignment order */
+ 	result = _PyLong_FromByteArray(bytearray, bytes, 1, 0);
+ 	PyMem_Free(bytearray);
+ 	return result;
+ }
+ 
+ static PyObject *
  random_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
  {
***************
*** 465,468 ****
--- 506,512 ----
  		PyDoc_STR("jumpahead(int) -> None.  Create new state from "
  			  "existing state and integer.")},
+ 	{"getrandbits",	(PyCFunction)random_getrandbits,  METH_VARARGS,
+ 		PyDoc_STR("getrandbits(k) -> x.  Generates a long int with "
+ 			  "k random bits.")},
  	{NULL,		NULL}		/* sentinel */
  };





More information about the Python-checkins mailing list