summaryrefslogtreecommitdiffstats
path: root/Lib/whrandom.py
blob: f43b2f900a515da6a874ed93670d6e9e8b8c814c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
"""Wichman-Hill random number generator.

Wichmann, B. A. & Hill, I. D. (1982)
Algorithm AS 183: 
An efficient and portable pseudo-random number generator
Applied Statistics 31 (1982) 188-190

see also: 
        Correction to Algorithm AS 183
        Applied Statistics 33 (1984) 123  

        McLeod, A. I. (1985)
        A remark on Algorithm AS 183 
        Applied Statistics 34 (1985),198-200


USE:
whrandom.random()       yields double precision random numbers 
                        uniformly distributed between 0 and 1.

whrandom.seed(x, y, z)  must be called before whrandom.random()
                        to seed the generator

There is also an interface to create multiple independent
random generators, and to choose from other ranges.



Multi-threading note: the random number generator used here is not
thread-safe; it is possible that nearly simultaneous calls in
different theads return the same random value.  To avoid this, you
have to use a lock around all calls.  (I didn't want to slow this
down in the serial case by using a lock here.)
"""

# Translated by Guido van Rossum from C source provided by
# Adrian Baddeley.


class whrandom:
	def __init__(self, x = 0, y = 0, z = 0):
		"""Initialize an instance.
		Without arguments, initialize from current time.
		With arguments (x, y, z), initialize from them."""
		self.seed(x, y, z)

	def seed(self, x = 0, y = 0, z = 0):
		"""Set the seed from (x, y, z).
		These must be integers in the range [0, 256)."""
		if not type(x) == type(y) == type(z) == type(0):
			raise TypeError, 'seeds must be integers'
		if not (0 <= x < 256 and 0 <= y < 256 and 0 <= z < 256):
			raise ValueError, 'seeds must be in range(0, 256)'
		if 0 == x == y == z:
			# Initialize from current time
			import time
			t = long(time.time() * 256)
			t = int((t&0xffffff) ^ (t>>24))
			t, x = divmod(t, 256)
			t, y = divmod(t, 256)
			t, z = divmod(t, 256)
		# Zero is a poor seed, so substitute 1
		self._seed = (x or 1, y or 1, z or 1)

	def random(self):
		"""Get the next random number in the range [0.0, 1.0)."""
		# This part is thread-unsafe:
		# BEGIN CRITICAL SECTION
		x, y, z = self._seed
		#
		x = (171 * x) % 30269
		y = (172 * y) % 30307
		z = (170 * z) % 30323
		#
		self._seed = x, y, z
		# END CRITICAL SECTION
		#
		return (x/30269.0 + y/30307.0 + z/30323.0) % 1.0

	def uniform(self, a, b):
		"""Get a random number in the range [a, b)."""
		return a + (b-a) * self.random()

	def randint(self, a, b):
		"""Get a random integer in the range [a, b] including
                both end points.

		(Deprecated; use randrange below.)"""
		return self.randrange(a, b+1)

	def choice(self, seq):
		"""Choose a random element from a non-empty sequence."""
		return seq[int(self.random() * len(seq))]

	def randrange(self, start, stop=None, step=1, int=int, default=None):
		"""Choose a random item from range(start, stop[, step]).

		This fixes the problem with randint() which includes the
		endpoint; in Python this is usually not what you want.
                Do not supply the 'int' and 'default' arguments."""
		# This code is a bit messy to make it fast for the
		# common case while still doing adequate error checking
		istart = int(start)
		if istart != start:
			raise ValueError, "non-integer arg 1 for randrange()"
		if stop is default:
			if istart > 0:
				return int(self.random() * istart)
			raise ValueError, "empty range for randrange()"
		istop = int(stop)
		if istop != stop:
			raise ValueError, "non-integer stop for randrange()"
		if step == 1:
			if istart < istop:
				return istart + int(self.random() *
						   (istop - istart))
			raise ValueError, "empty range for randrange()"
		istep = int(step)
		if istep != step:
			raise ValueError, "non-integer step for randrange()"
		if istep > 0:
			n = (istop - istart + istep - 1) / istep
		elif istep < 0:
			n = (istop - istart + istep + 1) / istep
		else:
			raise ValueError, "zero step for randrange()"

		if n <= 0:
			raise ValueError, "empty range for randrange()"
		return istart + istep*int(self.random() * n)


# Initialize from the current time
_inst = whrandom()
seed = _inst.seed
random = _inst.random
uniform = _inst.uniform
randint = _inst.randint
choice = _inst.choice
randrange = _inst.randrange
'>initsubsystems2_split Tcl is a high-level, general-purpose, interpreted, dynamic programming language. It was designed with the goal of being very simple but powerful.
summaryrefslogtreecommitdiffstats
path: root/compat/strncasecmp.c
blob: 0a69f353bacd2db9fe672708f25147252545e551 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*
 * strncasecmp.c --
 *
 *	Source code for the "strncasecmp" library routine.
 *
 * Copyright (c) 1988-1993 The Regents of the University of California.
 * Copyright (c) 1995-1996 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tclPort.h"

/*
 * This array is designed for mapping upper and lower case letter together for
 * a case independent comparison. The mappings are based upon ASCII character
 * sequences.
 */

static const unsigned char charmap[] = {
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
    0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
    0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
    0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
    0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
    0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
    0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
    0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
    0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
    0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
    0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
    0xc0, 0xe1, 0xe2, 0xe3, 0xe4, 0xc5, 0xe6, 0xe7,
    0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
    0xf8, 0xf9, 0xfa, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
    0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
};

/*
 * Here are the prototypes just in case they are not included in tclPort.h.
 */

int		strncasecmp(const char *s1, const char *s2, size_t n);
int		strcasecmp(const char *s1, const char *s2);

/*
 *----------------------------------------------------------------------
 *
 * strcasecmp --
 *
 *	Compares two strings, ignoring case differences.
 *
 * Results:
 *	Compares two null-terminated strings s1 and s2, returning -1, 0, or 1
 *	if s1 is lexicographically less than, equal to, or greater than s2.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
strcasecmp(
    const char *s1,		/* First string. */
    const char *s2)		/* Second string. */
{
    unsigned char u1, u2;

    for ( ; ; s1++, s2++) {
	u1 = (unsigned char) *s1;
	u2 = (unsigned char) *s2;
	if ((u1 == '\0') || (charmap[u1] != charmap[u2])) {
	    break;
	}
    }
    return charmap[u1] - charmap[u2];
}

/*
 *----------------------------------------------------------------------
 *
 * strncasecmp --
 *
 *	Compares two strings, ignoring case differences.
 *
 * Results:
 *	Compares up to length chars of s1 and s2, returning -1, 0, or 1 if s1
 *	is lexicographically less than, equal to, or greater than s2 over
 *	those characters.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
strncasecmp(
    const char *s1,		/* First string. */
    const char *s2,		/* Second string. */
    size_t length)		/* Maximum number of characters to compare
				 * (stop earlier if the end of either string
				 * is reached). */
{
    unsigned char u1, u2;

    for (; length != 0; length--, s1++, s2++) {
	u1 = (unsigned char) *s1;
	u2 = (unsigned char) *s2;
	if (charmap[u1] != charmap[u2]) {
	    return charmap[u1] - charmap[u2];
	}
	if (u1 == '\0') {
	    return 0;
	}
    }
    return 0;
}