+++ /dev/null
-\r
-/* Float object implementation */\r
-\r
-/* XXX There should be overflow checks here, but it's hard to check\r
- for any kind of float exception without losing portability. */\r
-\r
-#include "Python.h"\r
-#include "structseq.h"\r
-\r
-#include <ctype.h>\r
-#include <float.h>\r
-\r
-#undef MAX\r
-#undef MIN\r
-#define MAX(x, y) ((x) < (y) ? (y) : (x))\r
-#define MIN(x, y) ((x) < (y) ? (x) : (y))\r
-\r
-#ifdef _OSF_SOURCE\r
-/* OSF1 5.1 doesn't make this available with XOPEN_SOURCE_EXTENDED defined */\r
-extern int finite(double);\r
-#endif\r
-\r
-/* Special free list -- see comments for same code in intobject.c. */\r
-#define BLOCK_SIZE 1000 /* 1K less typical malloc overhead */\r
-#define BHEAD_SIZE 8 /* Enough for a 64-bit pointer */\r
-#define N_FLOATOBJECTS ((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyFloatObject))\r
-\r
-struct _floatblock {\r
- struct _floatblock *next;\r
- PyFloatObject objects[N_FLOATOBJECTS];\r
-};\r
-\r
-typedef struct _floatblock PyFloatBlock;\r
-\r
-static PyFloatBlock *block_list = NULL;\r
-static PyFloatObject *free_list = NULL;\r
-\r
-static PyFloatObject *\r
-fill_free_list(void)\r
-{\r
- PyFloatObject *p, *q;\r
- /* XXX Float blocks escape the object heap. Use PyObject_MALLOC ??? */\r
- p = (PyFloatObject *) PyMem_MALLOC(sizeof(PyFloatBlock));\r
- if (p == NULL)\r
- return (PyFloatObject *) PyErr_NoMemory();\r
- ((PyFloatBlock *)p)->next = block_list;\r
- block_list = (PyFloatBlock *)p;\r
- p = &((PyFloatBlock *)p)->objects[0];\r
- q = p + N_FLOATOBJECTS;\r
- while (--q > p)\r
- Py_TYPE(q) = (struct _typeobject *)(q-1);\r
- Py_TYPE(q) = NULL;\r
- return p + N_FLOATOBJECTS - 1;\r
-}\r
-\r
-double\r
-PyFloat_GetMax(void)\r
-{\r
- return DBL_MAX;\r
-}\r
-\r
-double\r
-PyFloat_GetMin(void)\r
-{\r
- return DBL_MIN;\r
-}\r
-\r
-static PyTypeObject FloatInfoType = {0, 0, 0, 0, 0, 0};\r
-\r
-PyDoc_STRVAR(floatinfo__doc__,\r
-"sys.float_info\n\\r
-\n\\r
-A structseq holding information about the float type. It contains low level\n\\r
-information about the precision and internal representation. Please study\n\\r
-your system's :file:`float.h` for more information.");\r
-\r
-static PyStructSequence_Field floatinfo_fields[] = {\r
- {"max", "DBL_MAX -- maximum representable finite float"},\r
- {"max_exp", "DBL_MAX_EXP -- maximum int e such that radix**(e-1) "\r
- "is representable"},\r
- {"max_10_exp", "DBL_MAX_10_EXP -- maximum int e such that 10**e "\r
- "is representable"},\r
- {"min", "DBL_MIN -- Minimum positive normalizer float"},\r
- {"min_exp", "DBL_MIN_EXP -- minimum int e such that radix**(e-1) "\r
- "is a normalized float"},\r
- {"min_10_exp", "DBL_MIN_10_EXP -- minimum int e such that 10**e is "\r
- "a normalized"},\r
- {"dig", "DBL_DIG -- digits"},\r
- {"mant_dig", "DBL_MANT_DIG -- mantissa digits"},\r
- {"epsilon", "DBL_EPSILON -- Difference between 1 and the next "\r
- "representable float"},\r
- {"radix", "FLT_RADIX -- radix of exponent"},\r
- {"rounds", "FLT_ROUNDS -- addition rounds"},\r
- {0}\r
-};\r
-\r
-static PyStructSequence_Desc floatinfo_desc = {\r
- "sys.float_info", /* name */\r
- floatinfo__doc__, /* doc */\r
- floatinfo_fields, /* fields */\r
- 11\r
-};\r
-\r
-PyObject *\r
-PyFloat_GetInfo(void)\r
-{\r
- PyObject* floatinfo;\r
- int pos = 0;\r
-\r
- floatinfo = PyStructSequence_New(&FloatInfoType);\r
- if (floatinfo == NULL) {\r
- return NULL;\r
- }\r
-\r
-#define SetIntFlag(flag) \\r
- PyStructSequence_SET_ITEM(floatinfo, pos++, PyInt_FromLong(flag))\r
-#define SetDblFlag(flag) \\r
- PyStructSequence_SET_ITEM(floatinfo, pos++, PyFloat_FromDouble(flag))\r
-\r
- SetDblFlag(DBL_MAX);\r
- SetIntFlag(DBL_MAX_EXP);\r
- SetIntFlag(DBL_MAX_10_EXP);\r
- SetDblFlag(DBL_MIN);\r
- SetIntFlag(DBL_MIN_EXP);\r
- SetIntFlag(DBL_MIN_10_EXP);\r
- SetIntFlag(DBL_DIG);\r
- SetIntFlag(DBL_MANT_DIG);\r
- SetDblFlag(DBL_EPSILON);\r
- SetIntFlag(FLT_RADIX);\r
- SetIntFlag(FLT_ROUNDS);\r
-#undef SetIntFlag\r
-#undef SetDblFlag\r
-\r
- if (PyErr_Occurred()) {\r
- Py_CLEAR(floatinfo);\r
- return NULL;\r
- }\r
- return floatinfo;\r
-}\r
-\r
-PyObject *\r
-PyFloat_FromDouble(double fval)\r
-{\r
- register PyFloatObject *op;\r
- if (free_list == NULL) {\r
- if ((free_list = fill_free_list()) == NULL)\r
- return NULL;\r
- }\r
- /* Inline PyObject_New */\r
- op = free_list;\r
- free_list = (PyFloatObject *)Py_TYPE(op);\r
- PyObject_INIT(op, &PyFloat_Type);\r
- op->ob_fval = fval;\r
- return (PyObject *) op;\r
-}\r
-\r
-/**************************************************************************\r
-RED_FLAG 22-Sep-2000 tim\r
-PyFloat_FromString's pend argument is braindead. Prior to this RED_FLAG,\r
-\r
-1. If v was a regular string, *pend was set to point to its terminating\r
- null byte. That's useless (the caller can find that without any\r
- help from this function!).\r
-\r
-2. If v was a Unicode string, or an object convertible to a character\r
- buffer, *pend was set to point into stack trash (the auto temp\r
- vector holding the character buffer). That was downright dangerous.\r
-\r
-Since we can't change the interface of a public API function, pend is\r
-still supported but now *officially* useless: if pend is not NULL,\r
-*pend is set to NULL.\r
-**************************************************************************/\r
-PyObject *\r
-PyFloat_FromString(PyObject *v, char **pend)\r
-{\r
- const char *s, *last, *end;\r
- double x;\r
- char buffer[256]; /* for errors */\r
-#ifdef Py_USING_UNICODE\r
- char *s_buffer = NULL;\r
-#endif\r
- Py_ssize_t len;\r
- PyObject *result = NULL;\r
-\r
- if (pend)\r
- *pend = NULL;\r
- if (PyString_Check(v)) {\r
- s = PyString_AS_STRING(v);\r
- len = PyString_GET_SIZE(v);\r
- }\r
-#ifdef Py_USING_UNICODE\r
- else if (PyUnicode_Check(v)) {\r
- s_buffer = (char *)PyMem_MALLOC(PyUnicode_GET_SIZE(v)+1);\r
- if (s_buffer == NULL)\r
- return PyErr_NoMemory();\r
- if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v),\r
- PyUnicode_GET_SIZE(v),\r
- s_buffer,\r
- NULL))\r
- goto error;\r
- s = s_buffer;\r
- len = strlen(s);\r
- }\r
-#endif\r
- else if (PyObject_AsCharBuffer(v, &s, &len)) {\r
- PyErr_SetString(PyExc_TypeError,\r
- "float() argument must be a string or a number");\r
- return NULL;\r
- }\r
- last = s + len;\r
-\r
- while (Py_ISSPACE(*s))\r
- s++;\r
- /* We don't care about overflow or underflow. If the platform\r
- * supports them, infinities and signed zeroes (on underflow) are\r
- * fine. */\r
- x = PyOS_string_to_double(s, (char **)&end, NULL);\r
- if (x == -1.0 && PyErr_Occurred())\r
- goto error;\r
- while (Py_ISSPACE(*end))\r
- end++;\r
- if (end == last)\r
- result = PyFloat_FromDouble(x);\r
- else {\r
- PyOS_snprintf(buffer, sizeof(buffer),\r
- "invalid literal for float(): %.200s", s);\r
- PyErr_SetString(PyExc_ValueError, buffer);\r
- result = NULL;\r
- }\r
-\r
- error:\r
-#ifdef Py_USING_UNICODE\r
- if (s_buffer)\r
- PyMem_FREE(s_buffer);\r
-#endif\r
- return result;\r
-}\r
-\r
-static void\r
-float_dealloc(PyFloatObject *op)\r
-{\r
- if (PyFloat_CheckExact(op)) {\r
- Py_TYPE(op) = (struct _typeobject *)free_list;\r
- free_list = op;\r
- }\r
- else\r
- Py_TYPE(op)->tp_free((PyObject *)op);\r
-}\r
-\r
-double\r
-PyFloat_AsDouble(PyObject *op)\r
-{\r
- PyNumberMethods *nb;\r
- PyFloatObject *fo;\r
- double val;\r
-\r
- if (op && PyFloat_Check(op))\r
- return PyFloat_AS_DOUBLE((PyFloatObject*) op);\r
-\r
- if (op == NULL) {\r
- PyErr_BadArgument();\r
- return -1;\r
- }\r
-\r
- if ((nb = Py_TYPE(op)->tp_as_number) == NULL || nb->nb_float == NULL) {\r
- PyErr_SetString(PyExc_TypeError, "a float is required");\r
- return -1;\r
- }\r
-\r
- fo = (PyFloatObject*) (*nb->nb_float) (op);\r
- if (fo == NULL)\r
- return -1;\r
- if (!PyFloat_Check(fo)) {\r
- Py_DECREF(fo);\r
- PyErr_SetString(PyExc_TypeError,\r
- "nb_float should return float object");\r
- return -1;\r
- }\r
-\r
- val = PyFloat_AS_DOUBLE(fo);\r
- Py_DECREF(fo);\r
-\r
- return val;\r
-}\r
-\r
-/* Methods */\r
-\r
-/* Macro and helper that convert PyObject obj to a C double and store\r
- the value in dbl; this replaces the functionality of the coercion\r
- slot function. If conversion to double raises an exception, obj is\r
- set to NULL, and the function invoking this macro returns NULL. If\r
- obj is not of float, int or long type, Py_NotImplemented is incref'ed,\r
- stored in obj, and returned from the function invoking this macro.\r
-*/\r
-#define CONVERT_TO_DOUBLE(obj, dbl) \\r
- if (PyFloat_Check(obj)) \\r
- dbl = PyFloat_AS_DOUBLE(obj); \\r
- else if (convert_to_double(&(obj), &(dbl)) < 0) \\r
- return obj;\r
-\r
-static int\r
-convert_to_double(PyObject **v, double *dbl)\r
-{\r
- register PyObject *obj = *v;\r
-\r
- if (PyInt_Check(obj)) {\r
- *dbl = (double)PyInt_AS_LONG(obj);\r
- }\r
- else if (PyLong_Check(obj)) {\r
- *dbl = PyLong_AsDouble(obj);\r
- if (*dbl == -1.0 && PyErr_Occurred()) {\r
- *v = NULL;\r
- return -1;\r
- }\r
- }\r
- else {\r
- Py_INCREF(Py_NotImplemented);\r
- *v = Py_NotImplemented;\r
- return -1;\r
- }\r
- return 0;\r
-}\r
-\r
-/* XXX PyFloat_AsString and PyFloat_AsReprString are deprecated:\r
- XXX they pass a char buffer without passing a length.\r
-*/\r
-void\r
-PyFloat_AsString(char *buf, PyFloatObject *v)\r
-{\r
- char *tmp = PyOS_double_to_string(v->ob_fval, 'g',\r
- PyFloat_STR_PRECISION,\r
- Py_DTSF_ADD_DOT_0, NULL);\r
- strcpy(buf, tmp);\r
- PyMem_Free(tmp);\r
-}\r
-\r
-void\r
-PyFloat_AsReprString(char *buf, PyFloatObject *v)\r
-{\r
- char * tmp = PyOS_double_to_string(v->ob_fval, 'r', 0,\r
- Py_DTSF_ADD_DOT_0, NULL);\r
- strcpy(buf, tmp);\r
- PyMem_Free(tmp);\r
-}\r
-\r
-/* ARGSUSED */\r
-static int\r
-float_print(PyFloatObject *v, FILE *fp, int flags)\r
-{\r
- char *buf;\r
- if (flags & Py_PRINT_RAW)\r
- buf = PyOS_double_to_string(v->ob_fval,\r
- 'g', PyFloat_STR_PRECISION,\r
- Py_DTSF_ADD_DOT_0, NULL);\r
- else\r
- buf = PyOS_double_to_string(v->ob_fval,\r
- 'r', 0, Py_DTSF_ADD_DOT_0, NULL);\r
- Py_BEGIN_ALLOW_THREADS\r
- fputs(buf, fp);\r
- Py_END_ALLOW_THREADS\r
- PyMem_Free(buf);\r
- return 0;\r
-}\r
-\r
-static PyObject *\r
-float_str_or_repr(PyFloatObject *v, int precision, char format_code)\r
-{\r
- PyObject *result;\r
- char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v),\r
- format_code, precision,\r
- Py_DTSF_ADD_DOT_0,\r
- NULL);\r
- if (!buf)\r
- return PyErr_NoMemory();\r
- result = PyString_FromString(buf);\r
- PyMem_Free(buf);\r
- return result;\r
-}\r
-\r
-static PyObject *\r
-float_repr(PyFloatObject *v)\r
-{\r
- return float_str_or_repr(v, 0, 'r');\r
-}\r
-\r
-static PyObject *\r
-float_str(PyFloatObject *v)\r
-{\r
- return float_str_or_repr(v, PyFloat_STR_PRECISION, 'g');\r
-}\r
-\r
-/* Comparison is pretty much a nightmare. When comparing float to float,\r
- * we do it as straightforwardly (and long-windedly) as conceivable, so\r
- * that, e.g., Python x == y delivers the same result as the platform\r
- * C x == y when x and/or y is a NaN.\r
- * When mixing float with an integer type, there's no good *uniform* approach.\r
- * Converting the double to an integer obviously doesn't work, since we\r
- * may lose info from fractional bits. Converting the integer to a double\r
- * also has two failure modes: (1) a long int may trigger overflow (too\r
- * large to fit in the dynamic range of a C double); (2) even a C long may have\r
- * more bits than fit in a C double (e.g., on a a 64-bit box long may have\r
- * 63 bits of precision, but a C double probably has only 53), and then\r
- * we can falsely claim equality when low-order integer bits are lost by\r
- * coercion to double. So this part is painful too.\r
- */\r
-\r
-static PyObject*\r
-float_richcompare(PyObject *v, PyObject *w, int op)\r
-{\r
- double i, j;\r
- int r = 0;\r
-\r
- assert(PyFloat_Check(v));\r
- i = PyFloat_AS_DOUBLE(v);\r
-\r
- /* Switch on the type of w. Set i and j to doubles to be compared,\r
- * and op to the richcomp to use.\r
- */\r
- if (PyFloat_Check(w))\r
- j = PyFloat_AS_DOUBLE(w);\r
-\r
- else if (!Py_IS_FINITE(i)) {\r
- if (PyInt_Check(w) || PyLong_Check(w))\r
- /* If i is an infinity, its magnitude exceeds any\r
- * finite integer, so it doesn't matter which int we\r
- * compare i with. If i is a NaN, similarly.\r
- */\r
- j = 0.0;\r
- else\r
- goto Unimplemented;\r
- }\r
-\r
- else if (PyInt_Check(w)) {\r
- long jj = PyInt_AS_LONG(w);\r
- /* In the worst realistic case I can imagine, C double is a\r
- * Cray single with 48 bits of precision, and long has 64\r
- * bits.\r
- */\r
-#if SIZEOF_LONG > 6\r
- unsigned long abs = (unsigned long)(jj < 0 ? -jj : jj);\r
- if (abs >> 48) {\r
- /* Needs more than 48 bits. Make it take the\r
- * PyLong path.\r
- */\r
- PyObject *result;\r
- PyObject *ww = PyLong_FromLong(jj);\r
-\r
- if (ww == NULL)\r
- return NULL;\r
- result = float_richcompare(v, ww, op);\r
- Py_DECREF(ww);\r
- return result;\r
- }\r
-#endif\r
- j = (double)jj;\r
- assert((long)j == jj);\r
- }\r
-\r
- else if (PyLong_Check(w)) {\r
- int vsign = i == 0.0 ? 0 : i < 0.0 ? -1 : 1;\r
- int wsign = _PyLong_Sign(w);\r
- size_t nbits;\r
- int exponent;\r
-\r
- if (vsign != wsign) {\r
- /* Magnitudes are irrelevant -- the signs alone\r
- * determine the outcome.\r
- */\r
- i = (double)vsign;\r
- j = (double)wsign;\r
- goto Compare;\r
- }\r
- /* The signs are the same. */\r
- /* Convert w to a double if it fits. In particular, 0 fits. */\r
- nbits = _PyLong_NumBits(w);\r
- if (nbits == (size_t)-1 && PyErr_Occurred()) {\r
- /* This long is so large that size_t isn't big enough\r
- * to hold the # of bits. Replace with little doubles\r
- * that give the same outcome -- w is so large that\r
- * its magnitude must exceed the magnitude of any\r
- * finite float.\r
- */\r
- PyErr_Clear();\r
- i = (double)vsign;\r
- assert(wsign != 0);\r
- j = wsign * 2.0;\r
- goto Compare;\r
- }\r
- if (nbits <= 48) {\r
- j = PyLong_AsDouble(w);\r
- /* It's impossible that <= 48 bits overflowed. */\r
- assert(j != -1.0 || ! PyErr_Occurred());\r
- goto Compare;\r
- }\r
- assert(wsign != 0); /* else nbits was 0 */\r
- assert(vsign != 0); /* if vsign were 0, then since wsign is\r
- * not 0, we would have taken the\r
- * vsign != wsign branch at the start */\r
- /* We want to work with non-negative numbers. */\r
- if (vsign < 0) {\r
- /* "Multiply both sides" by -1; this also swaps the\r
- * comparator.\r
- */\r
- i = -i;\r
- op = _Py_SwappedOp[op];\r
- }\r
- assert(i > 0.0);\r
- (void) frexp(i, &exponent);\r
- /* exponent is the # of bits in v before the radix point;\r
- * we know that nbits (the # of bits in w) > 48 at this point\r
- */\r
- if (exponent < 0 || (size_t)exponent < nbits) {\r
- i = 1.0;\r
- j = 2.0;\r
- goto Compare;\r
- }\r
- if ((size_t)exponent > nbits) {\r
- i = 2.0;\r
- j = 1.0;\r
- goto Compare;\r
- }\r
- /* v and w have the same number of bits before the radix\r
- * point. Construct two longs that have the same comparison\r
- * outcome.\r
- */\r
- {\r
- double fracpart;\r
- double intpart;\r
- PyObject *result = NULL;\r
- PyObject *one = NULL;\r
- PyObject *vv = NULL;\r
- PyObject *ww = w;\r
-\r
- if (wsign < 0) {\r
- ww = PyNumber_Negative(w);\r
- if (ww == NULL)\r
- goto Error;\r
- }\r
- else\r
- Py_INCREF(ww);\r
-\r
- fracpart = modf(i, &intpart);\r
- vv = PyLong_FromDouble(intpart);\r
- if (vv == NULL)\r
- goto Error;\r
-\r
- if (fracpart != 0.0) {\r
- /* Shift left, and or a 1 bit into vv\r
- * to represent the lost fraction.\r
- */\r
- PyObject *temp;\r
-\r
- one = PyInt_FromLong(1);\r
- if (one == NULL)\r
- goto Error;\r
-\r
- temp = PyNumber_Lshift(ww, one);\r
- if (temp == NULL)\r
- goto Error;\r
- Py_DECREF(ww);\r
- ww = temp;\r
-\r
- temp = PyNumber_Lshift(vv, one);\r
- if (temp == NULL)\r
- goto Error;\r
- Py_DECREF(vv);\r
- vv = temp;\r
-\r
- temp = PyNumber_Or(vv, one);\r
- if (temp == NULL)\r
- goto Error;\r
- Py_DECREF(vv);\r
- vv = temp;\r
- }\r
-\r
- r = PyObject_RichCompareBool(vv, ww, op);\r
- if (r < 0)\r
- goto Error;\r
- result = PyBool_FromLong(r);\r
- Error:\r
- Py_XDECREF(vv);\r
- Py_XDECREF(ww);\r
- Py_XDECREF(one);\r
- return result;\r
- }\r
- } /* else if (PyLong_Check(w)) */\r
-\r
- else /* w isn't float, int, or long */\r
- goto Unimplemented;\r
-\r
- Compare:\r
- PyFPE_START_PROTECT("richcompare", return NULL)\r
- switch (op) {\r
- case Py_EQ:\r
- r = i == j;\r
- break;\r
- case Py_NE:\r
- r = i != j;\r
- break;\r
- case Py_LE:\r
- r = i <= j;\r
- break;\r
- case Py_GE:\r
- r = i >= j;\r
- break;\r
- case Py_LT:\r
- r = i < j;\r
- break;\r
- case Py_GT:\r
- r = i > j;\r
- break;\r
- }\r
- PyFPE_END_PROTECT(r)\r
- return PyBool_FromLong(r);\r
-\r
- Unimplemented:\r
- Py_INCREF(Py_NotImplemented);\r
- return Py_NotImplemented;\r
-}\r
-\r
-static long\r
-float_hash(PyFloatObject *v)\r
-{\r
- return _Py_HashDouble(v->ob_fval);\r
-}\r
-\r
-static PyObject *\r
-float_add(PyObject *v, PyObject *w)\r
-{\r
- double a,b;\r
- CONVERT_TO_DOUBLE(v, a);\r
- CONVERT_TO_DOUBLE(w, b);\r
- PyFPE_START_PROTECT("add", return 0)\r
- a = a + b;\r
- PyFPE_END_PROTECT(a)\r
- return PyFloat_FromDouble(a);\r
-}\r
-\r
-static PyObject *\r
-float_sub(PyObject *v, PyObject *w)\r
-{\r
- double a,b;\r
- CONVERT_TO_DOUBLE(v, a);\r
- CONVERT_TO_DOUBLE(w, b);\r
- PyFPE_START_PROTECT("subtract", return 0)\r
- a = a - b;\r
- PyFPE_END_PROTECT(a)\r
- return PyFloat_FromDouble(a);\r
-}\r
-\r
-static PyObject *\r
-float_mul(PyObject *v, PyObject *w)\r
-{\r
- double a,b;\r
- CONVERT_TO_DOUBLE(v, a);\r
- CONVERT_TO_DOUBLE(w, b);\r
- PyFPE_START_PROTECT("multiply", return 0)\r
- a = a * b;\r
- PyFPE_END_PROTECT(a)\r
- return PyFloat_FromDouble(a);\r
-}\r
-\r
-static PyObject *\r
-float_div(PyObject *v, PyObject *w)\r
-{\r
- double a,b;\r
- CONVERT_TO_DOUBLE(v, a);\r
- CONVERT_TO_DOUBLE(w, b);\r
-#ifdef Py_NAN\r
- if (b == 0.0) {\r
- PyErr_SetString(PyExc_ZeroDivisionError,\r
- "float division by zero");\r
- return NULL;\r
- }\r
-#endif\r
- PyFPE_START_PROTECT("divide", return 0)\r
- a = a / b;\r
- PyFPE_END_PROTECT(a)\r
- return PyFloat_FromDouble(a);\r
-}\r
-\r
-static PyObject *\r
-float_classic_div(PyObject *v, PyObject *w)\r
-{\r
- double a,b;\r
- CONVERT_TO_DOUBLE(v, a);\r
- CONVERT_TO_DOUBLE(w, b);\r
- if (Py_DivisionWarningFlag >= 2 &&\r
- PyErr_Warn(PyExc_DeprecationWarning, "classic float division") < 0)\r
- return NULL;\r
-#ifdef Py_NAN\r
- if (b == 0.0) {\r
- PyErr_SetString(PyExc_ZeroDivisionError,\r
- "float division by zero");\r
- return NULL;\r
- }\r
-#endif\r
- PyFPE_START_PROTECT("divide", return 0)\r
- a = a / b;\r
- PyFPE_END_PROTECT(a)\r
- return PyFloat_FromDouble(a);\r
-}\r
-\r
-static PyObject *\r
-float_rem(PyObject *v, PyObject *w)\r
-{\r
- double vx, wx;\r
- double mod;\r
- CONVERT_TO_DOUBLE(v, vx);\r
- CONVERT_TO_DOUBLE(w, wx);\r
-#ifdef Py_NAN\r
- if (wx == 0.0) {\r
- PyErr_SetString(PyExc_ZeroDivisionError,\r
- "float modulo");\r
- return NULL;\r
- }\r
-#endif\r
- PyFPE_START_PROTECT("modulo", return 0)\r
- mod = fmod(vx, wx);\r
- if (mod) {\r
- /* ensure the remainder has the same sign as the denominator */\r
- if ((wx < 0) != (mod < 0)) {\r
- mod += wx;\r
- }\r
- }\r
- else {\r
- /* the remainder is zero, and in the presence of signed zeroes\r
- fmod returns different results across platforms; ensure\r
- it has the same sign as the denominator; we'd like to do\r
- "mod = wx * 0.0", but that may get optimized away */\r
- mod *= mod; /* hide "mod = +0" from optimizer */\r
- if (wx < 0.0)\r
- mod = -mod;\r
- }\r
- PyFPE_END_PROTECT(mod)\r
- return PyFloat_FromDouble(mod);\r
-}\r
-\r
-static PyObject *\r
-float_divmod(PyObject *v, PyObject *w)\r
-{\r
- double vx, wx;\r
- double div, mod, floordiv;\r
- CONVERT_TO_DOUBLE(v, vx);\r
- CONVERT_TO_DOUBLE(w, wx);\r
- if (wx == 0.0) {\r
- PyErr_SetString(PyExc_ZeroDivisionError, "float divmod()");\r
- return NULL;\r
- }\r
- PyFPE_START_PROTECT("divmod", return 0)\r
- mod = fmod(vx, wx);\r
- /* fmod is typically exact, so vx-mod is *mathematically* an\r
- exact multiple of wx. But this is fp arithmetic, and fp\r
- vx - mod is an approximation; the result is that div may\r
- not be an exact integral value after the division, although\r
- it will always be very close to one.\r
- */\r
- div = (vx - mod) / wx;\r
- if (mod) {\r
- /* ensure the remainder has the same sign as the denominator */\r
- if ((wx < 0) != (mod < 0)) {\r
- mod += wx;\r
- div -= 1.0;\r
- }\r
- }\r
- else {\r
- /* the remainder is zero, and in the presence of signed zeroes\r
- fmod returns different results across platforms; ensure\r
- it has the same sign as the denominator; we'd like to do\r
- "mod = wx * 0.0", but that may get optimized away */\r
- mod *= mod; /* hide "mod = +0" from optimizer */\r
- if (wx < 0.0)\r
- mod = -mod;\r
- }\r
- /* snap quotient to nearest integral value */\r
- if (div) {\r
- floordiv = floor(div);\r
- if (div - floordiv > 0.5)\r
- floordiv += 1.0;\r
- }\r
- else {\r
- /* div is zero - get the same sign as the true quotient */\r
- div *= div; /* hide "div = +0" from optimizers */\r
- floordiv = div * vx / wx; /* zero w/ sign of vx/wx */\r
- }\r
- PyFPE_END_PROTECT(floordiv)\r
- return Py_BuildValue("(dd)", floordiv, mod);\r
-}\r
-\r
-static PyObject *\r
-float_floor_div(PyObject *v, PyObject *w)\r
-{\r
- PyObject *t, *r;\r
-\r
- t = float_divmod(v, w);\r
- if (t == NULL || t == Py_NotImplemented)\r
- return t;\r
- assert(PyTuple_CheckExact(t));\r
- r = PyTuple_GET_ITEM(t, 0);\r
- Py_INCREF(r);\r
- Py_DECREF(t);\r
- return r;\r
-}\r
-\r
-/* determine whether x is an odd integer or not; assumes that\r
- x is not an infinity or nan. */\r
-#define DOUBLE_IS_ODD_INTEGER(x) (fmod(fabs(x), 2.0) == 1.0)\r
-\r
-static PyObject *\r
-float_pow(PyObject *v, PyObject *w, PyObject *z)\r
-{\r
- double iv, iw, ix;\r
- int negate_result = 0;\r
-\r
- if ((PyObject *)z != Py_None) {\r
- PyErr_SetString(PyExc_TypeError, "pow() 3rd argument not "\r
- "allowed unless all arguments are integers");\r
- return NULL;\r
- }\r
-\r
- CONVERT_TO_DOUBLE(v, iv);\r
- CONVERT_TO_DOUBLE(w, iw);\r
-\r
- /* Sort out special cases here instead of relying on pow() */\r
- if (iw == 0) { /* v**0 is 1, even 0**0 */\r
- return PyFloat_FromDouble(1.0);\r
- }\r
- if (Py_IS_NAN(iv)) { /* nan**w = nan, unless w == 0 */\r
- return PyFloat_FromDouble(iv);\r
- }\r
- if (Py_IS_NAN(iw)) { /* v**nan = nan, unless v == 1; 1**nan = 1 */\r
- return PyFloat_FromDouble(iv == 1.0 ? 1.0 : iw);\r
- }\r
- if (Py_IS_INFINITY(iw)) {\r
- /* v**inf is: 0.0 if abs(v) < 1; 1.0 if abs(v) == 1; inf if\r
- * abs(v) > 1 (including case where v infinite)\r
- *\r
- * v**-inf is: inf if abs(v) < 1; 1.0 if abs(v) == 1; 0.0 if\r
- * abs(v) > 1 (including case where v infinite)\r
- */\r
- iv = fabs(iv);\r
- if (iv == 1.0)\r
- return PyFloat_FromDouble(1.0);\r
- else if ((iw > 0.0) == (iv > 1.0))\r
- return PyFloat_FromDouble(fabs(iw)); /* return inf */\r
- else\r
- return PyFloat_FromDouble(0.0);\r
- }\r
- if (Py_IS_INFINITY(iv)) {\r
- /* (+-inf)**w is: inf for w positive, 0 for w negative; in\r
- * both cases, we need to add the appropriate sign if w is\r
- * an odd integer.\r
- */\r
- int iw_is_odd = DOUBLE_IS_ODD_INTEGER(iw);\r
- if (iw > 0.0)\r
- return PyFloat_FromDouble(iw_is_odd ? iv : fabs(iv));\r
- else\r
- return PyFloat_FromDouble(iw_is_odd ?\r
- copysign(0.0, iv) : 0.0);\r
- }\r
- if (iv == 0.0) { /* 0**w is: 0 for w positive, 1 for w zero\r
- (already dealt with above), and an error\r
- if w is negative. */\r
- int iw_is_odd = DOUBLE_IS_ODD_INTEGER(iw);\r
- if (iw < 0.0) {\r
- PyErr_SetString(PyExc_ZeroDivisionError,\r
- "0.0 cannot be raised to a "\r
- "negative power");\r
- return NULL;\r
- }\r
- /* use correct sign if iw is odd */\r
- return PyFloat_FromDouble(iw_is_odd ? iv : 0.0);\r
- }\r
-\r
- if (iv < 0.0) {\r
- /* Whether this is an error is a mess, and bumps into libm\r
- * bugs so we have to figure it out ourselves.\r
- */\r
- if (iw != floor(iw)) {\r
- PyErr_SetString(PyExc_ValueError, "negative number "\r
- "cannot be raised to a fractional power");\r
- return NULL;\r
- }\r
- /* iw is an exact integer, albeit perhaps a very large\r
- * one. Replace iv by its absolute value and remember\r
- * to negate the pow result if iw is odd.\r
- */\r
- iv = -iv;\r
- negate_result = DOUBLE_IS_ODD_INTEGER(iw);\r
- }\r
-\r
- if (iv == 1.0) { /* 1**w is 1, even 1**inf and 1**nan */\r
- /* (-1) ** large_integer also ends up here. Here's an\r
- * extract from the comments for the previous\r
- * implementation explaining why this special case is\r
- * necessary:\r
- *\r
- * -1 raised to an exact integer should never be exceptional.\r
- * Alas, some libms (chiefly glibc as of early 2003) return\r
- * NaN and set EDOM on pow(-1, large_int) if the int doesn't\r
- * happen to be representable in a *C* integer. That's a\r
- * bug.\r
- */\r
- return PyFloat_FromDouble(negate_result ? -1.0 : 1.0);\r
- }\r
-\r
- /* Now iv and iw are finite, iw is nonzero, and iv is\r
- * positive and not equal to 1.0. We finally allow\r
- * the platform pow to step in and do the rest.\r
- */\r
- errno = 0;\r
- PyFPE_START_PROTECT("pow", return NULL)\r
- ix = pow(iv, iw);\r
- PyFPE_END_PROTECT(ix)\r
- Py_ADJUST_ERANGE1(ix);\r
- if (negate_result)\r
- ix = -ix;\r
-\r
- if (errno != 0) {\r
- /* We don't expect any errno value other than ERANGE, but\r
- * the range of libm bugs appears unbounded.\r
- */\r
- PyErr_SetFromErrno(errno == ERANGE ? PyExc_OverflowError :\r
- PyExc_ValueError);\r
- return NULL;\r
- }\r
- return PyFloat_FromDouble(ix);\r
-}\r
-\r
-#undef DOUBLE_IS_ODD_INTEGER\r
-\r
-static PyObject *\r
-float_neg(PyFloatObject *v)\r
-{\r
- return PyFloat_FromDouble(-v->ob_fval);\r
-}\r
-\r
-static PyObject *\r
-float_abs(PyFloatObject *v)\r
-{\r
- return PyFloat_FromDouble(fabs(v->ob_fval));\r
-}\r
-\r
-static int\r
-float_nonzero(PyFloatObject *v)\r
-{\r
- return v->ob_fval != 0.0;\r
-}\r
-\r
-static int\r
-float_coerce(PyObject **pv, PyObject **pw)\r
-{\r
- if (PyInt_Check(*pw)) {\r
- long x = PyInt_AsLong(*pw);\r
- *pw = PyFloat_FromDouble((double)x);\r
- Py_INCREF(*pv);\r
- return 0;\r
- }\r
- else if (PyLong_Check(*pw)) {\r
- double x = PyLong_AsDouble(*pw);\r
- if (x == -1.0 && PyErr_Occurred())\r
- return -1;\r
- *pw = PyFloat_FromDouble(x);\r
- Py_INCREF(*pv);\r
- return 0;\r
- }\r
- else if (PyFloat_Check(*pw)) {\r
- Py_INCREF(*pv);\r
- Py_INCREF(*pw);\r
- return 0;\r
- }\r
- return 1; /* Can't do it */\r
-}\r
-\r
-static PyObject *\r
-float_is_integer(PyObject *v)\r
-{\r
- double x = PyFloat_AsDouble(v);\r
- PyObject *o;\r
-\r
- if (x == -1.0 && PyErr_Occurred())\r
- return NULL;\r
- if (!Py_IS_FINITE(x))\r
- Py_RETURN_FALSE;\r
- errno = 0;\r
- PyFPE_START_PROTECT("is_integer", return NULL)\r
- o = (floor(x) == x) ? Py_True : Py_False;\r
- PyFPE_END_PROTECT(x)\r
- if (errno != 0) {\r
- PyErr_SetFromErrno(errno == ERANGE ? PyExc_OverflowError :\r
- PyExc_ValueError);\r
- return NULL;\r
- }\r
- Py_INCREF(o);\r
- return o;\r
-}\r
-\r
-#if 0\r
-static PyObject *\r
-float_is_inf(PyObject *v)\r
-{\r
- double x = PyFloat_AsDouble(v);\r
- if (x == -1.0 && PyErr_Occurred())\r
- return NULL;\r
- return PyBool_FromLong((long)Py_IS_INFINITY(x));\r
-}\r
-\r
-static PyObject *\r
-float_is_nan(PyObject *v)\r
-{\r
- double x = PyFloat_AsDouble(v);\r
- if (x == -1.0 && PyErr_Occurred())\r
- return NULL;\r
- return PyBool_FromLong((long)Py_IS_NAN(x));\r
-}\r
-\r
-static PyObject *\r
-float_is_finite(PyObject *v)\r
-{\r
- double x = PyFloat_AsDouble(v);\r
- if (x == -1.0 && PyErr_Occurred())\r
- return NULL;\r
- return PyBool_FromLong((long)Py_IS_FINITE(x));\r
-}\r
-#endif\r
-\r
-static PyObject *\r
-float_trunc(PyObject *v)\r
-{\r
- double x = PyFloat_AsDouble(v);\r
- double wholepart; /* integral portion of x, rounded toward 0 */\r
-\r
- (void)modf(x, &wholepart);\r
- /* Try to get out cheap if this fits in a Python int. The attempt\r
- * to cast to long must be protected, as C doesn't define what\r
- * happens if the double is too big to fit in a long. Some rare\r
- * systems raise an exception then (RISCOS was mentioned as one,\r
- * and someone using a non-default option on Sun also bumped into\r
- * that). Note that checking for <= LONG_MAX is unsafe: if a long\r
- * has more bits of precision than a double, casting LONG_MAX to\r
- * double may yield an approximation, and if that's rounded up,\r
- * then, e.g., wholepart=LONG_MAX+1 would yield true from the C\r
- * expression wholepart<=LONG_MAX, despite that wholepart is\r
- * actually greater than LONG_MAX. However, assuming a two's complement\r
- * machine with no trap representation, LONG_MIN will be a power of 2 (and\r
- * hence exactly representable as a double), and LONG_MAX = -1-LONG_MIN, so\r
- * the comparisons with (double)LONG_MIN below should be safe.\r
- */\r
- if ((double)LONG_MIN <= wholepart && wholepart < -(double)LONG_MIN) {\r
- const long aslong = (long)wholepart;\r
- return PyInt_FromLong(aslong);\r
- }\r
- return PyLong_FromDouble(wholepart);\r
-}\r
-\r
-static PyObject *\r
-float_long(PyObject *v)\r
-{\r
- double x = PyFloat_AsDouble(v);\r
- return PyLong_FromDouble(x);\r
-}\r
-\r
-/* _Py_double_round: rounds a finite nonzero double to the closest multiple of\r
- 10**-ndigits; here ndigits is within reasonable bounds (typically, -308 <=\r
- ndigits <= 323). Returns a Python float, or sets a Python error and\r
- returns NULL on failure (OverflowError and memory errors are possible). */\r
-\r
-#ifndef PY_NO_SHORT_FLOAT_REPR\r
-/* version of _Py_double_round that uses the correctly-rounded string<->double\r
- conversions from Python/dtoa.c */\r
-\r
-/* FIVE_POW_LIMIT is the largest k such that 5**k is exactly representable as\r
- a double. Since we're using the code in Python/dtoa.c, it should be safe\r
- to assume that C doubles are IEEE 754 binary64 format. To be on the safe\r
- side, we check this. */\r
-#if DBL_MANT_DIG == 53\r
-#define FIVE_POW_LIMIT 22\r
-#else\r
-#error "C doubles do not appear to be IEEE 754 binary64 format"\r
-#endif\r
-\r
-PyObject *\r
-_Py_double_round(double x, int ndigits) {\r
-\r
- double rounded, m;\r
- Py_ssize_t buflen, mybuflen=100;\r
- char *buf, *buf_end, shortbuf[100], *mybuf=shortbuf;\r
- int decpt, sign, val, halfway_case;\r
- PyObject *result = NULL;\r
- _Py_SET_53BIT_PRECISION_HEADER;\r
-\r
- /* Easy path for the common case ndigits == 0. */\r
- if (ndigits == 0) {\r
- rounded = round(x);\r
- if (fabs(rounded - x) == 0.5)\r
- /* halfway between two integers; use round-away-from-zero */\r
- rounded = x + (x > 0.0 ? 0.5 : -0.5);\r
- return PyFloat_FromDouble(rounded);\r
- }\r
-\r
- /* The basic idea is very simple: convert and round the double to a\r
- decimal string using _Py_dg_dtoa, then convert that decimal string\r
- back to a double with _Py_dg_strtod. There's one minor difficulty:\r
- Python 2.x expects round to do round-half-away-from-zero, while\r
- _Py_dg_dtoa does round-half-to-even. So we need some way to detect\r
- and correct the halfway cases.\r
-\r
- Detection: a halfway value has the form k * 0.5 * 10**-ndigits for\r
- some odd integer k. Or in other words, a rational number x is\r
- exactly halfway between two multiples of 10**-ndigits if its\r
- 2-valuation is exactly -ndigits-1 and its 5-valuation is at least\r
- -ndigits. For ndigits >= 0 the latter condition is automatically\r
- satisfied for a binary float x, since any such float has\r
- nonnegative 5-valuation. For 0 > ndigits >= -22, x needs to be an\r
- integral multiple of 5**-ndigits; we can check this using fmod.\r
- For -22 > ndigits, there are no halfway cases: 5**23 takes 54 bits\r
- to represent exactly, so any odd multiple of 0.5 * 10**n for n >=\r
- 23 takes at least 54 bits of precision to represent exactly.\r
-\r
- Correction: a simple strategy for dealing with halfway cases is to\r
- (for the halfway cases only) call _Py_dg_dtoa with an argument of\r
- ndigits+1 instead of ndigits (thus doing an exact conversion to\r
- decimal), round the resulting string manually, and then convert\r
- back using _Py_dg_strtod.\r
- */\r
-\r
- /* nans, infinities and zeros should have already been dealt\r
- with by the caller (in this case, builtin_round) */\r
- assert(Py_IS_FINITE(x) && x != 0.0);\r
-\r
- /* find 2-valuation val of x */\r
- m = frexp(x, &val);\r
- while (m != floor(m)) {\r
- m *= 2.0;\r
- val--;\r
- }\r
-\r
- /* determine whether this is a halfway case */\r
- if (val == -ndigits-1) {\r
- if (ndigits >= 0)\r
- halfway_case = 1;\r
- else if (ndigits >= -FIVE_POW_LIMIT) {\r
- double five_pow = 1.0;\r
- int i;\r
- for (i=0; i < -ndigits; i++)\r
- five_pow *= 5.0;\r
- halfway_case = fmod(x, five_pow) == 0.0;\r
- }\r
- else\r
- halfway_case = 0;\r
- }\r
- else\r
- halfway_case = 0;\r
-\r
- /* round to a decimal string; use an extra place for halfway case */\r
- _Py_SET_53BIT_PRECISION_START;\r
- buf = _Py_dg_dtoa(x, 3, ndigits+halfway_case, &decpt, &sign, &buf_end);\r
- _Py_SET_53BIT_PRECISION_END;\r
- if (buf == NULL) {\r
- PyErr_NoMemory();\r
- return NULL;\r
- }\r
- buflen = buf_end - buf;\r
-\r
- /* in halfway case, do the round-half-away-from-zero manually */\r
- if (halfway_case) {\r
- int i, carry;\r
- /* sanity check: _Py_dg_dtoa should not have stripped\r
- any zeros from the result: there should be exactly\r
- ndigits+1 places following the decimal point, and\r
- the last digit in the buffer should be a '5'.*/\r
- assert(buflen - decpt == ndigits+1);\r
- assert(buf[buflen-1] == '5');\r
-\r
- /* increment and shift right at the same time. */\r
- decpt += 1;\r
- carry = 1;\r
- for (i=buflen-1; i-- > 0;) {\r
- carry += buf[i] - '0';\r
- buf[i+1] = carry % 10 + '0';\r
- carry /= 10;\r
- }\r
- buf[0] = carry + '0';\r
- }\r
-\r
- /* Get new buffer if shortbuf is too small. Space needed <= buf_end -\r
- buf + 8: (1 extra for '0', 1 for sign, 5 for exp, 1 for '\0'). */\r
- if (buflen + 8 > mybuflen) {\r
- mybuflen = buflen+8;\r
- mybuf = (char *)PyMem_Malloc(mybuflen);\r
- if (mybuf == NULL) {\r
- PyErr_NoMemory();\r
- goto exit;\r
- }\r
- }\r
- /* copy buf to mybuf, adding exponent, sign and leading 0 */\r
- PyOS_snprintf(mybuf, mybuflen, "%s0%se%d", (sign ? "-" : ""),\r
- buf, decpt - (int)buflen);\r
-\r
- /* and convert the resulting string back to a double */\r
- errno = 0;\r
- _Py_SET_53BIT_PRECISION_START;\r
- rounded = _Py_dg_strtod(mybuf, NULL);\r
- _Py_SET_53BIT_PRECISION_END;\r
- if (errno == ERANGE && fabs(rounded) >= 1.)\r
- PyErr_SetString(PyExc_OverflowError,\r
- "rounded value too large to represent");\r
- else\r
- result = PyFloat_FromDouble(rounded);\r
-\r
- /* done computing value; now clean up */\r
- if (mybuf != shortbuf)\r
- PyMem_Free(mybuf);\r
- exit:\r
- _Py_dg_freedtoa(buf);\r
- return result;\r
-}\r
-\r
-#undef FIVE_POW_LIMIT\r
-\r
-#else /* PY_NO_SHORT_FLOAT_REPR */\r
-\r
-/* fallback version, to be used when correctly rounded binary<->decimal\r
- conversions aren't available */\r
-\r
-PyObject *\r
-_Py_double_round(double x, int ndigits) {\r
- double pow1, pow2, y, z;\r
- if (ndigits >= 0) {\r
- if (ndigits > 22) {\r
- /* pow1 and pow2 are each safe from overflow, but\r
- pow1*pow2 ~= pow(10.0, ndigits) might overflow */\r
- pow1 = pow(10.0, (double)(ndigits-22));\r
- pow2 = 1e22;\r
- }\r
- else {\r
- pow1 = pow(10.0, (double)ndigits);\r
- pow2 = 1.0;\r
- }\r
- y = (x*pow1)*pow2;\r
- /* if y overflows, then rounded value is exactly x */\r
- if (!Py_IS_FINITE(y))\r
- return PyFloat_FromDouble(x);\r
- }\r
- else {\r
- pow1 = pow(10.0, (double)-ndigits);\r
- pow2 = 1.0; /* unused; silences a gcc compiler warning */\r
- y = x / pow1;\r
- }\r
-\r
- z = round(y);\r
- if (fabs(y-z) == 0.5)\r
- /* halfway between two integers; use round-away-from-zero */\r
- z = y + copysign(0.5, y);\r
-\r
- if (ndigits >= 0)\r
- z = (z / pow2) / pow1;\r
- else\r
- z *= pow1;\r
-\r
- /* if computation resulted in overflow, raise OverflowError */\r
- if (!Py_IS_FINITE(z)) {\r
- PyErr_SetString(PyExc_OverflowError,\r
- "overflow occurred during round");\r
- return NULL;\r
- }\r
-\r
- return PyFloat_FromDouble(z);\r
-}\r
-\r
-#endif /* PY_NO_SHORT_FLOAT_REPR */\r
-\r
-static PyObject *\r
-float_float(PyObject *v)\r
-{\r
- if (PyFloat_CheckExact(v))\r
- Py_INCREF(v);\r
- else\r
- v = PyFloat_FromDouble(((PyFloatObject *)v)->ob_fval);\r
- return v;\r
-}\r
-\r
-/* turn ASCII hex characters into integer values and vice versa */\r
-\r
-static char\r
-char_from_hex(int x)\r
-{\r
- assert(0 <= x && x < 16);\r
- return "0123456789abcdef"[x];\r
-}\r
-\r
-static int\r
-hex_from_char(char c) {\r
- int x;\r
- switch(c) {\r
- case '0':\r
- x = 0;\r
- break;\r
- case '1':\r
- x = 1;\r
- break;\r
- case '2':\r
- x = 2;\r
- break;\r
- case '3':\r
- x = 3;\r
- break;\r
- case '4':\r
- x = 4;\r
- break;\r
- case '5':\r
- x = 5;\r
- break;\r
- case '6':\r
- x = 6;\r
- break;\r
- case '7':\r
- x = 7;\r
- break;\r
- case '8':\r
- x = 8;\r
- break;\r
- case '9':\r
- x = 9;\r
- break;\r
- case 'a':\r
- case 'A':\r
- x = 10;\r
- break;\r
- case 'b':\r
- case 'B':\r
- x = 11;\r
- break;\r
- case 'c':\r
- case 'C':\r
- x = 12;\r
- break;\r
- case 'd':\r
- case 'D':\r
- x = 13;\r
- break;\r
- case 'e':\r
- case 'E':\r
- x = 14;\r
- break;\r
- case 'f':\r
- case 'F':\r
- x = 15;\r
- break;\r
- default:\r
- x = -1;\r
- break;\r
- }\r
- return x;\r
-}\r
-\r
-/* convert a float to a hexadecimal string */\r
-\r
-/* TOHEX_NBITS is DBL_MANT_DIG rounded up to the next integer\r
- of the form 4k+1. */\r
-#define TOHEX_NBITS DBL_MANT_DIG + 3 - (DBL_MANT_DIG+2)%4\r
-\r
-static PyObject *\r
-float_hex(PyObject *v)\r
-{\r
- double x, m;\r
- int e, shift, i, si, esign;\r
- /* Space for 1+(TOHEX_NBITS-1)/4 digits, a decimal point, and the\r
- trailing NUL byte. */\r
- char s[(TOHEX_NBITS-1)/4+3];\r
-\r
- CONVERT_TO_DOUBLE(v, x);\r
-\r
- if (Py_IS_NAN(x) || Py_IS_INFINITY(x))\r
- return float_str((PyFloatObject *)v);\r
-\r
- if (x == 0.0) {\r
- if (copysign(1.0, x) == -1.0)\r
- return PyString_FromString("-0x0.0p+0");\r
- else\r
- return PyString_FromString("0x0.0p+0");\r
- }\r
-\r
- m = frexp(fabs(x), &e);\r
- shift = 1 - MAX(DBL_MIN_EXP - e, 0);\r
- m = ldexp(m, shift);\r
- e -= shift;\r
-\r
- si = 0;\r
- s[si] = char_from_hex((int)m);\r
- si++;\r
- m -= (int)m;\r
- s[si] = '.';\r
- si++;\r
- for (i=0; i < (TOHEX_NBITS-1)/4; i++) {\r
- m *= 16.0;\r
- s[si] = char_from_hex((int)m);\r
- si++;\r
- m -= (int)m;\r
- }\r
- s[si] = '\0';\r
-\r
- if (e < 0) {\r
- esign = (int)'-';\r
- e = -e;\r
- }\r
- else\r
- esign = (int)'+';\r
-\r
- if (x < 0.0)\r
- return PyString_FromFormat("-0x%sp%c%d", s, esign, e);\r
- else\r
- return PyString_FromFormat("0x%sp%c%d", s, esign, e);\r
-}\r
-\r
-PyDoc_STRVAR(float_hex_doc,\r
-"float.hex() -> string\n\\r
-\n\\r
-Return a hexadecimal representation of a floating-point number.\n\\r
->>> (-0.1).hex()\n\\r
-'-0x1.999999999999ap-4'\n\\r
->>> 3.14159.hex()\n\\r
-'0x1.921f9f01b866ep+1'");\r
-\r
-/* Case-insensitive locale-independent string match used for nan and inf\r
- detection. t should be lower-case and null-terminated. Return a nonzero\r
- result if the first strlen(t) characters of s match t and 0 otherwise. */\r
-\r
-static int\r
-case_insensitive_match(const char *s, const char *t)\r
-{\r
- while(*t && Py_TOLOWER(*s) == *t) {\r
- s++;\r
- t++;\r
- }\r
- return *t ? 0 : 1;\r
-}\r
-\r
-/* Convert a hexadecimal string to a float. */\r
-\r
-static PyObject *\r
-float_fromhex(PyObject *cls, PyObject *arg)\r
-{\r
- PyObject *result_as_float, *result;\r
- double x;\r
- long exp, top_exp, lsb, key_digit;\r
- char *s, *coeff_start, *s_store, *coeff_end, *exp_start, *s_end;\r
- int half_eps, digit, round_up, sign=1;\r
- Py_ssize_t length, ndigits, fdigits, i;\r
-\r
- /*\r
- * For the sake of simplicity and correctness, we impose an artificial\r
- * limit on ndigits, the total number of hex digits in the coefficient\r
- * The limit is chosen to ensure that, writing exp for the exponent,\r
- *\r
- * (1) if exp > LONG_MAX/2 then the value of the hex string is\r
- * guaranteed to overflow (provided it's nonzero)\r
- *\r
- * (2) if exp < LONG_MIN/2 then the value of the hex string is\r
- * guaranteed to underflow to 0.\r
- *\r
- * (3) if LONG_MIN/2 <= exp <= LONG_MAX/2 then there's no danger of\r
- * overflow in the calculation of exp and top_exp below.\r
- *\r
- * More specifically, ndigits is assumed to satisfy the following\r
- * inequalities:\r
- *\r
- * 4*ndigits <= DBL_MIN_EXP - DBL_MANT_DIG - LONG_MIN/2\r
- * 4*ndigits <= LONG_MAX/2 + 1 - DBL_MAX_EXP\r
- *\r
- * If either of these inequalities is not satisfied, a ValueError is\r
- * raised. Otherwise, write x for the value of the hex string, and\r
- * assume x is nonzero. Then\r
- *\r
- * 2**(exp-4*ndigits) <= |x| < 2**(exp+4*ndigits).\r
- *\r
- * Now if exp > LONG_MAX/2 then:\r
- *\r
- * exp - 4*ndigits >= LONG_MAX/2 + 1 - (LONG_MAX/2 + 1 - DBL_MAX_EXP)\r
- * = DBL_MAX_EXP\r
- *\r
- * so |x| >= 2**DBL_MAX_EXP, which is too large to be stored in C\r
- * double, so overflows. If exp < LONG_MIN/2, then\r
- *\r
- * exp + 4*ndigits <= LONG_MIN/2 - 1 + (\r
- * DBL_MIN_EXP - DBL_MANT_DIG - LONG_MIN/2)\r
- * = DBL_MIN_EXP - DBL_MANT_DIG - 1\r
- *\r
- * and so |x| < 2**(DBL_MIN_EXP-DBL_MANT_DIG-1), hence underflows to 0\r
- * when converted to a C double.\r
- *\r
- * It's easy to show that if LONG_MIN/2 <= exp <= LONG_MAX/2 then both\r
- * exp+4*ndigits and exp-4*ndigits are within the range of a long.\r
- */\r
-\r
- if (PyString_AsStringAndSize(arg, &s, &length))\r
- return NULL;\r
- s_end = s + length;\r
-\r
- /********************\r
- * Parse the string *\r
- ********************/\r
-\r
- /* leading whitespace and optional sign */\r
- while (Py_ISSPACE(*s))\r
- s++;\r
- if (*s == '-') {\r
- s++;\r
- sign = -1;\r
- }\r
- else if (*s == '+')\r
- s++;\r
-\r
- /* infinities and nans */\r
- if (*s == 'i' || *s == 'I') {\r
- if (!case_insensitive_match(s+1, "nf"))\r
- goto parse_error;\r
- s += 3;\r
- x = Py_HUGE_VAL;\r
- if (case_insensitive_match(s, "inity"))\r
- s += 5;\r
- goto finished;\r
- }\r
- if (*s == 'n' || *s == 'N') {\r
- if (!case_insensitive_match(s+1, "an"))\r
- goto parse_error;\r
- s += 3;\r
- x = Py_NAN;\r
- goto finished;\r
- }\r
-\r
- /* [0x] */\r
- s_store = s;\r
- if (*s == '0') {\r
- s++;\r
- if (*s == 'x' || *s == 'X')\r
- s++;\r
- else\r
- s = s_store;\r
- }\r
-\r
- /* coefficient: <integer> [. <fraction>] */\r
- coeff_start = s;\r
- while (hex_from_char(*s) >= 0)\r
- s++;\r
- s_store = s;\r
- if (*s == '.') {\r
- s++;\r
- while (hex_from_char(*s) >= 0)\r
- s++;\r
- coeff_end = s-1;\r
- }\r
- else\r
- coeff_end = s;\r
-\r
- /* ndigits = total # of hex digits; fdigits = # after point */\r
- ndigits = coeff_end - coeff_start;\r
- fdigits = coeff_end - s_store;\r
- if (ndigits == 0)\r
- goto parse_error;\r
- if (ndigits > MIN(DBL_MIN_EXP - DBL_MANT_DIG - LONG_MIN/2,\r
- LONG_MAX/2 + 1 - DBL_MAX_EXP)/4)\r
- goto insane_length_error;\r
-\r
- /* [p <exponent>] */\r
- if (*s == 'p' || *s == 'P') {\r
- s++;\r
- exp_start = s;\r
- if (*s == '-' || *s == '+')\r
- s++;\r
- if (!('0' <= *s && *s <= '9'))\r
- goto parse_error;\r
- s++;\r
- while ('0' <= *s && *s <= '9')\r
- s++;\r
- exp = strtol(exp_start, NULL, 10);\r
- }\r
- else\r
- exp = 0;\r
-\r
-/* for 0 <= j < ndigits, HEX_DIGIT(j) gives the jth most significant digit */\r
-#define HEX_DIGIT(j) hex_from_char(*((j) < fdigits ? \\r
- coeff_end-(j) : \\r
- coeff_end-1-(j)))\r
-\r
- /*******************************************\r
- * Compute rounded value of the hex string *\r
- *******************************************/\r
-\r
- /* Discard leading zeros, and catch extreme overflow and underflow */\r
- while (ndigits > 0 && HEX_DIGIT(ndigits-1) == 0)\r
- ndigits--;\r
- if (ndigits == 0 || exp < LONG_MIN/2) {\r
- x = 0.0;\r
- goto finished;\r
- }\r
- if (exp > LONG_MAX/2)\r
- goto overflow_error;\r
-\r
- /* Adjust exponent for fractional part. */\r
- exp = exp - 4*((long)fdigits);\r
-\r
- /* top_exp = 1 more than exponent of most sig. bit of coefficient */\r
- top_exp = exp + 4*((long)ndigits - 1);\r
- for (digit = HEX_DIGIT(ndigits-1); digit != 0; digit /= 2)\r
- top_exp++;\r
-\r
- /* catch almost all nonextreme cases of overflow and underflow here */\r
- if (top_exp < DBL_MIN_EXP - DBL_MANT_DIG) {\r
- x = 0.0;\r
- goto finished;\r
- }\r
- if (top_exp > DBL_MAX_EXP)\r
- goto overflow_error;\r
-\r
- /* lsb = exponent of least significant bit of the *rounded* value.\r
- This is top_exp - DBL_MANT_DIG unless result is subnormal. */\r
- lsb = MAX(top_exp, (long)DBL_MIN_EXP) - DBL_MANT_DIG;\r
-\r
- x = 0.0;\r
- if (exp >= lsb) {\r
- /* no rounding required */\r
- for (i = ndigits-1; i >= 0; i--)\r
- x = 16.0*x + HEX_DIGIT(i);\r
- x = ldexp(x, (int)(exp));\r
- goto finished;\r
- }\r
- /* rounding required. key_digit is the index of the hex digit\r
- containing the first bit to be rounded away. */\r
- half_eps = 1 << (int)((lsb - exp - 1) % 4);\r
- key_digit = (lsb - exp - 1) / 4;\r
- for (i = ndigits-1; i > key_digit; i--)\r
- x = 16.0*x + HEX_DIGIT(i);\r
- digit = HEX_DIGIT(key_digit);\r
- x = 16.0*x + (double)(digit & (16-2*half_eps));\r
-\r
- /* round-half-even: round up if bit lsb-1 is 1 and at least one of\r
- bits lsb, lsb-2, lsb-3, lsb-4, ... is 1. */\r
- if ((digit & half_eps) != 0) {\r
- round_up = 0;\r
- if ((digit & (3*half_eps-1)) != 0 ||\r
- (half_eps == 8 && (HEX_DIGIT(key_digit+1) & 1) != 0))\r
- round_up = 1;\r
- else\r
- for (i = key_digit-1; i >= 0; i--)\r
- if (HEX_DIGIT(i) != 0) {\r
- round_up = 1;\r
- break;\r
- }\r
- if (round_up == 1) {\r
- x += 2*half_eps;\r
- if (top_exp == DBL_MAX_EXP &&\r
- x == ldexp((double)(2*half_eps), DBL_MANT_DIG))\r
- /* overflow corner case: pre-rounded value <\r
- 2**DBL_MAX_EXP; rounded=2**DBL_MAX_EXP. */\r
- goto overflow_error;\r
- }\r
- }\r
- x = ldexp(x, (int)(exp+4*key_digit));\r
-\r
- finished:\r
- /* optional trailing whitespace leading to the end of the string */\r
- while (Py_ISSPACE(*s))\r
- s++;\r
- if (s != s_end)\r
- goto parse_error;\r
- result_as_float = Py_BuildValue("(d)", sign * x);\r
- if (result_as_float == NULL)\r
- return NULL;\r
- result = PyObject_CallObject(cls, result_as_float);\r
- Py_DECREF(result_as_float);\r
- return result;\r
-\r
- overflow_error:\r
- PyErr_SetString(PyExc_OverflowError,\r
- "hexadecimal value too large to represent as a float");\r
- return NULL;\r
-\r
- parse_error:\r
- PyErr_SetString(PyExc_ValueError,\r
- "invalid hexadecimal floating-point string");\r
- return NULL;\r
-\r
- insane_length_error:\r
- PyErr_SetString(PyExc_ValueError,\r
- "hexadecimal string too long to convert");\r
- return NULL;\r
-}\r
-\r
-PyDoc_STRVAR(float_fromhex_doc,\r
-"float.fromhex(string) -> float\n\\r
-\n\\r
-Create a floating-point number from a hexadecimal string.\n\\r
->>> float.fromhex('0x1.ffffp10')\n\\r
-2047.984375\n\\r
->>> float.fromhex('-0x1p-1074')\n\\r
--4.9406564584124654e-324");\r
-\r
-\r
-static PyObject *\r
-float_as_integer_ratio(PyObject *v, PyObject *unused)\r
-{\r
- double self;\r
- double float_part;\r
- int exponent;\r
- int i;\r
-\r
- PyObject *prev;\r
- PyObject *py_exponent = NULL;\r
- PyObject *numerator = NULL;\r
- PyObject *denominator = NULL;\r
- PyObject *result_pair = NULL;\r
- PyNumberMethods *long_methods = PyLong_Type.tp_as_number;\r
-\r
-#define INPLACE_UPDATE(obj, call) \\r
- prev = obj; \\r
- obj = call; \\r
- Py_DECREF(prev); \\r
-\r
- CONVERT_TO_DOUBLE(v, self);\r
-\r
- if (Py_IS_INFINITY(self)) {\r
- PyErr_SetString(PyExc_OverflowError,\r
- "Cannot pass infinity to float.as_integer_ratio.");\r
- return NULL;\r
- }\r
-#ifdef Py_NAN\r
- if (Py_IS_NAN(self)) {\r
- PyErr_SetString(PyExc_ValueError,\r
- "Cannot pass NaN to float.as_integer_ratio.");\r
- return NULL;\r
- }\r
-#endif\r
-\r
- PyFPE_START_PROTECT("as_integer_ratio", goto error);\r
- float_part = frexp(self, &exponent); /* self == float_part * 2**exponent exactly */\r
- PyFPE_END_PROTECT(float_part);\r
-\r
- for (i=0; i<300 && float_part != floor(float_part) ; i++) {\r
- float_part *= 2.0;\r
- exponent--;\r
- }\r
- /* self == float_part * 2**exponent exactly and float_part is integral.\r
- If FLT_RADIX != 2, the 300 steps may leave a tiny fractional part\r
- to be truncated by PyLong_FromDouble(). */\r
-\r
- numerator = PyLong_FromDouble(float_part);\r
- if (numerator == NULL) goto error;\r
-\r
- /* fold in 2**exponent */\r
- denominator = PyLong_FromLong(1);\r
- py_exponent = PyLong_FromLong(labs((long)exponent));\r
- if (py_exponent == NULL) goto error;\r
- INPLACE_UPDATE(py_exponent,\r
- long_methods->nb_lshift(denominator, py_exponent));\r
- if (py_exponent == NULL) goto error;\r
- if (exponent > 0) {\r
- INPLACE_UPDATE(numerator,\r
- long_methods->nb_multiply(numerator, py_exponent));\r
- if (numerator == NULL) goto error;\r
- }\r
- else {\r
- Py_DECREF(denominator);\r
- denominator = py_exponent;\r
- py_exponent = NULL;\r
- }\r
-\r
- /* Returns ints instead of longs where possible */\r
- INPLACE_UPDATE(numerator, PyNumber_Int(numerator));\r
- if (numerator == NULL) goto error;\r
- INPLACE_UPDATE(denominator, PyNumber_Int(denominator));\r
- if (denominator == NULL) goto error;\r
-\r
- result_pair = PyTuple_Pack(2, numerator, denominator);\r
-\r
-#undef INPLACE_UPDATE\r
-error:\r
- Py_XDECREF(py_exponent);\r
- Py_XDECREF(denominator);\r
- Py_XDECREF(numerator);\r
- return result_pair;\r
-}\r
-\r
-PyDoc_STRVAR(float_as_integer_ratio_doc,\r
-"float.as_integer_ratio() -> (int, int)\n"\r
-"\n"\r
-"Return a pair of integers, whose ratio is exactly equal to the original\n"\r
-"float and with a positive denominator.\n"\r
-"Raise OverflowError on infinities and a ValueError on NaNs.\n"\r
-"\n"\r
-">>> (10.0).as_integer_ratio()\n"\r
-"(10, 1)\n"\r
-">>> (0.0).as_integer_ratio()\n"\r
-"(0, 1)\n"\r
-">>> (-.25).as_integer_ratio()\n"\r
-"(-1, 4)");\r
-\r
-\r
-static PyObject *\r
-float_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);\r
-\r
-static PyObject *\r
-float_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
-{\r
- PyObject *x = Py_False; /* Integer zero */\r
- static char *kwlist[] = {"x", 0};\r
-\r
- if (type != &PyFloat_Type)\r
- return float_subtype_new(type, args, kwds); /* Wimp out */\r
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:float", kwlist, &x))\r
- return NULL;\r
- /* If it's a string, but not a string subclass, use\r
- PyFloat_FromString. */\r
- if (PyString_CheckExact(x))\r
- return PyFloat_FromString(x, NULL);\r
- return PyNumber_Float(x);\r
-}\r
-\r
-/* Wimpy, slow approach to tp_new calls for subtypes of float:\r
- first create a regular float from whatever arguments we got,\r
- then allocate a subtype instance and initialize its ob_fval\r
- from the regular float. The regular float is then thrown away.\r
-*/\r
-static PyObject *\r
-float_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)\r
-{\r
- PyObject *tmp, *newobj;\r
-\r
- assert(PyType_IsSubtype(type, &PyFloat_Type));\r
- tmp = float_new(&PyFloat_Type, args, kwds);\r
- if (tmp == NULL)\r
- return NULL;\r
- assert(PyFloat_CheckExact(tmp));\r
- newobj = type->tp_alloc(type, 0);\r
- if (newobj == NULL) {\r
- Py_DECREF(tmp);\r
- return NULL;\r
- }\r
- ((PyFloatObject *)newobj)->ob_fval = ((PyFloatObject *)tmp)->ob_fval;\r
- Py_DECREF(tmp);\r
- return newobj;\r
-}\r
-\r
-static PyObject *\r
-float_getnewargs(PyFloatObject *v)\r
-{\r
- return Py_BuildValue("(d)", v->ob_fval);\r
-}\r
-\r
-/* this is for the benefit of the pack/unpack routines below */\r
-\r
-typedef enum {\r
- unknown_format, ieee_big_endian_format, ieee_little_endian_format\r
-} float_format_type;\r
-\r
-static float_format_type double_format, float_format;\r
-static float_format_type detected_double_format, detected_float_format;\r
-\r
-static PyObject *\r
-float_getformat(PyTypeObject *v, PyObject* arg)\r
-{\r
- char* s;\r
- float_format_type r;\r
-\r
- if (!PyString_Check(arg)) {\r
- PyErr_Format(PyExc_TypeError,\r
- "__getformat__() argument must be string, not %.500s",\r
- Py_TYPE(arg)->tp_name);\r
- return NULL;\r
- }\r
- s = PyString_AS_STRING(arg);\r
- if (strcmp(s, "double") == 0) {\r
- r = double_format;\r
- }\r
- else if (strcmp(s, "float") == 0) {\r
- r = float_format;\r
- }\r
- else {\r
- PyErr_SetString(PyExc_ValueError,\r
- "__getformat__() argument 1 must be "\r
- "'double' or 'float'");\r
- return NULL;\r
- }\r
-\r
- switch (r) {\r
- case unknown_format:\r
- return PyString_FromString("unknown");\r
- case ieee_little_endian_format:\r
- return PyString_FromString("IEEE, little-endian");\r
- case ieee_big_endian_format:\r
- return PyString_FromString("IEEE, big-endian");\r
- default:\r
- Py_FatalError("insane float_format or double_format");\r
- return NULL;\r
- }\r
-}\r
-\r
-PyDoc_STRVAR(float_getformat_doc,\r
-"float.__getformat__(typestr) -> string\n"\r
-"\n"\r
-"You probably don't want to use this function. It exists mainly to be\n"\r
-"used in Python's test suite.\n"\r
-"\n"\r
-"typestr must be 'double' or 'float'. This function returns whichever of\n"\r
-"'unknown', 'IEEE, big-endian' or 'IEEE, little-endian' best describes the\n"\r
-"format of floating point numbers used by the C type named by typestr.");\r
-\r
-static PyObject *\r
-float_setformat(PyTypeObject *v, PyObject* args)\r
-{\r
- char* typestr;\r
- char* format;\r
- float_format_type f;\r
- float_format_type detected;\r
- float_format_type *p;\r
-\r
- if (!PyArg_ParseTuple(args, "ss:__setformat__", &typestr, &format))\r
- return NULL;\r
-\r
- if (strcmp(typestr, "double") == 0) {\r
- p = &double_format;\r
- detected = detected_double_format;\r
- }\r
- else if (strcmp(typestr, "float") == 0) {\r
- p = &float_format;\r
- detected = detected_float_format;\r
- }\r
- else {\r
- PyErr_SetString(PyExc_ValueError,\r
- "__setformat__() argument 1 must "\r
- "be 'double' or 'float'");\r
- return NULL;\r
- }\r
-\r
- if (strcmp(format, "unknown") == 0) {\r
- f = unknown_format;\r
- }\r
- else if (strcmp(format, "IEEE, little-endian") == 0) {\r
- f = ieee_little_endian_format;\r
- }\r
- else if (strcmp(format, "IEEE, big-endian") == 0) {\r
- f = ieee_big_endian_format;\r
- }\r
- else {\r
- PyErr_SetString(PyExc_ValueError,\r
- "__setformat__() argument 2 must be "\r
- "'unknown', 'IEEE, little-endian' or "\r
- "'IEEE, big-endian'");\r
- return NULL;\r
-\r
- }\r
-\r
- if (f != unknown_format && f != detected) {\r
- PyErr_Format(PyExc_ValueError,\r
- "can only set %s format to 'unknown' or the "\r
- "detected platform value", typestr);\r
- return NULL;\r
- }\r
-\r
- *p = f;\r
- Py_RETURN_NONE;\r
-}\r
-\r
-PyDoc_STRVAR(float_setformat_doc,\r
-"float.__setformat__(typestr, fmt) -> None\n"\r
-"\n"\r
-"You probably don't want to use this function. It exists mainly to be\n"\r
-"used in Python's test suite.\n"\r
-"\n"\r
-"typestr must be 'double' or 'float'. fmt must be one of 'unknown',\n"\r
-"'IEEE, big-endian' or 'IEEE, little-endian', and in addition can only be\n"\r
-"one of the latter two if it appears to match the underlying C reality.\n"\r
-"\n"\r
-"Override the automatic determination of C-level floating point type.\n"\r
-"This affects how floats are converted to and from binary strings.");\r
-\r
-static PyObject *\r
-float_getzero(PyObject *v, void *closure)\r
-{\r
- return PyFloat_FromDouble(0.0);\r
-}\r
-\r
-static PyObject *\r
-float__format__(PyObject *self, PyObject *args)\r
-{\r
- PyObject *format_spec;\r
-\r
- if (!PyArg_ParseTuple(args, "O:__format__", &format_spec))\r
- return NULL;\r
- if (PyBytes_Check(format_spec))\r
- return _PyFloat_FormatAdvanced(self,\r
- PyBytes_AS_STRING(format_spec),\r
- PyBytes_GET_SIZE(format_spec));\r
- if (PyUnicode_Check(format_spec)) {\r
- /* Convert format_spec to a str */\r
- PyObject *result;\r
- PyObject *str_spec = PyObject_Str(format_spec);\r
-\r
- if (str_spec == NULL)\r
- return NULL;\r
-\r
- result = _PyFloat_FormatAdvanced(self,\r
- PyBytes_AS_STRING(str_spec),\r
- PyBytes_GET_SIZE(str_spec));\r
-\r
- Py_DECREF(str_spec);\r
- return result;\r
- }\r
- PyErr_SetString(PyExc_TypeError, "__format__ requires str or unicode");\r
- return NULL;\r
-}\r
-\r
-PyDoc_STRVAR(float__format__doc,\r
-"float.__format__(format_spec) -> string\n"\r
-"\n"\r
-"Formats the float according to format_spec.");\r
-\r
-\r
-static PyMethodDef float_methods[] = {\r
- {"conjugate", (PyCFunction)float_float, METH_NOARGS,\r
- "Return self, the complex conjugate of any float."},\r
- {"__trunc__", (PyCFunction)float_trunc, METH_NOARGS,\r
- "Return the Integral closest to x between 0 and x."},\r
- {"as_integer_ratio", (PyCFunction)float_as_integer_ratio, METH_NOARGS,\r
- float_as_integer_ratio_doc},\r
- {"fromhex", (PyCFunction)float_fromhex,\r
- METH_O|METH_CLASS, float_fromhex_doc},\r
- {"hex", (PyCFunction)float_hex,\r
- METH_NOARGS, float_hex_doc},\r
- {"is_integer", (PyCFunction)float_is_integer, METH_NOARGS,\r
- "Return True if the float is an integer."},\r
-#if 0\r
- {"is_inf", (PyCFunction)float_is_inf, METH_NOARGS,\r
- "Return True if the float is positive or negative infinite."},\r
- {"is_finite", (PyCFunction)float_is_finite, METH_NOARGS,\r
- "Return True if the float is finite, neither infinite nor NaN."},\r
- {"is_nan", (PyCFunction)float_is_nan, METH_NOARGS,\r
- "Return True if the float is not a number (NaN)."},\r
-#endif\r
- {"__getnewargs__", (PyCFunction)float_getnewargs, METH_NOARGS},\r
- {"__getformat__", (PyCFunction)float_getformat,\r
- METH_O|METH_CLASS, float_getformat_doc},\r
- {"__setformat__", (PyCFunction)float_setformat,\r
- METH_VARARGS|METH_CLASS, float_setformat_doc},\r
- {"__format__", (PyCFunction)float__format__,\r
- METH_VARARGS, float__format__doc},\r
- {NULL, NULL} /* sentinel */\r
-};\r
-\r
-static PyGetSetDef float_getset[] = {\r
- {"real",\r
- (getter)float_float, (setter)NULL,\r
- "the real part of a complex number",\r
- NULL},\r
- {"imag",\r
- (getter)float_getzero, (setter)NULL,\r
- "the imaginary part of a complex number",\r
- NULL},\r
- {NULL} /* Sentinel */\r
-};\r
-\r
-PyDoc_STRVAR(float_doc,\r
-"float(x) -> floating point number\n\\r
-\n\\r
-Convert a string or number to a floating point number, if possible.");\r
-\r
-\r
-static PyNumberMethods float_as_number = {\r
- float_add, /*nb_add*/\r
- float_sub, /*nb_subtract*/\r
- float_mul, /*nb_multiply*/\r
- float_classic_div, /*nb_divide*/\r
- float_rem, /*nb_remainder*/\r
- float_divmod, /*nb_divmod*/\r
- float_pow, /*nb_power*/\r
- (unaryfunc)float_neg, /*nb_negative*/\r
- (unaryfunc)float_float, /*nb_positive*/\r
- (unaryfunc)float_abs, /*nb_absolute*/\r
- (inquiry)float_nonzero, /*nb_nonzero*/\r
- 0, /*nb_invert*/\r
- 0, /*nb_lshift*/\r
- 0, /*nb_rshift*/\r
- 0, /*nb_and*/\r
- 0, /*nb_xor*/\r
- 0, /*nb_or*/\r
- float_coerce, /*nb_coerce*/\r
- float_trunc, /*nb_int*/\r
- float_long, /*nb_long*/\r
- float_float, /*nb_float*/\r
- 0, /* nb_oct */\r
- 0, /* nb_hex */\r
- 0, /* nb_inplace_add */\r
- 0, /* nb_inplace_subtract */\r
- 0, /* nb_inplace_multiply */\r
- 0, /* nb_inplace_divide */\r
- 0, /* nb_inplace_remainder */\r
- 0, /* nb_inplace_power */\r
- 0, /* nb_inplace_lshift */\r
- 0, /* nb_inplace_rshift */\r
- 0, /* nb_inplace_and */\r
- 0, /* nb_inplace_xor */\r
- 0, /* nb_inplace_or */\r
- float_floor_div, /* nb_floor_divide */\r
- float_div, /* nb_true_divide */\r
- 0, /* nb_inplace_floor_divide */\r
- 0, /* nb_inplace_true_divide */\r
-};\r
-\r
-PyTypeObject PyFloat_Type = {\r
- PyVarObject_HEAD_INIT(&PyType_Type, 0)\r
- "float",\r
- sizeof(PyFloatObject),\r
- 0,\r
- (destructor)float_dealloc, /* tp_dealloc */\r
- (printfunc)float_print, /* tp_print */\r
- 0, /* tp_getattr */\r
- 0, /* tp_setattr */\r
- 0, /* tp_compare */\r
- (reprfunc)float_repr, /* tp_repr */\r
- &float_as_number, /* tp_as_number */\r
- 0, /* tp_as_sequence */\r
- 0, /* tp_as_mapping */\r
- (hashfunc)float_hash, /* tp_hash */\r
- 0, /* tp_call */\r
- (reprfunc)float_str, /* tp_str */\r
- PyObject_GenericGetAttr, /* tp_getattro */\r
- 0, /* tp_setattro */\r
- 0, /* tp_as_buffer */\r
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |\r
- Py_TPFLAGS_BASETYPE, /* tp_flags */\r
- float_doc, /* tp_doc */\r
- 0, /* tp_traverse */\r
- 0, /* tp_clear */\r
- float_richcompare, /* tp_richcompare */\r
- 0, /* tp_weaklistoffset */\r
- 0, /* tp_iter */\r
- 0, /* tp_iternext */\r
- float_methods, /* tp_methods */\r
- 0, /* tp_members */\r
- float_getset, /* tp_getset */\r
- 0, /* tp_base */\r
- 0, /* tp_dict */\r
- 0, /* tp_descr_get */\r
- 0, /* tp_descr_set */\r
- 0, /* tp_dictoffset */\r
- 0, /* tp_init */\r
- 0, /* tp_alloc */\r
- float_new, /* tp_new */\r
-};\r
-\r
-void\r
-_PyFloat_Init(void)\r
-{\r
- /* We attempt to determine if this machine is using IEEE\r
- floating point formats by peering at the bits of some\r
- carefully chosen values. If it looks like we are on an\r
- IEEE platform, the float packing/unpacking routines can\r
- just copy bits, if not they resort to arithmetic & shifts\r
- and masks. The shifts & masks approach works on all finite\r
- values, but what happens to infinities, NaNs and signed\r
- zeroes on packing is an accident, and attempting to unpack\r
- a NaN or an infinity will raise an exception.\r
-\r
- Note that if we're on some whacked-out platform which uses\r
- IEEE formats but isn't strictly little-endian or big-\r
- endian, we will fall back to the portable shifts & masks\r
- method. */\r
-\r
-#if SIZEOF_DOUBLE == 8\r
- {\r
- double x = 9006104071832581.0;\r
- if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0)\r
- detected_double_format = ieee_big_endian_format;\r
- else if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0)\r
- detected_double_format = ieee_little_endian_format;\r
- else\r
- detected_double_format = unknown_format;\r
- }\r
-#else\r
- detected_double_format = unknown_format;\r
-#endif\r
-\r
-#if SIZEOF_FLOAT == 4\r
- {\r
- float y = 16711938.0;\r
- if (memcmp(&y, "\x4b\x7f\x01\x02", 4) == 0)\r
- detected_float_format = ieee_big_endian_format;\r
- else if (memcmp(&y, "\x02\x01\x7f\x4b", 4) == 0)\r
- detected_float_format = ieee_little_endian_format;\r
- else\r
- detected_float_format = unknown_format;\r
- }\r
-#else\r
- detected_float_format = unknown_format;\r
-#endif\r
-\r
- double_format = detected_double_format;\r
- float_format = detected_float_format;\r
-\r
- /* Init float info */\r
- if (FloatInfoType.tp_name == 0)\r
- PyStructSequence_InitType(&FloatInfoType, &floatinfo_desc);\r
-}\r
-\r
-int\r
-PyFloat_ClearFreeList(void)\r
-{\r
- PyFloatObject *p;\r
- PyFloatBlock *list, *next;\r
- int i;\r
- int u; /* remaining unfreed ints per block */\r
- int freelist_size = 0;\r
-\r
- list = block_list;\r
- block_list = NULL;\r
- free_list = NULL;\r
- while (list != NULL) {\r
- u = 0;\r
- for (i = 0, p = &list->objects[0];\r
- i < N_FLOATOBJECTS;\r
- i++, p++) {\r
- if (PyFloat_CheckExact(p) && Py_REFCNT(p) != 0)\r
- u++;\r
- }\r
- next = list->next;\r
- if (u) {\r
- list->next = block_list;\r
- block_list = list;\r
- for (i = 0, p = &list->objects[0];\r
- i < N_FLOATOBJECTS;\r
- i++, p++) {\r
- if (!PyFloat_CheckExact(p) ||\r
- Py_REFCNT(p) == 0) {\r
- Py_TYPE(p) = (struct _typeobject *)\r
- free_list;\r
- free_list = p;\r
- }\r
- }\r
- }\r
- else {\r
- PyMem_FREE(list);\r
- }\r
- freelist_size += u;\r
- list = next;\r
- }\r
- return freelist_size;\r
-}\r
-\r
-void\r
-PyFloat_Fini(void)\r
-{\r
- PyFloatObject *p;\r
- PyFloatBlock *list;\r
- int i;\r
- int u; /* total unfreed floats per block */\r
-\r
- u = PyFloat_ClearFreeList();\r
-\r
- if (!Py_VerboseFlag)\r
- return;\r
- fprintf(stderr, "# cleanup floats");\r
- if (!u) {\r
- fprintf(stderr, "\n");\r
- }\r
- else {\r
- fprintf(stderr,\r
- ": %d unfreed float%s\n",\r
- u, u == 1 ? "" : "s");\r
- }\r
- if (Py_VerboseFlag > 1) {\r
- list = block_list;\r
- while (list != NULL) {\r
- for (i = 0, p = &list->objects[0];\r
- i < N_FLOATOBJECTS;\r
- i++, p++) {\r
- if (PyFloat_CheckExact(p) &&\r
- Py_REFCNT(p) != 0) {\r
- char *buf = PyOS_double_to_string(\r
- PyFloat_AS_DOUBLE(p), 'r',\r
- 0, 0, NULL);\r
- if (buf) {\r
- /* XXX(twouters) cast\r
- refcount to long\r
- until %zd is\r
- universally\r
- available\r
- */\r
- fprintf(stderr,\r
- "# <float at %p, refcnt=%ld, val=%s>\n",\r
- p, (long)Py_REFCNT(p), buf);\r
- PyMem_Free(buf);\r
- }\r
- }\r
- }\r
- list = list->next;\r
- }\r
- }\r
-}\r
-\r
-/*----------------------------------------------------------------------------\r
- * _PyFloat_{Pack,Unpack}{4,8}. See floatobject.h.\r
- */\r
-int\r
-_PyFloat_Pack4(double x, unsigned char *p, int le)\r
-{\r
- if (float_format == unknown_format) {\r
- unsigned char sign;\r
- int e;\r
- double f;\r
- unsigned int fbits;\r
- int incr = 1;\r
-\r
- if (le) {\r
- p += 3;\r
- incr = -1;\r
- }\r
-\r
- if (x < 0) {\r
- sign = 1;\r
- x = -x;\r
- }\r
- else\r
- sign = 0;\r
-\r
- f = frexp(x, &e);\r
-\r
- /* Normalize f to be in the range [1.0, 2.0) */\r
- if (0.5 <= f && f < 1.0) {\r
- f *= 2.0;\r
- e--;\r
- }\r
- else if (f == 0.0)\r
- e = 0;\r
- else {\r
- PyErr_SetString(PyExc_SystemError,\r
- "frexp() result out of range");\r
- return -1;\r
- }\r
-\r
- if (e >= 128)\r
- goto Overflow;\r
- else if (e < -126) {\r
- /* Gradual underflow */\r
- f = ldexp(f, 126 + e);\r
- e = 0;\r
- }\r
- else if (!(e == 0 && f == 0.0)) {\r
- e += 127;\r
- f -= 1.0; /* Get rid of leading 1 */\r
- }\r
-\r
- f *= 8388608.0; /* 2**23 */\r
- fbits = (unsigned int)(f + 0.5); /* Round */\r
- assert(fbits <= 8388608);\r
- if (fbits >> 23) {\r
- /* The carry propagated out of a string of 23 1 bits. */\r
- fbits = 0;\r
- ++e;\r
- if (e >= 255)\r
- goto Overflow;\r
- }\r
-\r
- /* First byte */\r
- *p = (sign << 7) | (e >> 1);\r
- p += incr;\r
-\r
- /* Second byte */\r
- *p = (char) (((e & 1) << 7) | (fbits >> 16));\r
- p += incr;\r
-\r
- /* Third byte */\r
- *p = (fbits >> 8) & 0xFF;\r
- p += incr;\r
-\r
- /* Fourth byte */\r
- *p = fbits & 0xFF;\r
-\r
- /* Done */\r
- return 0;\r
-\r
- }\r
- else {\r
- float y = (float)x;\r
- const char *s = (char*)&y;\r
- int i, incr = 1;\r
-\r
- if (Py_IS_INFINITY(y) && !Py_IS_INFINITY(x))\r
- goto Overflow;\r
-\r
- if ((float_format == ieee_little_endian_format && !le)\r
- || (float_format == ieee_big_endian_format && le)) {\r
- p += 3;\r
- incr = -1;\r
- }\r
-\r
- for (i = 0; i < 4; i++) {\r
- *p = *s++;\r
- p += incr;\r
- }\r
- return 0;\r
- }\r
- Overflow:\r
- PyErr_SetString(PyExc_OverflowError,\r
- "float too large to pack with f format");\r
- return -1;\r
-}\r
-\r
-int\r
-_PyFloat_Pack8(double x, unsigned char *p, int le)\r
-{\r
- if (double_format == unknown_format) {\r
- unsigned char sign;\r
- int e;\r
- double f;\r
- unsigned int fhi, flo;\r
- int incr = 1;\r
-\r
- if (le) {\r
- p += 7;\r
- incr = -1;\r
- }\r
-\r
- if (x < 0) {\r
- sign = 1;\r
- x = -x;\r
- }\r
- else\r
- sign = 0;\r
-\r
- f = frexp(x, &e);\r
-\r
- /* Normalize f to be in the range [1.0, 2.0) */\r
- if (0.5 <= f && f < 1.0) {\r
- f *= 2.0;\r
- e--;\r
- }\r
- else if (f == 0.0)\r
- e = 0;\r
- else {\r
- PyErr_SetString(PyExc_SystemError,\r
- "frexp() result out of range");\r
- return -1;\r
- }\r
-\r
- if (e >= 1024)\r
- goto Overflow;\r
- else if (e < -1022) {\r
- /* Gradual underflow */\r
- f = ldexp(f, 1022 + e);\r
- e = 0;\r
- }\r
- else if (!(e == 0 && f == 0.0)) {\r
- e += 1023;\r
- f -= 1.0; /* Get rid of leading 1 */\r
- }\r
-\r
- /* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */\r
- f *= 268435456.0; /* 2**28 */\r
- fhi = (unsigned int)f; /* Truncate */\r
- assert(fhi < 268435456);\r
-\r
- f -= (double)fhi;\r
- f *= 16777216.0; /* 2**24 */\r
- flo = (unsigned int)(f + 0.5); /* Round */\r
- assert(flo <= 16777216);\r
- if (flo >> 24) {\r
- /* The carry propagated out of a string of 24 1 bits. */\r
- flo = 0;\r
- ++fhi;\r
- if (fhi >> 28) {\r
- /* And it also progagated out of the next 28 bits. */\r
- fhi = 0;\r
- ++e;\r
- if (e >= 2047)\r
- goto Overflow;\r
- }\r
- }\r
-\r
- /* First byte */\r
- *p = (sign << 7) | (e >> 4);\r
- p += incr;\r
-\r
- /* Second byte */\r
- *p = (unsigned char) (((e & 0xF) << 4) | (fhi >> 24));\r
- p += incr;\r
-\r
- /* Third byte */\r
- *p = (fhi >> 16) & 0xFF;\r
- p += incr;\r
-\r
- /* Fourth byte */\r
- *p = (fhi >> 8) & 0xFF;\r
- p += incr;\r
-\r
- /* Fifth byte */\r
- *p = fhi & 0xFF;\r
- p += incr;\r
-\r
- /* Sixth byte */\r
- *p = (flo >> 16) & 0xFF;\r
- p += incr;\r
-\r
- /* Seventh byte */\r
- *p = (flo >> 8) & 0xFF;\r
- p += incr;\r
-\r
- /* Eighth byte */\r
- *p = flo & 0xFF;\r
- /* p += incr; Unneeded (for now) */\r
-\r
- /* Done */\r
- return 0;\r
-\r
- Overflow:\r
- PyErr_SetString(PyExc_OverflowError,\r
- "float too large to pack with d format");\r
- return -1;\r
- }\r
- else {\r
- const char *s = (char*)&x;\r
- int i, incr = 1;\r
-\r
- if ((double_format == ieee_little_endian_format && !le)\r
- || (double_format == ieee_big_endian_format && le)) {\r
- p += 7;\r
- incr = -1;\r
- }\r
-\r
- for (i = 0; i < 8; i++) {\r
- *p = *s++;\r
- p += incr;\r
- }\r
- return 0;\r
- }\r
-}\r
-\r
-double\r
-_PyFloat_Unpack4(const unsigned char *p, int le)\r
-{\r
- if (float_format == unknown_format) {\r
- unsigned char sign;\r
- int e;\r
- unsigned int f;\r
- double x;\r
- int incr = 1;\r
-\r
- if (le) {\r
- p += 3;\r
- incr = -1;\r
- }\r
-\r
- /* First byte */\r
- sign = (*p >> 7) & 1;\r
- e = (*p & 0x7F) << 1;\r
- p += incr;\r
-\r
- /* Second byte */\r
- e |= (*p >> 7) & 1;\r
- f = (*p & 0x7F) << 16;\r
- p += incr;\r
-\r
- if (e == 255) {\r
- PyErr_SetString(\r
- PyExc_ValueError,\r
- "can't unpack IEEE 754 special value "\r
- "on non-IEEE platform");\r
- return -1;\r
- }\r
-\r
- /* Third byte */\r
- f |= *p << 8;\r
- p += incr;\r
-\r
- /* Fourth byte */\r
- f |= *p;\r
-\r
- x = (double)f / 8388608.0;\r
-\r
- /* XXX This sadly ignores Inf/NaN issues */\r
- if (e == 0)\r
- e = -126;\r
- else {\r
- x += 1.0;\r
- e -= 127;\r
- }\r
- x = ldexp(x, e);\r
-\r
- if (sign)\r
- x = -x;\r
-\r
- return x;\r
- }\r
- else {\r
- float x;\r
-\r
- if ((float_format == ieee_little_endian_format && !le)\r
- || (float_format == ieee_big_endian_format && le)) {\r
- char buf[4];\r
- char *d = &buf[3];\r
- int i;\r
-\r
- for (i = 0; i < 4; i++) {\r
- *d-- = *p++;\r
- }\r
- memcpy(&x, buf, 4);\r
- }\r
- else {\r
- memcpy(&x, p, 4);\r
- }\r
-\r
- return x;\r
- }\r
-}\r
-\r
-double\r
-_PyFloat_Unpack8(const unsigned char *p, int le)\r
-{\r
- if (double_format == unknown_format) {\r
- unsigned char sign;\r
- int e;\r
- unsigned int fhi, flo;\r
- double x;\r
- int incr = 1;\r
-\r
- if (le) {\r
- p += 7;\r
- incr = -1;\r
- }\r
-\r
- /* First byte */\r
- sign = (*p >> 7) & 1;\r
- e = (*p & 0x7F) << 4;\r
-\r
- p += incr;\r
-\r
- /* Second byte */\r
- e |= (*p >> 4) & 0xF;\r
- fhi = (*p & 0xF) << 24;\r
- p += incr;\r
-\r
- if (e == 2047) {\r
- PyErr_SetString(\r
- PyExc_ValueError,\r
- "can't unpack IEEE 754 special value "\r
- "on non-IEEE platform");\r
- return -1.0;\r
- }\r
-\r
- /* Third byte */\r
- fhi |= *p << 16;\r
- p += incr;\r
-\r
- /* Fourth byte */\r
- fhi |= *p << 8;\r
- p += incr;\r
-\r
- /* Fifth byte */\r
- fhi |= *p;\r
- p += incr;\r
-\r
- /* Sixth byte */\r
- flo = *p << 16;\r
- p += incr;\r
-\r
- /* Seventh byte */\r
- flo |= *p << 8;\r
- p += incr;\r
-\r
- /* Eighth byte */\r
- flo |= *p;\r
-\r
- x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */\r
- x /= 268435456.0; /* 2**28 */\r
-\r
- if (e == 0)\r
- e = -1022;\r
- else {\r
- x += 1.0;\r
- e -= 1023;\r
- }\r
- x = ldexp(x, e);\r
-\r
- if (sign)\r
- x = -x;\r
-\r
- return x;\r
- }\r
- else {\r
- double x;\r
-\r
- if ((double_format == ieee_little_endian_format && !le)\r
- || (double_format == ieee_big_endian_format && le)) {\r
- char buf[8];\r
- char *d = &buf[7];\r
- int i;\r
-\r
- for (i = 0; i < 8; i++) {\r
- *d-- = *p++;\r
- }\r
- memcpy(&x, buf, 8);\r
- }\r
- else {\r
- memcpy(&x, p, 8);\r
- }\r
-\r
- return x;\r
- }\r
-}\r