File indexing completed on 2025-11-19 09:50:48
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_bytesobject.h" // _PyBytesWriter
0012 #include "pycore_global_objects.h"// _PY_NSMALLNEGINTS
0013 #include "pycore_runtime.h" // _PyRuntime
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 #define _PY_LONG_DEFAULT_MAX_STR_DIGITS 4300
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043 #define _PY_LONG_MAX_STR_DIGITS_THRESHOLD 640
0044
0045 #if ((_PY_LONG_DEFAULT_MAX_STR_DIGITS != 0) && \
0046 (_PY_LONG_DEFAULT_MAX_STR_DIGITS < _PY_LONG_MAX_STR_DIGITS_THRESHOLD))
0047 # error "_PY_LONG_DEFAULT_MAX_STR_DIGITS smaller than threshold."
0048 #endif
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 (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+i];
0079 }
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089 PyAPI_DATA(double) _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e);
0090
0091 extern PyObject* _PyLong_FromBytes(const char *, Py_ssize_t, int);
0092
0093
0094
0095
0096
0097
0098
0099
0100 PyAPI_DATA(PyObject*) _PyLong_DivmodNear(PyObject *, PyObject *);
0101
0102
0103
0104
0105 PyAPI_DATA(PyObject*) _PyLong_Format(PyObject *obj, int base);
0106
0107
0108 PyAPI_DATA(PyObject*) _PyLong_Rshift(PyObject *, size_t);
0109
0110
0111 PyAPI_DATA(PyObject*) _PyLong_Lshift(PyObject *, size_t);
0112
0113 PyAPI_FUNC(PyObject*) _PyLong_Add(PyLongObject *left, PyLongObject *right);
0114 PyAPI_FUNC(PyObject*) _PyLong_Multiply(PyLongObject *left, PyLongObject *right);
0115 PyAPI_FUNC(PyObject*) _PyLong_Subtract(PyLongObject *left, PyLongObject *right);
0116
0117
0118 PyAPI_DATA(unsigned char) _PyLong_DigitValue[256];
0119
0120
0121
0122 extern int _PyLong_FormatAdvancedWriter(
0123 _PyUnicodeWriter *writer,
0124 PyObject *obj,
0125 PyObject *format_spec,
0126 Py_ssize_t start,
0127 Py_ssize_t end);
0128
0129 extern int _PyLong_FormatWriter(
0130 _PyUnicodeWriter *writer,
0131 PyObject *obj,
0132 int base,
0133 int alternate);
0134
0135 extern char* _PyLong_FormatBytesWriter(
0136 _PyBytesWriter *writer,
0137 char *str,
0138 PyObject *obj,
0139 int base,
0140 int alternate);
0141
0142
0143
0144
0145 PyAPI_FUNC(int) _PyLong_UnsignedShort_Converter(PyObject *, void *);
0146
0147
0148 PyAPI_FUNC(int) _PyLong_UnsignedInt_Converter(PyObject *, void *);
0149
0150
0151 PyAPI_FUNC(int) _PyLong_UnsignedLong_Converter(PyObject *, void *);
0152
0153
0154 PyAPI_FUNC(int) _PyLong_UnsignedLongLong_Converter(PyObject *, void *);
0155
0156
0157 PyAPI_FUNC(int) _PyLong_Size_t_Converter(PyObject *, void *);
0158
0159
0160
0161
0162
0163
0164 #define SIGN_MASK 3
0165 #define SIGN_ZERO 1
0166 #define SIGN_NEGATIVE 2
0167 #define NON_SIZE_BITS 3
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181 #if SIGN_MASK != _PyLong_SIGN_MASK
0182 # error "SIGN_MASK does not match _PyLong_SIGN_MASK"
0183 #endif
0184 #if NON_SIZE_BITS != _PyLong_NON_SIZE_BITS
0185 # error "NON_SIZE_BITS does not match _PyLong_NON_SIZE_BITS"
0186 #endif
0187
0188
0189
0190
0191
0192
0193
0194
0195 static inline int
0196 _PyLong_IsNonNegativeCompact(const PyLongObject* op) {
0197 assert(PyLong_Check(op));
0198 return op->long_value.lv_tag <= (1 << NON_SIZE_BITS);
0199 }
0200
0201
0202 static inline int
0203 _PyLong_BothAreCompact(const PyLongObject* a, const PyLongObject* b) {
0204 assert(PyLong_Check(a));
0205 assert(PyLong_Check(b));
0206 return (a->long_value.lv_tag | b->long_value.lv_tag) < (2 << NON_SIZE_BITS);
0207 }
0208
0209 static inline bool
0210 _PyLong_IsZero(const PyLongObject *op)
0211 {
0212 return (op->long_value.lv_tag & SIGN_MASK) == SIGN_ZERO;
0213 }
0214
0215 static inline bool
0216 _PyLong_IsNegative(const PyLongObject *op)
0217 {
0218 return (op->long_value.lv_tag & SIGN_MASK) == SIGN_NEGATIVE;
0219 }
0220
0221 static inline bool
0222 _PyLong_IsPositive(const PyLongObject *op)
0223 {
0224 return (op->long_value.lv_tag & SIGN_MASK) == 0;
0225 }
0226
0227 static inline Py_ssize_t
0228 _PyLong_DigitCount(const PyLongObject *op)
0229 {
0230 assert(PyLong_Check(op));
0231 return op->long_value.lv_tag >> NON_SIZE_BITS;
0232 }
0233
0234
0235 static inline Py_ssize_t
0236 _PyLong_SignedDigitCount(const PyLongObject *op)
0237 {
0238 assert(PyLong_Check(op));
0239 Py_ssize_t sign = 1 - (op->long_value.lv_tag & SIGN_MASK);
0240 return sign * (Py_ssize_t)(op->long_value.lv_tag >> NON_SIZE_BITS);
0241 }
0242
0243 static inline int
0244 _PyLong_CompactSign(const PyLongObject *op)
0245 {
0246 assert(PyLong_Check(op));
0247 assert(_PyLong_IsCompact(op));
0248 return 1 - (op->long_value.lv_tag & SIGN_MASK);
0249 }
0250
0251 static inline int
0252 _PyLong_NonCompactSign(const PyLongObject *op)
0253 {
0254 assert(PyLong_Check(op));
0255 assert(!_PyLong_IsCompact(op));
0256 return 1 - (op->long_value.lv_tag & SIGN_MASK);
0257 }
0258
0259
0260 static inline int
0261 _PyLong_SameSign(const PyLongObject *a, const PyLongObject *b)
0262 {
0263 return (a->long_value.lv_tag & SIGN_MASK) == (b->long_value.lv_tag & SIGN_MASK);
0264 }
0265
0266 #define TAG_FROM_SIGN_AND_SIZE(sign, size) ((1 - (sign)) | ((size) << NON_SIZE_BITS))
0267
0268 static inline void
0269 _PyLong_SetSignAndDigitCount(PyLongObject *op, int sign, Py_ssize_t size)
0270 {
0271 assert(size >= 0);
0272 assert(-1 <= sign && sign <= 1);
0273 assert(sign != 0 || size == 0);
0274 op->long_value.lv_tag = TAG_FROM_SIGN_AND_SIZE(sign, (size_t)size);
0275 }
0276
0277 static inline void
0278 _PyLong_SetDigitCount(PyLongObject *op, Py_ssize_t size)
0279 {
0280 assert(size >= 0);
0281 op->long_value.lv_tag = (((size_t)size) << NON_SIZE_BITS) | (op->long_value.lv_tag & SIGN_MASK);
0282 }
0283
0284 #define NON_SIZE_MASK ~((1 << NON_SIZE_BITS) - 1)
0285
0286 static inline void
0287 _PyLong_FlipSign(PyLongObject *op) {
0288 unsigned int flipped_sign = 2 - (op->long_value.lv_tag & SIGN_MASK);
0289 op->long_value.lv_tag &= NON_SIZE_MASK;
0290 op->long_value.lv_tag |= flipped_sign;
0291 }
0292
0293 #define _PyLong_DIGIT_INIT(val) \
0294 { \
0295 .ob_base = _PyObject_HEAD_INIT(&PyLong_Type), \
0296 .long_value = { \
0297 .lv_tag = TAG_FROM_SIGN_AND_SIZE( \
0298 (val) == 0 ? 0 : ((val) < 0 ? -1 : 1), \
0299 (val) == 0 ? 0 : 1), \
0300 { ((val) >= 0 ? (val) : -(val)) }, \
0301 } \
0302 }
0303
0304 #define _PyLong_FALSE_TAG TAG_FROM_SIGN_AND_SIZE(0, 0)
0305 #define _PyLong_TRUE_TAG TAG_FROM_SIGN_AND_SIZE(1, 1)
0306
0307 #ifdef __cplusplus
0308 }
0309 #endif
0310 #endif