1#ifndef Py_INTERNAL_LONG_H 2#define Py_INTERNAL_LONG_H 3#ifdef __cplusplus 4extern "C" { 5#endif 6 7#ifndef Py_BUILD_CORE 8# error "this header requires Py_BUILD_CORE define" 9#endif 10 11#include "pycore_global_objects.h" // _PY_NSMALLNEGINTS 12#include "pycore_runtime.h" // _PyRuntime 13 14/* 15 * Default int base conversion size limitation: Denial of Service prevention. 16 * 17 * Chosen such that this isn't wildly slow on modern hardware and so that 18 * everyone's existing deployed numpy test suite passes before 19 * https://github.com/numpy/numpy/issues/22098 is widely available. 20 * 21 * $ python -m timeit -s 's = "1"*4300' 'int(s)' 22 * 2000 loops, best of 5: 125 usec per loop 23 * $ python -m timeit -s 's = "1"*4300; v = int(s)' 'str(v)' 24 * 1000 loops, best of 5: 311 usec per loop 25 * (zen2 cloud VM) 26 * 27 * 4300 decimal digits fits a ~14284 bit number. 28 */ 29#define _PY_LONG_DEFAULT_MAX_STR_DIGITS 4300 30/* 31 * Threshold for max digits check. For performance reasons int() and 32 * int.__str__() don't checks values that are smaller than this 33 * threshold. Acts as a guaranteed minimum size limit for bignums that 34 * applications can expect from CPython. 35 * 36 * % python -m timeit -s 's = "1"*640; v = int(s)' 'str(int(s))' 37 * 20000 loops, best of 5: 12 usec per loop 38 * 39 * "640 digits should be enough for anyone." - gps 40 * fits a ~2126 bit decimal number. 41 */ 42#define _PY_LONG_MAX_STR_DIGITS_THRESHOLD 640 43 44#if ((_PY_LONG_DEFAULT_MAX_STR_DIGITS != 0) && \ 45 (_PY_LONG_DEFAULT_MAX_STR_DIGITS < _PY_LONG_MAX_STR_DIGITS_THRESHOLD)) 46# error "_PY_LONG_DEFAULT_MAX_STR_DIGITS smaller than threshold." 47#endif 48 49 50/* runtime lifecycle */ 51 52extern PyStatus _PyLong_InitTypes(PyInterpreterState *); 53extern void _PyLong_FiniTypes(PyInterpreterState *interp); 54 55 56/* other API */ 57 58#define _PyLong_SMALL_INTS _Py_SINGLETON(small_ints) 59 60// _PyLong_GetZero() and _PyLong_GetOne() must always be available 61// _PyLong_FromUnsignedChar must always be available 62#if _PY_NSMALLPOSINTS < 257 63# error "_PY_NSMALLPOSINTS must be greater than or equal to 257" 64#endif 65 66// Return a borrowed reference to the zero singleton. 67// The function cannot return NULL. 68static inline PyObject* _PyLong_GetZero(void) 69{ return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS]; } 70 71// Return a borrowed reference to the one singleton. 72// The function cannot return NULL. 73static inline PyObject* _PyLong_GetOne(void) 74{ return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+1]; } 75 76static inline PyObject* _PyLong_FromUnsignedChar(unsigned char i) 77{ 78 return Py_NewRef((PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+i]); 79} 80 81PyObject *_PyLong_Add(PyLongObject *left, PyLongObject *right); 82PyObject *_PyLong_Multiply(PyLongObject *left, PyLongObject *right); 83PyObject *_PyLong_Subtract(PyLongObject *left, PyLongObject *right); 84 85/* Used by Python/mystrtoul.c, _PyBytes_FromHex(), 86 _PyBytes_DecodeEscape(), etc. */ 87PyAPI_DATA(unsigned char) _PyLong_DigitValue[256]; 88 89/* Format the object based on the format_spec, as defined in PEP 3101 90 (Advanced String Formatting). */ 91PyAPI_FUNC(int) _PyLong_FormatAdvancedWriter( 92 _PyUnicodeWriter *writer, 93 PyObject *obj, 94 PyObject *format_spec, 95 Py_ssize_t start, 96 Py_ssize_t end); 97 98PyAPI_FUNC(int) _PyLong_FormatWriter( 99 _PyUnicodeWriter *writer, 100 PyObject *obj, 101 int base, 102 int alternate); 103 104PyAPI_FUNC(char*) _PyLong_FormatBytesWriter( 105 _PyBytesWriter *writer, 106 char *str, 107 PyObject *obj, 108 int base, 109 int alternate); 110 111#ifdef __cplusplus 112} 113#endif 114#endif /* !Py_INTERNAL_LONG_H */ 115