[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