Annotation of embedaddon/php/ext/standard/lcg.c, revision 1.1
1.1 ! misho 1: /*
! 2: +----------------------------------------------------------------------+
! 3: | PHP Version 5 |
! 4: +----------------------------------------------------------------------+
! 5: | Copyright (c) 1997-2012 The PHP Group |
! 6: +----------------------------------------------------------------------+
! 7: | This source file is subject to version 3.01 of the PHP license, |
! 8: | that is bundled with this package in the file LICENSE, and is |
! 9: | available through the world-wide-web at the following url: |
! 10: | http://www.php.net/license/3_01.txt |
! 11: | If you did not receive a copy of the PHP license and are unable to |
! 12: | obtain it through the world-wide-web, please send a note to |
! 13: | license@php.net so we can mail you a copy immediately. |
! 14: +----------------------------------------------------------------------+
! 15: | Author: Sascha Schumann <sascha@schumann.cx> |
! 16: +----------------------------------------------------------------------+
! 17: */
! 18:
! 19: /* $Id: lcg.c 321634 2012-01-01 13:15:04Z felipe $ */
! 20:
! 21: #include "php.h"
! 22: #include "php_lcg.h"
! 23:
! 24: #if HAVE_UNISTD_H
! 25: #include <unistd.h>
! 26: #endif
! 27:
! 28: #ifdef PHP_WIN32
! 29: #include "win32/time.h"
! 30: #else
! 31: #include <sys/time.h>
! 32: #endif
! 33:
! 34: #ifdef ZTS
! 35: int lcg_globals_id;
! 36: #else
! 37: static php_lcg_globals lcg_globals;
! 38: #endif
! 39:
! 40: #ifdef PHP_WIN32
! 41: #include <process.h>
! 42: #endif
! 43:
! 44: /*
! 45: * combinedLCG() returns a pseudo random number in the range of (0, 1).
! 46: * The function combines two CGs with periods of
! 47: * 2^31 - 85 and 2^31 - 249. The period of this function
! 48: * is equal to the product of both primes.
! 49: */
! 50:
! 51: #define MODMULT(a, b, c, m, s) q = s/a;s=b*(s-a*q)-c*q;if(s<0)s+=m
! 52:
! 53: static void lcg_seed(TSRMLS_D);
! 54:
! 55: PHPAPI double php_combined_lcg(TSRMLS_D) /* {{{ */
! 56: {
! 57: php_int32 q;
! 58: php_int32 z;
! 59:
! 60: if (!LCG(seeded)) {
! 61: lcg_seed(TSRMLS_C);
! 62: }
! 63:
! 64: MODMULT(53668, 40014, 12211, 2147483563L, LCG(s1));
! 65: MODMULT(52774, 40692, 3791, 2147483399L, LCG(s2));
! 66:
! 67: z = LCG(s1) - LCG(s2);
! 68: if (z < 1) {
! 69: z += 2147483562;
! 70: }
! 71:
! 72: return z * 4.656613e-10;
! 73: }
! 74: /* }}} */
! 75:
! 76: static void lcg_seed(TSRMLS_D) /* {{{ */
! 77: {
! 78: struct timeval tv;
! 79:
! 80: if (gettimeofday(&tv, NULL) == 0) {
! 81: LCG(s1) = tv.tv_sec ^ (tv.tv_usec<<11);
! 82: } else {
! 83: LCG(s1) = 1;
! 84: }
! 85: #ifdef ZTS
! 86: LCG(s2) = (long) tsrm_thread_id();
! 87: #else
! 88: LCG(s2) = (long) getpid();
! 89: #endif
! 90:
! 91: /* Add entropy to s2 by calling gettimeofday() again */
! 92: if (gettimeofday(&tv, NULL) == 0) {
! 93: LCG(s2) ^= (tv.tv_usec<<11);
! 94: }
! 95:
! 96: LCG(seeded) = 1;
! 97: }
! 98: /* }}} */
! 99:
! 100: static void lcg_init_globals(php_lcg_globals *lcg_globals_p TSRMLS_DC) /* {{{ */
! 101: {
! 102: LCG(seeded) = 0;
! 103: }
! 104: /* }}} */
! 105:
! 106: PHP_MINIT_FUNCTION(lcg) /* {{{ */
! 107: {
! 108: #ifdef ZTS
! 109: ts_allocate_id(&lcg_globals_id, sizeof(php_lcg_globals), (ts_allocate_ctor) lcg_init_globals, NULL);
! 110: #else
! 111: lcg_init_globals(&lcg_globals);
! 112: #endif
! 113: return SUCCESS;
! 114: }
! 115: /* }}} */
! 116:
! 117: /* {{{ proto float lcg_value()
! 118: Returns a value from the combined linear congruential generator */
! 119: PHP_FUNCTION(lcg_value)
! 120: {
! 121: RETURN_DOUBLE(php_combined_lcg(TSRMLS_C));
! 122: }
! 123: /* }}} */
! 124:
! 125: /*
! 126: * Local variables:
! 127: * tab-width: 4
! 128: * c-basic-offset: 4
! 129: * End:
! 130: * vim600: sw=4 ts=4 fdm=marker
! 131: * vim<600: sw=4 ts=4
! 132: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>