File indexing completed on 2025-01-18 10:06:46
0001 #ifndef Py_INTERNAL_LONG_H
0002 #define Py_INTERNAL_LONG_H
0003 #ifdef __cplusplus
0004 extern "C" {
0005 #endif
0006
0007 #ifndef Py_BUILD_CORE
0008 # error "this header requires Py_BUILD_CORE define"
0009 #endif
0010
0011 #include "pycore_global_objects.h" // _PY_NSMALLNEGINTS
0012 #include "pycore_runtime.h" // _PyRuntime
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 #define _PY_LONG_DEFAULT_MAX_STR_DIGITS 4300
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 #define _PY_LONG_MAX_STR_DIGITS_THRESHOLD 640
0043
0044 #if ((_PY_LONG_DEFAULT_MAX_STR_DIGITS != 0) && \
0045 (_PY_LONG_DEFAULT_MAX_STR_DIGITS < _PY_LONG_MAX_STR_DIGITS_THRESHOLD))
0046 # error "_PY_LONG_DEFAULT_MAX_STR_DIGITS smaller than threshold."
0047 #endif
0048
0049
0050
0051
0052 extern PyStatus _PyLong_InitTypes(PyInterpreterState *);
0053 extern void _PyLong_FiniTypes(PyInterpreterState *interp);
0054
0055
0056
0057
0058 #define _PyLong_SMALL_INTS _Py_SINGLETON(small_ints)
0059
0060
0061
0062 #if _PY_NSMALLPOSINTS < 257
0063 # error "_PY_NSMALLPOSINTS must be greater than or equal to 257"
0064 #endif
0065
0066
0067
0068 static inline PyObject* _PyLong_GetZero(void)
0069 { return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS]; }
0070
0071
0072
0073 static inline PyObject* _PyLong_GetOne(void)
0074 { return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+1]; }
0075
0076 static inline PyObject* _PyLong_FromUnsignedChar(unsigned char i)
0077 {
0078 return Py_NewRef((PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+i]);
0079 }
0080
0081 PyObject *_PyLong_Add(PyLongObject *left, PyLongObject *right);
0082 PyObject *_PyLong_Multiply(PyLongObject *left, PyLongObject *right);
0083 PyObject *_PyLong_Subtract(PyLongObject *left, PyLongObject *right);
0084
0085
0086
0087 PyAPI_DATA(unsigned char) _PyLong_DigitValue[256];
0088
0089
0090
0091 PyAPI_FUNC(int) _PyLong_FormatAdvancedWriter(
0092 _PyUnicodeWriter *writer,
0093 PyObject *obj,
0094 PyObject *format_spec,
0095 Py_ssize_t start,
0096 Py_ssize_t end);
0097
0098 PyAPI_FUNC(int) _PyLong_FormatWriter(
0099 _PyUnicodeWriter *writer,
0100 PyObject *obj,
0101 int base,
0102 int alternate);
0103
0104 PyAPI_FUNC(char*) _PyLong_FormatBytesWriter(
0105 _PyBytesWriter *writer,
0106 char *str,
0107 PyObject *obj,
0108 int base,
0109 int alternate);
0110
0111
0112
0113
0114
0115
0116 #define SIGN_MASK 3
0117 #define SIGN_ZERO 1
0118 #define SIGN_NEGATIVE 2
0119 #define NON_SIZE_BITS 3
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133 static_assert(SIGN_MASK == _PyLong_SIGN_MASK, "SIGN_MASK does not match _PyLong_SIGN_MASK");
0134 static_assert(NON_SIZE_BITS == _PyLong_NON_SIZE_BITS, "NON_SIZE_BITS does not match _PyLong_NON_SIZE_BITS");
0135
0136
0137
0138
0139
0140
0141
0142
0143 static inline int
0144 _PyLong_IsNonNegativeCompact(const PyLongObject* op) {
0145 assert(PyLong_Check(op));
0146 return op->long_value.lv_tag <= (1 << NON_SIZE_BITS);
0147 }
0148
0149
0150 static inline int
0151 _PyLong_BothAreCompact(const PyLongObject* a, const PyLongObject* b) {
0152 assert(PyLong_Check(a));
0153 assert(PyLong_Check(b));
0154 return (a->long_value.lv_tag | b->long_value.lv_tag) < (2 << NON_SIZE_BITS);
0155 }
0156
0157 static inline bool
0158 _PyLong_IsZero(const PyLongObject *op)
0159 {
0160 return (op->long_value.lv_tag & SIGN_MASK) == SIGN_ZERO;
0161 }
0162
0163 static inline bool
0164 _PyLong_IsNegative(const PyLongObject *op)
0165 {
0166 return (op->long_value.lv_tag & SIGN_MASK) == SIGN_NEGATIVE;
0167 }
0168
0169 static inline bool
0170 _PyLong_IsPositive(const PyLongObject *op)
0171 {
0172 return (op->long_value.lv_tag & SIGN_MASK) == 0;
0173 }
0174
0175 static inline Py_ssize_t
0176 _PyLong_DigitCount(const PyLongObject *op)
0177 {
0178 assert(PyLong_Check(op));
0179 return op->long_value.lv_tag >> NON_SIZE_BITS;
0180 }
0181
0182
0183 static inline Py_ssize_t
0184 _PyLong_SignedDigitCount(const PyLongObject *op)
0185 {
0186 assert(PyLong_Check(op));
0187 Py_ssize_t sign = 1 - (op->long_value.lv_tag & SIGN_MASK);
0188 return sign * (Py_ssize_t)(op->long_value.lv_tag >> NON_SIZE_BITS);
0189 }
0190
0191 static inline int
0192 _PyLong_CompactSign(const PyLongObject *op)
0193 {
0194 assert(PyLong_Check(op));
0195 assert(_PyLong_IsCompact(op));
0196 return 1 - (op->long_value.lv_tag & SIGN_MASK);
0197 }
0198
0199 static inline int
0200 _PyLong_NonCompactSign(const PyLongObject *op)
0201 {
0202 assert(PyLong_Check(op));
0203 assert(!_PyLong_IsCompact(op));
0204 return 1 - (op->long_value.lv_tag & SIGN_MASK);
0205 }
0206
0207
0208 static inline int
0209 _PyLong_SameSign(const PyLongObject *a, const PyLongObject *b)
0210 {
0211 return (a->long_value.lv_tag & SIGN_MASK) == (b->long_value.lv_tag & SIGN_MASK);
0212 }
0213
0214 #define TAG_FROM_SIGN_AND_SIZE(sign, size) ((1 - (sign)) | ((size) << NON_SIZE_BITS))
0215
0216 static inline void
0217 _PyLong_SetSignAndDigitCount(PyLongObject *op, int sign, Py_ssize_t size)
0218 {
0219 assert(size >= 0);
0220 assert(-1 <= sign && sign <= 1);
0221 assert(sign != 0 || size == 0);
0222 op->long_value.lv_tag = TAG_FROM_SIGN_AND_SIZE(sign, (size_t)size);
0223 }
0224
0225 static inline void
0226 _PyLong_SetDigitCount(PyLongObject *op, Py_ssize_t size)
0227 {
0228 assert(size >= 0);
0229 op->long_value.lv_tag = (((size_t)size) << NON_SIZE_BITS) | (op->long_value.lv_tag & SIGN_MASK);
0230 }
0231
0232 #define NON_SIZE_MASK ~((1 << NON_SIZE_BITS) - 1)
0233
0234 static inline void
0235 _PyLong_FlipSign(PyLongObject *op) {
0236 unsigned int flipped_sign = 2 - (op->long_value.lv_tag & SIGN_MASK);
0237 op->long_value.lv_tag &= NON_SIZE_MASK;
0238 op->long_value.lv_tag |= flipped_sign;
0239 }
0240
0241 #define _PyLong_DIGIT_INIT(val) \
0242 { \
0243 .ob_base = _PyObject_HEAD_INIT(&PyLong_Type) \
0244 .long_value = { \
0245 .lv_tag = TAG_FROM_SIGN_AND_SIZE( \
0246 (val) == 0 ? 0 : ((val) < 0 ? -1 : 1), \
0247 (val) == 0 ? 0 : 1), \
0248 { ((val) >= 0 ? (val) : -(val)) }, \
0249 } \
0250 }
0251
0252 #define _PyLong_FALSE_TAG TAG_FROM_SIGN_AND_SIZE(0, 0)
0253 #define _PyLong_TRUE_TAG TAG_FROM_SIGN_AND_SIZE(1, 1)
0254
0255 #ifdef __cplusplus
0256 }
0257 #endif
0258 #endif