/* Float object implementation */ /* XXX There should be overflow checks here, but it's hard to check for any kind of float exception without losing portability. */ #include "Python.h" #include "pycore_abstract.h" // _PyNumber_Index() #include "pycore_dtoa.h" // _Py_dg_dtoa() #include "pycore_floatobject.h" // _PyFloat_FormatAdvancedWriter() #include "pycore_freelist.h" // _Py_FREELIST_FREE(), _Py_FREELIST_POP() #include "pycore_initconfig.h" // _PyStatus_OK() #include "pycore_long.h" // _PyLong_GetOne() #include "pycore_modsupport.h" // _PyArg_NoKwnames() #include "pycore_object.h" // _PyObject_Init(), _PyDebugAllocatorStats() #include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR #include "pycore_pystate.h" // _PyInterpreterState_GET() #include "pycore_structseq.h" // _PyStructSequence_FiniBuiltin() #include <float.h> // DBL_MAX #include <stdlib.h> // strtol() /*[clinic input] class float "PyObject *" "&PyFloat_Type" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=dd0003f68f144284]*/ #include "clinic/floatobject.c.h" double PyFloat_GetMax(void) { … } double PyFloat_GetMin(void) { … } static PyTypeObject FloatInfoType; PyDoc_STRVAR(floatinfo__doc__, "sys.float_info\n\ \n\ A named tuple holding information about the float type. It contains low level\n\ information about the precision and internal representation. Please study\n\ your system's :file:`float.h` for more information."); static PyStructSequence_Field floatinfo_fields[] = …; static PyStructSequence_Desc floatinfo_desc = …; PyObject * PyFloat_GetInfo(void) { … } PyObject * PyFloat_FromDouble(double fval) { … } #ifdef Py_GIL_DISABLED PyObject *_PyFloat_FromDouble_ConsumeInputs(_PyStackRef left, _PyStackRef right, double value) { PyStackRef_CLOSE(left); PyStackRef_CLOSE(right); return PyFloat_FromDouble(value); } #else // Py_GIL_DISABLED PyObject *_PyFloat_FromDouble_ConsumeInputs(_PyStackRef left, _PyStackRef right, double value) { … } #endif // Py_GIL_DISABLED static PyObject * float_from_string_inner(const char *s, Py_ssize_t len, void *obj) { … } PyObject * PyFloat_FromString(PyObject *v) { … } void _PyFloat_ExactDealloc(PyObject *obj) { … } static void float_dealloc(PyObject *op) { … } double PyFloat_AsDouble(PyObject *op) { … } /* Macro and helper that convert PyObject obj to a C double and store the value in dbl. If conversion to double raises an exception, obj is set to NULL, and the function invoking this macro returns NULL. If obj is not of float or int type, Py_NotImplemented is incref'ed, stored in obj, and returned from the function invoking this macro. */ #define CONVERT_TO_DOUBLE(obj, dbl) … /* Methods */ int _Py_convert_int_to_double(PyObject **v, double *dbl) { … } static PyObject * float_repr(PyFloatObject *v) { … } /* Comparison is pretty much a nightmare. When comparing float to float, * we do it as straightforwardly (and long-windedly) as conceivable, so * that, e.g., Python x == y delivers the same result as the platform * C x == y when x and/or y is a NaN. * When mixing float with an integer type, there's no good *uniform* approach. * Converting the double to an integer obviously doesn't work, since we * may lose info from fractional bits. Converting the integer to a double * also has two failure modes: (1) an int may trigger overflow (too * large to fit in the dynamic range of a C double); (2) even a C long may have * more bits than fit in a C double (e.g., on a 64-bit box long may have * 63 bits of precision, but a C double probably has only 53), and then * we can falsely claim equality when low-order integer bits are lost by * coercion to double. So this part is painful too. */ static PyObject* float_richcompare(PyObject *v, PyObject *w, int op) { … } static Py_hash_t float_hash(PyFloatObject *v) { … } static PyObject * float_add(PyObject *v, PyObject *w) { … } static PyObject * float_sub(PyObject *v, PyObject *w) { … } static PyObject * float_mul(PyObject *v, PyObject *w) { … } static PyObject * float_div(PyObject *v, PyObject *w) { … } static PyObject * float_rem(PyObject *v, PyObject *w) { … } static void _float_div_mod(double vx, double wx, double *floordiv, double *mod) { … } static PyObject * float_divmod(PyObject *v, PyObject *w) { … } static PyObject * float_floor_div(PyObject *v, PyObject *w) { … } /* determine whether x is an odd integer or not; assumes that x is not an infinity or nan. */ #define DOUBLE_IS_ODD_INTEGER … static PyObject * float_pow(PyObject *v, PyObject *w, PyObject *z) { … } #undef DOUBLE_IS_ODD_INTEGER static PyObject * float_neg(PyFloatObject *v) { … } static PyObject * float_abs(PyFloatObject *v) { … } static int float_bool(PyFloatObject *v) { … } /*[clinic input] float.is_integer Return True if the float is an integer. [clinic start generated code]*/ static PyObject * float_is_integer_impl(PyObject *self) /*[clinic end generated code: output=7112acf95a4d31ea input=311810d3f777e10d]*/ { … } /*[clinic input] float.__trunc__ Return the Integral closest to x between 0 and x. [clinic start generated code]*/ static PyObject * float___trunc___impl(PyObject *self) /*[clinic end generated code: output=dd3e289dd4c6b538 input=591b9ba0d650fdff]*/ { … } /*[clinic input] float.__floor__ Return the floor as an Integral. [clinic start generated code]*/ static PyObject * float___floor___impl(PyObject *self) /*[clinic end generated code: output=e0551dbaea8c01d1 input=77bb13eb12e268df]*/ { … } /*[clinic input] float.__ceil__ Return the ceiling as an Integral. [clinic start generated code]*/ static PyObject * float___ceil___impl(PyObject *self) /*[clinic end generated code: output=a2fd8858f73736f9 input=79e41ae94aa0a516]*/ { … } /* double_round: rounds a finite double to the closest multiple of 10**-ndigits; here ndigits is within reasonable bounds (typically, -308 <= ndigits <= 323). Returns a Python float, or sets a Python error and returns NULL on failure (OverflowError and memory errors are possible). */ #if _PY_SHORT_FLOAT_REPR == 1 /* version of double_round that uses the correctly-rounded string<->double conversions from Python/dtoa.c */ static PyObject * double_round(double x, int ndigits) { … } #else // _PY_SHORT_FLOAT_REPR == 0 /* fallback version, to be used when correctly rounded binary<->decimal conversions aren't available */ static PyObject * double_round(double x, int ndigits) { double pow1, pow2, y, z; if (ndigits >= 0) { if (ndigits > 22) { /* pow1 and pow2 are each safe from overflow, but pow1*pow2 ~= pow(10.0, ndigits) might overflow */ pow1 = pow(10.0, (double)(ndigits-22)); pow2 = 1e22; } else { pow1 = pow(10.0, (double)ndigits); pow2 = 1.0; } y = (x*pow1)*pow2; /* if y overflows, then rounded value is exactly x */ if (!isfinite(y)) return PyFloat_FromDouble(x); } else { pow1 = pow(10.0, (double)-ndigits); pow2 = 1.0; /* unused; silences a gcc compiler warning */ y = x / pow1; } z = round(y); if (fabs(y-z) == 0.5) /* halfway between two integers; use round-half-even */ z = 2.0*round(y/2.0); if (ndigits >= 0) z = (z / pow2) / pow1; else z *= pow1; /* if computation resulted in overflow, raise OverflowError */ if (!isfinite(z)) { PyErr_SetString(PyExc_OverflowError, "overflow occurred during round"); return NULL; } return PyFloat_FromDouble(z); } #endif // _PY_SHORT_FLOAT_REPR == 0 /* round a Python float v to the closest multiple of 10**-ndigits */ /*[clinic input] float.__round__ ndigits as o_ndigits: object = None / Return the Integral closest to x, rounding half toward even. When an argument is passed, work like built-in round(x, ndigits). [clinic start generated code]*/ static PyObject * float___round___impl(PyObject *self, PyObject *o_ndigits) /*[clinic end generated code: output=374c36aaa0f13980 input=fc0fe25924fbc9ed]*/ { … } static PyObject * float_float(PyObject *v) { … } /*[clinic input] float.conjugate Return self, the complex conjugate of any float. [clinic start generated code]*/ static PyObject * float_conjugate_impl(PyObject *self) /*[clinic end generated code: output=8ca292c2479194af input=82ba6f37a9ff91dd]*/ { … } /* turn ASCII hex characters into integer values and vice versa */ static char char_from_hex(int x) { … } /* This table maps characters to their hexadecimal values, only * works with encodings whose lower half is ASCII (like UTF-8). * '0' maps to 0, ..., '9' maps to 9. * 'a' and 'A' map to 10, ..., 'f' and 'F' map to 15. * All other indices map to -1. */ static const int _CHAR_TO_HEX[256] = …; /* Convert a character to its hexadecimal value, or -1 if it's not a * valid hexadecimal character, only works with encodings whose lower * half is ASCII (like UTF-8). */ static int hex_from_char(unsigned char c) { … } /* convert a float to a hexadecimal string */ /* TOHEX_NBITS is DBL_MANT_DIG rounded up to the next integer of the form 4k+1. */ #define TOHEX_NBITS … /*[clinic input] float.hex Return a hexadecimal representation of a floating-point number. >>> (-0.1).hex() '-0x1.999999999999ap-4' >>> 3.14159.hex() '0x1.921f9f01b866ep+1' [clinic start generated code]*/ static PyObject * float_hex_impl(PyObject *self) /*[clinic end generated code: output=0ebc9836e4d302d4 input=bec1271a33d47e67]*/ { … } /* Convert a hexadecimal string to a float. */ /*[clinic input] @classmethod float.fromhex string: object / Create a floating-point number from a hexadecimal string. >>> float.fromhex('0x1.ffffp10') 2047.984375 >>> float.fromhex('-0x1p-1074') -5e-324 [clinic start generated code]*/ static PyObject * float_fromhex(PyTypeObject *type, PyObject *string) /*[clinic end generated code: output=46c0274d22b78e82 input=0407bebd354bca89]*/ { … } /*[clinic input] float.as_integer_ratio Return a pair of integers, whose ratio is exactly equal to the original float. The ratio is in lowest terms and has a positive denominator. Raise OverflowError on infinities and a ValueError on NaNs. >>> (10.0).as_integer_ratio() (10, 1) >>> (0.0).as_integer_ratio() (0, 1) >>> (-.25).as_integer_ratio() (-1, 4) [clinic start generated code]*/ static PyObject * float_as_integer_ratio_impl(PyObject *self) /*[clinic end generated code: output=65f25f0d8d30a712 input=d5ba7765655d75bd]*/ { … } static PyObject * float_subtype_new(PyTypeObject *type, PyObject *x); /*[clinic input] @classmethod float.__new__ as float_new x: object(c_default="NULL") = 0 / Convert a string or number to a floating-point number, if possible. [clinic start generated code]*/ static PyObject * float_new_impl(PyTypeObject *type, PyObject *x) /*[clinic end generated code: output=ccf1e8dc460ba6ba input=55909f888aa0c8a6]*/ { … } /* Wimpy, slow approach to tp_new calls for subtypes of float: first create a regular float from whatever arguments we got, then allocate a subtype instance and initialize its ob_fval from the regular float. The regular float is then thrown away. */ static PyObject * float_subtype_new(PyTypeObject *type, PyObject *x) { … } static PyObject * float_vectorcall(PyObject *type, PyObject * const*args, size_t nargsf, PyObject *kwnames) { … } /*[clinic input] @classmethod float.from_number number: object / Convert real number to a floating-point number. [clinic start generated code]*/ static PyObject * float_from_number(PyTypeObject *type, PyObject *number) /*[clinic end generated code: output=bbcf05529fe907a3 input=1f8424d9bc11866a]*/ { … } /*[clinic input] float.__getnewargs__ [clinic start generated code]*/ static PyObject * float___getnewargs___impl(PyObject *self) /*[clinic end generated code: output=873258c9d206b088 input=002279d1d77891e6]*/ { … } /* this is for the benefit of the pack/unpack routines below */ float_format_type; #define unknown_format … #define ieee_big_endian_format … #define ieee_little_endian_format … #define float_format … #define double_format … /*[clinic input] @classmethod float.__getformat__ typestr: str Must be 'double' or 'float'. / You probably don't want to use this function. It exists mainly to be used in Python's test suite. This function returns whichever of 'unknown', 'IEEE, big-endian' or 'IEEE, little-endian' best describes the format of floating-point numbers used by the C type named by typestr. [clinic start generated code]*/ static PyObject * float___getformat___impl(PyTypeObject *type, const char *typestr) /*[clinic end generated code: output=2bfb987228cc9628 input=90d5e246409a246e]*/ { … } static PyObject * float_getreal(PyObject *v, void *closure) { … } static PyObject * float_getimag(PyObject *v, void *closure) { … } /*[clinic input] float.__format__ format_spec: unicode / Formats the float according to format_spec. [clinic start generated code]*/ static PyObject * float___format___impl(PyObject *self, PyObject *format_spec) /*[clinic end generated code: output=b260e52a47eade56 input=2ece1052211fd0e6]*/ { … } static PyMethodDef float_methods[] = …; static PyGetSetDef float_getset[] = …; static PyNumberMethods float_as_number = …; PyTypeObject PyFloat_Type = …; static void _init_global_state(void) { … } void _PyFloat_InitState(PyInterpreterState *interp) { … } PyStatus _PyFloat_InitTypes(PyInterpreterState *interp) { … } void _PyFloat_FiniType(PyInterpreterState *interp) { … } /* Print summary info about the state of the optimized allocator */ void _PyFloat_DebugMallocStats(FILE *out) { … } /*---------------------------------------------------------------------------- * PyFloat_{Pack,Unpack}{2,4,8}. See floatobject.h. * To match the NPY_HALF_ROUND_TIES_TO_EVEN behavior in: * https://github.com/numpy/numpy/blob/master/numpy/core/src/npymath/halffloat.c * We use: * bits = (unsigned short)f; Note the truncation * if ((f - bits > 0.5) || (f - bits == 0.5 && bits % 2)) { * bits++; * } */ int PyFloat_Pack2(double x, char *data, int le) { … } int PyFloat_Pack4(double x, char *data, int le) { … } int PyFloat_Pack8(double x, char *data, int le) { … } double PyFloat_Unpack2(const char *data, int le) { … } double PyFloat_Unpack4(const char *data, int le) { … } double PyFloat_Unpack8(const char *data, int le) { … }