17db96d56Sopenharmony_ci#ifndef Py_INTERNAL_LONG_H
27db96d56Sopenharmony_ci#define Py_INTERNAL_LONG_H
37db96d56Sopenharmony_ci#ifdef __cplusplus
47db96d56Sopenharmony_ciextern "C" {
57db96d56Sopenharmony_ci#endif
67db96d56Sopenharmony_ci
77db96d56Sopenharmony_ci#ifndef Py_BUILD_CORE
87db96d56Sopenharmony_ci#  error "this header requires Py_BUILD_CORE define"
97db96d56Sopenharmony_ci#endif
107db96d56Sopenharmony_ci
117db96d56Sopenharmony_ci#include "pycore_global_objects.h"  // _PY_NSMALLNEGINTS
127db96d56Sopenharmony_ci#include "pycore_runtime.h"       // _PyRuntime
137db96d56Sopenharmony_ci
147db96d56Sopenharmony_ci/*
157db96d56Sopenharmony_ci * Default int base conversion size limitation: Denial of Service prevention.
167db96d56Sopenharmony_ci *
177db96d56Sopenharmony_ci * Chosen such that this isn't wildly slow on modern hardware and so that
187db96d56Sopenharmony_ci * everyone's existing deployed numpy test suite passes before
197db96d56Sopenharmony_ci * https://github.com/numpy/numpy/issues/22098 is widely available.
207db96d56Sopenharmony_ci *
217db96d56Sopenharmony_ci * $ python -m timeit -s 's = "1"*4300' 'int(s)'
227db96d56Sopenharmony_ci * 2000 loops, best of 5: 125 usec per loop
237db96d56Sopenharmony_ci * $ python -m timeit -s 's = "1"*4300; v = int(s)' 'str(v)'
247db96d56Sopenharmony_ci * 1000 loops, best of 5: 311 usec per loop
257db96d56Sopenharmony_ci * (zen2 cloud VM)
267db96d56Sopenharmony_ci *
277db96d56Sopenharmony_ci * 4300 decimal digits fits a ~14284 bit number.
287db96d56Sopenharmony_ci */
297db96d56Sopenharmony_ci#define _PY_LONG_DEFAULT_MAX_STR_DIGITS 4300
307db96d56Sopenharmony_ci/*
317db96d56Sopenharmony_ci * Threshold for max digits check.  For performance reasons int() and
327db96d56Sopenharmony_ci * int.__str__() don't checks values that are smaller than this
337db96d56Sopenharmony_ci * threshold.  Acts as a guaranteed minimum size limit for bignums that
347db96d56Sopenharmony_ci * applications can expect from CPython.
357db96d56Sopenharmony_ci *
367db96d56Sopenharmony_ci * % python -m timeit -s 's = "1"*640; v = int(s)' 'str(int(s))'
377db96d56Sopenharmony_ci * 20000 loops, best of 5: 12 usec per loop
387db96d56Sopenharmony_ci *
397db96d56Sopenharmony_ci * "640 digits should be enough for anyone." - gps
407db96d56Sopenharmony_ci * fits a ~2126 bit decimal number.
417db96d56Sopenharmony_ci */
427db96d56Sopenharmony_ci#define _PY_LONG_MAX_STR_DIGITS_THRESHOLD 640
437db96d56Sopenharmony_ci
447db96d56Sopenharmony_ci#if ((_PY_LONG_DEFAULT_MAX_STR_DIGITS != 0) && \
457db96d56Sopenharmony_ci   (_PY_LONG_DEFAULT_MAX_STR_DIGITS < _PY_LONG_MAX_STR_DIGITS_THRESHOLD))
467db96d56Sopenharmony_ci# error "_PY_LONG_DEFAULT_MAX_STR_DIGITS smaller than threshold."
477db96d56Sopenharmony_ci#endif
487db96d56Sopenharmony_ci
497db96d56Sopenharmony_ci
507db96d56Sopenharmony_ci/* runtime lifecycle */
517db96d56Sopenharmony_ci
527db96d56Sopenharmony_ciextern PyStatus _PyLong_InitTypes(PyInterpreterState *);
537db96d56Sopenharmony_ciextern void _PyLong_FiniTypes(PyInterpreterState *interp);
547db96d56Sopenharmony_ci
557db96d56Sopenharmony_ci
567db96d56Sopenharmony_ci/* other API */
577db96d56Sopenharmony_ci
587db96d56Sopenharmony_ci#define _PyLong_SMALL_INTS _Py_SINGLETON(small_ints)
597db96d56Sopenharmony_ci
607db96d56Sopenharmony_ci// _PyLong_GetZero() and _PyLong_GetOne() must always be available
617db96d56Sopenharmony_ci// _PyLong_FromUnsignedChar must always be available
627db96d56Sopenharmony_ci#if _PY_NSMALLPOSINTS < 257
637db96d56Sopenharmony_ci#  error "_PY_NSMALLPOSINTS must be greater than or equal to 257"
647db96d56Sopenharmony_ci#endif
657db96d56Sopenharmony_ci
667db96d56Sopenharmony_ci// Return a borrowed reference to the zero singleton.
677db96d56Sopenharmony_ci// The function cannot return NULL.
687db96d56Sopenharmony_cistatic inline PyObject* _PyLong_GetZero(void)
697db96d56Sopenharmony_ci{ return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS]; }
707db96d56Sopenharmony_ci
717db96d56Sopenharmony_ci// Return a borrowed reference to the one singleton.
727db96d56Sopenharmony_ci// The function cannot return NULL.
737db96d56Sopenharmony_cistatic inline PyObject* _PyLong_GetOne(void)
747db96d56Sopenharmony_ci{ return (PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+1]; }
757db96d56Sopenharmony_ci
767db96d56Sopenharmony_cistatic inline PyObject* _PyLong_FromUnsignedChar(unsigned char i)
777db96d56Sopenharmony_ci{
787db96d56Sopenharmony_ci    return Py_NewRef((PyObject *)&_PyLong_SMALL_INTS[_PY_NSMALLNEGINTS+i]);
797db96d56Sopenharmony_ci}
807db96d56Sopenharmony_ci
817db96d56Sopenharmony_ciPyObject *_PyLong_Add(PyLongObject *left, PyLongObject *right);
827db96d56Sopenharmony_ciPyObject *_PyLong_Multiply(PyLongObject *left, PyLongObject *right);
837db96d56Sopenharmony_ciPyObject *_PyLong_Subtract(PyLongObject *left, PyLongObject *right);
847db96d56Sopenharmony_ci
857db96d56Sopenharmony_ci/* Used by Python/mystrtoul.c, _PyBytes_FromHex(),
867db96d56Sopenharmony_ci   _PyBytes_DecodeEscape(), etc. */
877db96d56Sopenharmony_ciPyAPI_DATA(unsigned char) _PyLong_DigitValue[256];
887db96d56Sopenharmony_ci
897db96d56Sopenharmony_ci/* Format the object based on the format_spec, as defined in PEP 3101
907db96d56Sopenharmony_ci   (Advanced String Formatting). */
917db96d56Sopenharmony_ciPyAPI_FUNC(int) _PyLong_FormatAdvancedWriter(
927db96d56Sopenharmony_ci    _PyUnicodeWriter *writer,
937db96d56Sopenharmony_ci    PyObject *obj,
947db96d56Sopenharmony_ci    PyObject *format_spec,
957db96d56Sopenharmony_ci    Py_ssize_t start,
967db96d56Sopenharmony_ci    Py_ssize_t end);
977db96d56Sopenharmony_ci
987db96d56Sopenharmony_ciPyAPI_FUNC(int) _PyLong_FormatWriter(
997db96d56Sopenharmony_ci    _PyUnicodeWriter *writer,
1007db96d56Sopenharmony_ci    PyObject *obj,
1017db96d56Sopenharmony_ci    int base,
1027db96d56Sopenharmony_ci    int alternate);
1037db96d56Sopenharmony_ci
1047db96d56Sopenharmony_ciPyAPI_FUNC(char*) _PyLong_FormatBytesWriter(
1057db96d56Sopenharmony_ci    _PyBytesWriter *writer,
1067db96d56Sopenharmony_ci    char *str,
1077db96d56Sopenharmony_ci    PyObject *obj,
1087db96d56Sopenharmony_ci    int base,
1097db96d56Sopenharmony_ci    int alternate);
1107db96d56Sopenharmony_ci
1117db96d56Sopenharmony_ci#ifdef __cplusplus
1127db96d56Sopenharmony_ci}
1137db96d56Sopenharmony_ci#endif
1147db96d56Sopenharmony_ci#endif /* !Py_INTERNAL_LONG_H */
115