| 
									
										
										
										
											2020-10-27 00:00:03 +01:00
										 |  |  | #ifndef Py_INTERNAL_LONG_H
 | 
					
						
							|  |  |  | #define Py_INTERNAL_LONG_H
 | 
					
						
							|  |  |  | #ifdef __cplusplus
 | 
					
						
							|  |  |  | extern "C" { | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef Py_BUILD_CORE
 | 
					
						
							|  |  |  | #  error "this header requires Py_BUILD_CORE define"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-04 10:27:23 +02:00
										 |  |  | #include "pycore_bytesobject.h"   // _PyBytesWriter
 | 
					
						
							|  |  |  | #include "pycore_global_objects.h"// _PY_NSMALLNEGINTS
 | 
					
						
							| 
									
										
										
										
											2021-12-09 12:59:26 -07:00
										 |  |  | #include "pycore_runtime.h"       // _PyRuntime
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-02 09:35:08 -07:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Default int base conversion size limitation: Denial of Service prevention. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Chosen such that this isn't wildly slow on modern hardware and so that | 
					
						
							|  |  |  |  * everyone's existing deployed numpy test suite passes before | 
					
						
							|  |  |  |  * https://github.com/numpy/numpy/issues/22098 is widely available.
 | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2022-09-04 17:21:18 +01:00
										 |  |  |  * $ python -m timeit -s 's = "1"*4300' 'int(s)' | 
					
						
							| 
									
										
										
										
											2022-09-02 09:35:08 -07:00
										 |  |  |  * 2000 loops, best of 5: 125 usec per loop | 
					
						
							| 
									
										
										
										
											2022-09-04 17:21:18 +01:00
										 |  |  |  * $ python -m timeit -s 's = "1"*4300; v = int(s)' 'str(v)' | 
					
						
							| 
									
										
										
										
											2022-09-02 09:35:08 -07:00
										 |  |  |  * 1000 loops, best of 5: 311 usec per loop | 
					
						
							|  |  |  |  * (zen2 cloud VM) | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 4300 decimal digits fits a ~14284 bit number. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #define _PY_LONG_DEFAULT_MAX_STR_DIGITS 4300
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Threshold for max digits check.  For performance reasons int() and | 
					
						
							|  |  |  |  * int.__str__() don't checks values that are smaller than this | 
					
						
							|  |  |  |  * threshold.  Acts as a guaranteed minimum size limit for bignums that | 
					
						
							|  |  |  |  * applications can expect from CPython. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * % python -m timeit -s 's = "1"*640; v = int(s)' 'str(int(s))' | 
					
						
							|  |  |  |  * 20000 loops, best of 5: 12 usec per loop | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * "640 digits should be enough for anyone." - gps | 
					
						
							|  |  |  |  * fits a ~2126 bit decimal number. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #define _PY_LONG_MAX_STR_DIGITS_THRESHOLD 640
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if ((_PY_LONG_DEFAULT_MAX_STR_DIGITS != 0) && \
 | 
					
						
							|  |  |  |    (_PY_LONG_DEFAULT_MAX_STR_DIGITS < _PY_LONG_MAX_STR_DIGITS_THRESHOLD)) | 
					
						
							|  |  |  | # error "_PY_LONG_DEFAULT_MAX_STR_DIGITS smaller than threshold."
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-09 12:59:26 -07:00
										 |  |  | /* runtime lifecycle */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | extern PyStatus _PyLong_InitTypes(PyInterpreterState *); | 
					
						
							| 
									
										
										
										
											2022-01-21 01:42:25 +01:00
										 |  |  | extern void _PyLong_FiniTypes(PyInterpreterState *interp); | 
					
						
							| 
									
										
										
										
											2021-12-09 12:59:26 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* other API */ | 
					
						
							| 
									
										
										
										
											2020-10-27 00:00:03 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-12-13 11:06:26 +01:00
										 |  |  | PyAPI_FUNC(void) _PyLong_ExactDealloc(PyObject *self); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-13 18:04:05 -07:00
										 |  |  | #define _PyLong_SMALL_INTS _Py_SINGLETON(small_ints)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // _PyLong_GetZero() and _PyLong_GetOne() must always be available
 | 
					
						
							| 
									
										
										
										
											2022-03-23 14:00:05 +05:30
										 |  |  | // _PyLong_FromUnsignedChar must always be available
 | 
					
						
							|  |  |  | #if _PY_NSMALLPOSINTS < 257
 | 
					
						
							|  |  |  | #  error "_PY_NSMALLPOSINTS must be greater than or equal to 257"
 | 
					
						
							| 
									
										
										
										
											2021-12-13 18:04:05 -07:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-04 09:10:55 +01:00
										 |  |  | #define _PY_IS_SMALL_INT(val) ((val) >= 0 && (val) < 256 && (val) < _PY_NSMALLPOSINTS)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-04 16:24:50 -07:00
										 |  |  | // Return a reference to the immortal zero singleton.
 | 
					
						
							| 
									
										
										
										
											2020-10-27 00:00:03 +01:00
										 |  |  | // The function cannot return NULL.
 | 
					
						
							|  |  |  | static inline PyObject* _PyLong_GetZero(void) | 
					
						
							| 
									
										
										
										
											2021-12-09 12:59:26 -07:00
										 |  |  | { return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS]; } | 
					
						
							| 
									
										
										
										
											2020-10-27 00:00:03 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-04 16:24:50 -07:00
										 |  |  | // Return a reference to the immortal one singleton.
 | 
					
						
							| 
									
										
										
										
											2020-10-27 00:00:03 +01:00
										 |  |  | // The function cannot return NULL.
 | 
					
						
							|  |  |  | static inline PyObject* _PyLong_GetOne(void) | 
					
						
							| 
									
										
										
										
											2021-12-09 12:59:26 -07:00
										 |  |  | { return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+1]; } | 
					
						
							| 
									
										
										
										
											2020-10-27 00:00:03 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-23 14:00:05 +05:30
										 |  |  | static inline PyObject* _PyLong_FromUnsignedChar(unsigned char i) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-08-04 16:24:50 -07:00
										 |  |  |     return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+i]; | 
					
						
							| 
									
										
										
										
											2022-03-23 14:00:05 +05:30
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-24 18:53:50 +02:00
										 |  |  | // _PyLong_Frexp returns a double x and an exponent e such that the
 | 
					
						
							| 
									
										
										
										
											2024-09-29 10:40:20 +03:00
										 |  |  | // true value is approximately equal to x * 2**e.  x is
 | 
					
						
							| 
									
										
										
										
											2023-08-24 18:53:50 +02:00
										 |  |  | // 0.0 if and only if the input is 0 (in which case, e and x are both
 | 
					
						
							| 
									
										
										
										
											2024-09-29 10:40:20 +03:00
										 |  |  | // zeroes); otherwise, 0.5 <= abs(x) < 1.0.
 | 
					
						
							|  |  |  | // Always successful.
 | 
					
						
							| 
									
										
										
										
											2023-08-24 18:53:50 +02:00
										 |  |  | //
 | 
					
						
							|  |  |  | // Export for 'math' shared extension
 | 
					
						
							| 
									
										
										
										
											2024-08-30 08:13:24 +03:00
										 |  |  | PyAPI_DATA(double) _PyLong_Frexp(PyLongObject *a, int64_t *e); | 
					
						
							| 
									
										
										
										
											2023-08-24 18:53:50 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | extern PyObject* _PyLong_FromBytes(const char *, Py_ssize_t, int); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // _PyLong_DivmodNear.  Given integers a and b, compute the nearest
 | 
					
						
							|  |  |  | // integer q to the exact quotient a / b, rounding to the nearest even integer
 | 
					
						
							|  |  |  | // in the case of a tie.  Return (q, r), where r = a - q*b.  The remainder r
 | 
					
						
							|  |  |  | // will satisfy abs(r) <= abs(b)/2, with equality possible only if q is
 | 
					
						
							|  |  |  | // even.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Export for '_datetime' shared extension.
 | 
					
						
							|  |  |  | PyAPI_DATA(PyObject*) _PyLong_DivmodNear(PyObject *, PyObject *); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // _PyLong_Format: Convert the long to a string object with given base,
 | 
					
						
							|  |  |  | // appending a base prefix of 0[box] if base is 2, 8 or 16.
 | 
					
						
							|  |  |  | // Export for '_tkinter' shared extension.
 | 
					
						
							|  |  |  | PyAPI_DATA(PyObject*) _PyLong_Format(PyObject *obj, int base); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Export for 'math' shared extension
 | 
					
						
							| 
									
										
										
										
											2024-09-29 10:40:20 +03:00
										 |  |  | PyAPI_DATA(PyObject*) _PyLong_Rshift(PyObject *, int64_t); | 
					
						
							| 
									
										
										
										
											2023-08-24 18:53:50 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Export for 'math' shared extension
 | 
					
						
							| 
									
										
										
										
											2024-09-29 10:40:20 +03:00
										 |  |  | PyAPI_DATA(PyObject*) _PyLong_Lshift(PyObject *, int64_t); | 
					
						
							| 
									
										
										
										
											2023-08-24 18:53:50 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-02-29 08:11:28 -08:00
										 |  |  | PyAPI_FUNC(PyObject*) _PyLong_Add(PyLongObject *left, PyLongObject *right); | 
					
						
							|  |  |  | PyAPI_FUNC(PyObject*) _PyLong_Multiply(PyLongObject *left, PyLongObject *right); | 
					
						
							|  |  |  | PyAPI_FUNC(PyObject*) _PyLong_Subtract(PyLongObject *left, PyLongObject *right); | 
					
						
							| 
									
										
										
										
											2021-08-27 09:21:01 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-25 05:48:04 +02:00
										 |  |  | // Export for 'binascii' shared extension.
 | 
					
						
							| 
									
										
										
										
											2021-10-19 02:04:52 +02:00
										 |  |  | PyAPI_DATA(unsigned char) _PyLong_DigitValue[256]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Format the object based on the format_spec, as defined in PEP 3101
 | 
					
						
							|  |  |  |    (Advanced String Formatting). */ | 
					
						
							| 
									
										
										
										
											2023-07-25 03:49:28 +02:00
										 |  |  | extern int _PyLong_FormatAdvancedWriter( | 
					
						
							| 
									
										
										
										
											2021-10-19 02:04:52 +02:00
										 |  |  |     _PyUnicodeWriter *writer, | 
					
						
							|  |  |  |     PyObject *obj, | 
					
						
							|  |  |  |     PyObject *format_spec, | 
					
						
							|  |  |  |     Py_ssize_t start, | 
					
						
							|  |  |  |     Py_ssize_t end); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-25 03:49:28 +02:00
										 |  |  | extern int _PyLong_FormatWriter( | 
					
						
							| 
									
										
										
										
											2021-10-19 02:04:52 +02:00
										 |  |  |     _PyUnicodeWriter *writer, | 
					
						
							|  |  |  |     PyObject *obj, | 
					
						
							|  |  |  |     int base, | 
					
						
							|  |  |  |     int alternate); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-25 03:49:28 +02:00
										 |  |  | extern char* _PyLong_FormatBytesWriter( | 
					
						
							| 
									
										
										
										
											2021-10-19 02:04:52 +02:00
										 |  |  |     _PyBytesWriter *writer, | 
					
						
							|  |  |  |     char *str, | 
					
						
							|  |  |  |     PyObject *obj, | 
					
						
							|  |  |  |     int base, | 
					
						
							|  |  |  |     int alternate); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-26 02:24:27 +02:00
										 |  |  | // Argument converters used by Argument Clinic
 | 
					
						
							| 
									
										
										
										
											2023-08-26 03:18:09 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Export for 'select' shared extension (Argument Clinic code)
 | 
					
						
							| 
									
										
										
										
											2023-08-26 02:24:27 +02:00
										 |  |  | PyAPI_FUNC(int) _PyLong_UnsignedShort_Converter(PyObject *, void *); | 
					
						
							| 
									
										
										
										
											2023-08-26 03:18:09 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Export for '_testclinic' shared extension (Argument Clinic code)
 | 
					
						
							| 
									
										
										
										
											2023-08-26 02:24:27 +02:00
										 |  |  | PyAPI_FUNC(int) _PyLong_UnsignedInt_Converter(PyObject *, void *); | 
					
						
							| 
									
										
										
										
											2023-08-26 03:18:09 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Export for '_blake2' shared extension (Argument Clinic code)
 | 
					
						
							| 
									
										
										
										
											2023-08-26 02:24:27 +02:00
										 |  |  | PyAPI_FUNC(int) _PyLong_UnsignedLong_Converter(PyObject *, void *); | 
					
						
							| 
									
										
										
										
											2023-08-26 03:18:09 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Export for '_blake2' shared extension (Argument Clinic code)
 | 
					
						
							| 
									
										
										
										
											2023-08-26 02:24:27 +02:00
										 |  |  | PyAPI_FUNC(int) _PyLong_UnsignedLongLong_Converter(PyObject *, void *); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-26 03:18:09 +02:00
										 |  |  | // Export for '_testclinic' shared extension (Argument Clinic code)
 | 
					
						
							|  |  |  | PyAPI_FUNC(int) _PyLong_Size_t_Converter(PyObject *, void *); | 
					
						
							| 
									
										
										
										
											2023-08-26 02:24:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-22 14:49:51 +00:00
										 |  |  | /* Long value tag bits:
 | 
					
						
							|  |  |  |  * 0-1: Sign bits value = (1-sign), ie. negative=2, positive=0, zero=1. | 
					
						
							| 
									
										
										
										
											2025-01-29 16:22:18 +01:00
										 |  |  |  * 2: Set to 1 for the small ints | 
					
						
							| 
									
										
										
										
											2023-03-22 14:49:51 +00:00
										 |  |  |  * 3+ Unsigned digit count | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #define SIGN_MASK 3
 | 
					
						
							|  |  |  | #define SIGN_ZERO 1
 | 
					
						
							|  |  |  | #define SIGN_NEGATIVE 2
 | 
					
						
							|  |  |  | #define NON_SIZE_BITS 3
 | 
					
						
							| 
									
										
										
										
											2025-01-29 16:22:18 +01:00
										 |  |  | #define IMMORTALITY_BIT_MASK (1 << 2)
 | 
					
						
							| 
									
										
										
										
											2023-03-22 14:49:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-21 14:45:48 +01:00
										 |  |  | /* The functions _PyLong_IsCompact and _PyLong_CompactValue are defined
 | 
					
						
							|  |  |  |  * in Include/cpython/longobject.h, since they need to be inline. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * "Compact" values have at least one bit to spare, | 
					
						
							|  |  |  |  * so that addition and subtraction can be performed on the values | 
					
						
							|  |  |  |  * without risk of overflow. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The inline functions need tag bits. | 
					
						
							|  |  |  |  * For readability, rather than do `#define SIGN_MASK _PyLong_SIGN_MASK` | 
					
						
							|  |  |  |  * we define them to the numbers in both places and then assert that | 
					
						
							|  |  |  |  * they're the same. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2024-09-06 15:52:07 +02:00
										 |  |  | #if SIGN_MASK != _PyLong_SIGN_MASK
 | 
					
						
							|  |  |  | #  error "SIGN_MASK does not match _PyLong_SIGN_MASK"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #if NON_SIZE_BITS != _PyLong_NON_SIZE_BITS
 | 
					
						
							|  |  |  | #  error "NON_SIZE_BITS does not match _PyLong_NON_SIZE_BITS"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2023-05-21 14:45:48 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-22 14:49:51 +00:00
										 |  |  | /* All *compact" values are guaranteed to fit into
 | 
					
						
							|  |  |  |  * a Py_ssize_t with at least one bit to spare. | 
					
						
							|  |  |  |  * In other words, for 64 bit machines, compact | 
					
						
							|  |  |  |  * will be signed 63 (or fewer) bit values | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Return 1 if the argument is compact int */ | 
					
						
							|  |  |  | static inline int | 
					
						
							|  |  |  | _PyLong_IsNonNegativeCompact(const PyLongObject* op) { | 
					
						
							|  |  |  |     assert(PyLong_Check(op)); | 
					
						
							| 
									
										
										
										
											2025-01-29 16:22:18 +01:00
										 |  |  |     return ((op->long_value.lv_tag & ~IMMORTALITY_BIT_MASK) <= (1 << NON_SIZE_BITS)); | 
					
						
							| 
									
										
										
										
											2023-03-22 14:49:51 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-22 12:30:18 +01:00
										 |  |  | static inline int | 
					
						
							| 
									
										
										
										
											2023-03-22 14:49:51 +00:00
										 |  |  | _PyLong_BothAreCompact(const PyLongObject* a, const PyLongObject* b) { | 
					
						
							|  |  |  |     assert(PyLong_Check(a)); | 
					
						
							|  |  |  |     assert(PyLong_Check(b)); | 
					
						
							|  |  |  |     return (a->long_value.lv_tag | b->long_value.lv_tag) < (2 << NON_SIZE_BITS); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline bool | 
					
						
							|  |  |  | _PyLong_IsZero(const PyLongObject *op) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return (op->long_value.lv_tag & SIGN_MASK) == SIGN_ZERO; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline bool | 
					
						
							|  |  |  | _PyLong_IsNegative(const PyLongObject *op) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return (op->long_value.lv_tag & SIGN_MASK) == SIGN_NEGATIVE; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline bool | 
					
						
							|  |  |  | _PyLong_IsPositive(const PyLongObject *op) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return (op->long_value.lv_tag & SIGN_MASK) == 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline Py_ssize_t | 
					
						
							|  |  |  | _PyLong_DigitCount(const PyLongObject *op) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     assert(PyLong_Check(op)); | 
					
						
							| 
									
										
										
										
											2024-09-17 17:35:40 +02:00
										 |  |  |     return (Py_ssize_t)(op->long_value.lv_tag >> NON_SIZE_BITS); | 
					
						
							| 
									
										
										
										
											2022-12-22 12:30:18 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-22 14:49:51 +00:00
										 |  |  | /* Equivalent to _PyLong_DigitCount(op) * _PyLong_NonCompactSign(op) */ | 
					
						
							|  |  |  | static inline Py_ssize_t | 
					
						
							|  |  |  | _PyLong_SignedDigitCount(const PyLongObject *op) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     assert(PyLong_Check(op)); | 
					
						
							|  |  |  |     Py_ssize_t sign = 1 - (op->long_value.lv_tag & SIGN_MASK); | 
					
						
							|  |  |  |     return sign * (Py_ssize_t)(op->long_value.lv_tag >> NON_SIZE_BITS); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline int | 
					
						
							|  |  |  | _PyLong_CompactSign(const PyLongObject *op) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     assert(PyLong_Check(op)); | 
					
						
							| 
									
										
										
										
											2024-06-26 20:11:21 +02:00
										 |  |  |     assert(_PyLong_IsCompact((PyLongObject *)op)); | 
					
						
							| 
									
										
										
										
											2023-03-22 14:49:51 +00:00
										 |  |  |     return 1 - (op->long_value.lv_tag & SIGN_MASK); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline int | 
					
						
							|  |  |  | _PyLong_NonCompactSign(const PyLongObject *op) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     assert(PyLong_Check(op)); | 
					
						
							| 
									
										
										
										
											2024-06-26 20:11:21 +02:00
										 |  |  |     assert(!_PyLong_IsCompact((PyLongObject *)op)); | 
					
						
							| 
									
										
										
										
											2023-03-22 14:49:51 +00:00
										 |  |  |     return 1 - (op->long_value.lv_tag & SIGN_MASK); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Do a and b have the same sign? */ | 
					
						
							|  |  |  | static inline int | 
					
						
							|  |  |  | _PyLong_SameSign(const PyLongObject *a, const PyLongObject *b) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return (a->long_value.lv_tag & SIGN_MASK) == (b->long_value.lv_tag & SIGN_MASK); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-17 17:35:40 +02:00
										 |  |  | #define TAG_FROM_SIGN_AND_SIZE(sign, size) \
 | 
					
						
							|  |  |  |     ((uintptr_t)(1 - (sign)) | ((uintptr_t)(size) << NON_SIZE_BITS)) | 
					
						
							| 
									
										
										
										
											2023-03-22 14:49:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static inline void | 
					
						
							|  |  |  | _PyLong_SetSignAndDigitCount(PyLongObject *op, int sign, Py_ssize_t size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     assert(size >= 0); | 
					
						
							|  |  |  |     assert(-1 <= sign && sign <= 1); | 
					
						
							|  |  |  |     assert(sign != 0 || size == 0); | 
					
						
							| 
									
										
										
										
											2024-09-17 17:35:40 +02:00
										 |  |  |     op->long_value.lv_tag = TAG_FROM_SIGN_AND_SIZE(sign, size); | 
					
						
							| 
									
										
										
										
											2023-03-22 14:49:51 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline void | 
					
						
							|  |  |  | _PyLong_SetDigitCount(PyLongObject *op, Py_ssize_t size) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     assert(size >= 0); | 
					
						
							|  |  |  |     op->long_value.lv_tag = (((size_t)size) << NON_SIZE_BITS) | (op->long_value.lv_tag & SIGN_MASK); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-17 17:35:40 +02:00
										 |  |  | #define NON_SIZE_MASK ~(uintptr_t)((1 << NON_SIZE_BITS) - 1)
 | 
					
						
							| 
									
										
										
										
											2023-03-22 14:49:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static inline void | 
					
						
							|  |  |  | _PyLong_FlipSign(PyLongObject *op) { | 
					
						
							|  |  |  |     unsigned int flipped_sign = 2 - (op->long_value.lv_tag & SIGN_MASK); | 
					
						
							|  |  |  |     op->long_value.lv_tag &= NON_SIZE_MASK; | 
					
						
							|  |  |  |     op->long_value.lv_tag |= flipped_sign; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define _PyLong_DIGIT_INIT(val) \
 | 
					
						
							|  |  |  |     { \ | 
					
						
							| 
									
										
										
										
											2023-10-30 12:06:09 -04:00
										 |  |  |         .ob_base = _PyObject_HEAD_INIT(&PyLong_Type), \ | 
					
						
							| 
									
										
										
										
											2023-03-22 14:49:51 +00:00
										 |  |  |         .long_value  = { \ | 
					
						
							|  |  |  |             .lv_tag = TAG_FROM_SIGN_AND_SIZE( \ | 
					
						
							|  |  |  |                 (val) == 0 ? 0 : ((val) < 0 ? -1 : 1), \ | 
					
						
							| 
									
										
										
										
											2025-01-29 16:22:18 +01:00
										 |  |  |                 (val) == 0 ? 0 : 1) | IMMORTALITY_BIT_MASK, \ | 
					
						
							| 
									
										
										
										
											2023-03-22 14:49:51 +00:00
										 |  |  |             { ((val) >= 0 ? (val) : -(val)) }, \ | 
					
						
							|  |  |  |         } \ | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define _PyLong_FALSE_TAG TAG_FROM_SIGN_AND_SIZE(0, 0)
 | 
					
						
							|  |  |  | #define _PyLong_TRUE_TAG TAG_FROM_SIGN_AND_SIZE(1, 1)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-27 00:00:03 +01:00
										 |  |  | #ifdef __cplusplus
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | #endif /* !Py_INTERNAL_LONG_H */
 |