[issue4258] Use 30-bit digits instead of 15-bit digits for Python integers. - Code Review (original) (raw)
OLD
NEW
1 #ifndef Py_LONGINTREPR_H
1 #ifndef Py_LONGINTREPR_H
2 #define Py_LONGINTREPR_H
2 #define Py_LONGINTREPR_H
3 #ifdef __cplusplus
3 #ifdef __cplusplus
4 extern "C" {
4 extern "C" {
5 #endif
5 #endif
6
6
7
7
8 /* This is published for the benefit of "friend" marshal.c only. */
8 /* This is published for the benefit of "friend" marshal.c only. */
9
9
10 /* Parameters of the long integer representation.
10 /* Parameters of the long integer representation.
11 These shouldn't have to be changed as C should guarantee that a short
11 These shouldn't have to be changed as C should guarantee that a short
12 contains at least 16 bits, but it's made changeable anyway.
12 contains at least 16 bits, but it's made changeable anyway.
13 Note: 'digit' should be able to hold 2*MASK+1, and 'twodigits'
13 Note: 'digit' should be able to hold 2*MASK+1, and 'twodigits'
14 should be able to hold the intermediate results in 'mul'
14 should be able to hold the intermediate results in 'mul'
15 (at most (BASE-1)*(2*BASE+1) == MASK*(2*MASK+3)).
15 (at most (BASE-1)*(2*BASE+1) == MASK*(2*MASK+3)).
16 Also, x_sub assumes that 'digit' is an unsigned type, and overflow
16 Also, x_sub assumes that 'digit' is an unsigned type, and overflow
17 is handled by taking the result mod 2**N for some N > SHIFT.
17 is handled by taking the result mod 2**N for some N > SHIFT.
18 And, at some places it is assumed that MASK fits in an int, as well.
18 And, at some places it is assumed that MASK fits in an int, as well.
19 long_pow() requires that SHIFT be divisible by 5. */
19 long_pow() requires that SHIFT be divisible by 5. */
20
20
21 /* Additional restrictions: PyLong_SHIFT should be greater than or equal to 8,
22 and strictly less than the number of bits in an unsigned long. It should
23 also be strictly less than the number of bits in a Py_ssize_t.
24 Furthermore, NSMALLNEGINTS and NSMALLPOSINTS should fit in a digit. */
25
26
27 #if HAVE_STDINT_H
28 #include <stdint.h>
29 #endif
30
31 #if PYLONG_DIGIT_SIZE == 30
32 #if !(defined HAVE_UINT64_T && defined HAVE_UINT32_T && \
33 defined HAVE_INT64_T && defined HAVE_INT32_T)
34 #error "30-bit long digits requested, but the necessary types are not available on this platform"
35 #endif
36 typedef PY_UINT32_T digit;
37 typedef PY_INT32_T sdigit; /* signed variant of digit */
38 typedef PY_UINT64_T twodigits;
39 typedef PY_INT64_T stwodigits; /* signed variant of twodigits */
40 #define PyLong_SHIFT 30
41 #elif PYLONG_DIGIT_SIZE == 15
21 typedef unsigned short digit;
42 typedef unsigned short digit;
22 typedef short sdigit; /* signed variant of digit */
43 typedef short sdigit; /* signed variant of digit */
23 #define BASE_TWODIGITS_TYPE long
44 typedef unsigned long twodigits;
24 typedef unsigned BASE_TWODIGITS_TYPE twodigits;
45 typedef long stwodigits; /* signed variant of twodigits */
25 typedef BASE_TWODIGITS_TYPE stwodigits; /* signed variant of twodigits */
26
27 #define PyLong_SHIFT 15
46 #define PyLong_SHIFT 15
47 #else
48 #error "PYLONG_DIGIT_SIZE should be 15 or 30"
49 #endif
28 #define PyLong_BASE ((digit)1 << PyLong_SHIFT)
50 #define PyLong_BASE ((digit)1 << PyLong_SHIFT)
29 #define PyLong_MASK ((digit)(PyLong_BASE - 1))
51 #define PyLong_MASK ((digit)(PyLong_BASE - 1))
30
52
31 #if PyLong_SHIFT % 5 != 0
53 #if PyLong_SHIFT % 5 != 0
32 #error "longobject.c requires that SHIFT be divisible by 5"
54 #error "longobject.c requires that SHIFT be divisible by 5"
33 #endif
55 #endif
34
56
35 /* Long integer representation.
57 /* Long integer representation.
36 The absolute value of a number is equal to
58 The absolute value of a number is equal to
37 SUM(for i=0 through abs(ob_size)-1) ob_digit[i] * 2**(SHIFT*i)
59 SUM(for i=0 through abs(ob_size)-1) ob_digit[i] * 2**(SHIFT*i)
(...skipping 16 matching lines...) Expand all Loading...
54
76
55 PyAPI_FUNC(PyLongObject *) _PyLong_New(Py_ssize_t);
77 PyAPI_FUNC(PyLongObject *) _PyLong_New(Py_ssize_t);
56
78
57 /* Return a copy of src. */
79 /* Return a copy of src. */
58 PyAPI_FUNC(PyObject *) _PyLong_Copy(PyLongObject *src);
80 PyAPI_FUNC(PyObject *) _PyLong_Copy(PyLongObject *src);
59
81
60 #ifdef __cplusplus
82 #ifdef __cplusplus
61 }
83 }
62 #endif
84 #endif
63 #endif /* !Py_LONGINTREPR_H */
85 #endif /* !Py_LONGINTREPR_H */
OLD
NEW