source: vendor/python/2.5/Objects/rangeobject.c

Last change on this file was 3225, checked in by bird, 19 years ago

Python 2.5

File size: 7.9 KB
Line 
1/* Range object implementation */
2
3#include "Python.h"
4
5typedef struct {
6 PyObject_HEAD
7 long start;
8 long step;
9 long len;
10} rangeobject;
11
12/* Return number of items in range/xrange (lo, hi, step). step > 0
13 * required. Return a value < 0 if & only if the true value is too
14 * large to fit in a signed long.
15 */
16static long
17get_len_of_range(long lo, long hi, long step)
18{
19 /* -------------------------------------------------------------
20 If lo >= hi, the range is empty.
21 Else if n values are in the range, the last one is
22 lo + (n-1)*step, which must be <= hi-1. Rearranging,
23 n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives
24 the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so
25 the RHS is non-negative and so truncation is the same as the
26 floor. Letting M be the largest positive long, the worst case
27 for the RHS numerator is hi=M, lo=-M-1, and then
28 hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough
29 precision to compute the RHS exactly.
30 ---------------------------------------------------------------*/
31 long n = 0;
32 if (lo < hi) {
33 unsigned long uhi = (unsigned long)hi;
34 unsigned long ulo = (unsigned long)lo;
35 unsigned long diff = uhi - ulo - 1;
36 n = (long)(diff / (unsigned long)step + 1);
37 }
38 return n;
39}
40
41static PyObject *
42range_new(PyTypeObject *type, PyObject *args, PyObject *kw)
43{
44 rangeobject *obj;
45 long ilow = 0, ihigh = 0, istep = 1;
46 long n;
47
48 if (!_PyArg_NoKeywords("xrange()", kw))
49 return NULL;
50
51 if (PyTuple_Size(args) <= 1) {