LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/python3/Objects - floatobject.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 79 914 8.6 %
Date: 2012-12-17 Functions: 8 47 17.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : 
       2             : /* Float object implementation */
       3             : 
       4             : /* XXX There should be overflow checks here, but it's hard to check
       5             :    for any kind of float exception without losing portability. */
       6             : 
       7             : #include "Python.h"
       8             : 
       9             : #include <ctype.h>
      10             : #include <float.h>
      11             : 
      12             : #undef MAX
      13             : #undef MIN
      14             : #define MAX(x, y) ((x) < (y) ? (y) : (x))
      15             : #define MIN(x, y) ((x) < (y) ? (x) : (y))
      16             : 
      17             : 
      18             : /* Special free list
      19             :    free_list is a singly-linked list of available PyFloatObjects, linked
      20             :    via abuse of their ob_type members.
      21             : */
      22             : 
      23             : #ifndef PyFloat_MAXFREELIST
      24             : #define PyFloat_MAXFREELIST    100
      25             : #endif
      26             : static int numfree = 0;
      27             : static PyFloatObject *free_list = NULL;
      28             : 
      29             : double
      30           0 : PyFloat_GetMax(void)
      31             : {
      32           0 :     return DBL_MAX;
      33             : }
      34             : 
      35             : double
      36           0 : PyFloat_GetMin(void)
      37             : {
      38           0 :     return DBL_MIN;
      39             : }
      40             : 
      41             : static PyTypeObject FloatInfoType;
      42             : 
      43             : PyDoc_STRVAR(floatinfo__doc__,
      44             : "sys.float_info\n\
      45             : \n\
      46             : A structseq holding information about the float type. It contains low level\n\
      47             : information about the precision and internal representation. Please study\n\
      48             : your system's :file:`float.h` for more information.");
      49             : 
      50             : static PyStructSequence_Field floatinfo_fields[] = {
      51             :     {"max",             "DBL_MAX -- maximum representable finite float"},
      52             :     {"max_exp",         "DBL_MAX_EXP -- maximum int e such that radix**(e-1) "
      53             :                     "is representable"},
      54             :     {"max_10_exp",      "DBL_MAX_10_EXP -- maximum int e such that 10**e "
      55             :                     "is representable"},
      56             :     {"min",             "DBL_MIN -- Minimum positive normalizer float"},
      57             :     {"min_exp",         "DBL_MIN_EXP -- minimum int e such that radix**(e-1) "
      58             :                     "is a normalized float"},
      59             :     {"min_10_exp",      "DBL_MIN_10_EXP -- minimum int e such that 10**e is "
      60             :                     "a normalized"},
      61             :     {"dig",             "DBL_DIG -- digits"},
      62             :     {"mant_dig",        "DBL_MANT_DIG -- mantissa digits"},
      63             :     {"epsilon",         "DBL_EPSILON -- Difference between 1 and the next "
      64             :                     "representable float"},
      65             :     {"radix",           "FLT_RADIX -- radix of exponent"},
      66             :     {"rounds",          "FLT_ROUNDS -- addition rounds"},
      67             :     {0}
      68             : };
      69             : 
      70             : static PyStructSequence_Desc floatinfo_desc = {
      71             :     "sys.float_info",           /* name */
      72             :     floatinfo__doc__,           /* doc */
      73             :     floatinfo_fields,           /* fields */
      74             :     11
      75             : };
      76             : 
      77             : PyObject *
      78           1 : PyFloat_GetInfo(void)
      79             : {
      80             :     PyObject* floatinfo;
      81           1 :     int pos = 0;
      82             : 
      83           1 :     floatinfo = PyStructSequence_New(&FloatInfoType);
      84           1 :     if (floatinfo == NULL) {
      85           0 :         return NULL;
      86             :     }
      87             : 
      88             : #define SetIntFlag(flag) \
      89             :     PyStructSequence_SET_ITEM(floatinfo, pos++, PyLong_FromLong(flag))
      90             : #define SetDblFlag(flag) \
      91             :     PyStructSequence_SET_ITEM(floatinfo, pos++, PyFloat_FromDouble(flag))
      92             : 
      93           1 :     SetDblFlag(DBL_MAX);
      94           1 :     SetIntFlag(DBL_MAX_EXP);
      95           1 :     SetIntFlag(DBL_MAX_10_EXP);
      96           1 :     SetDblFlag(DBL_MIN);
      97           1 :     SetIntFlag(DBL_MIN_EXP);
      98           1 :     SetIntFlag(DBL_MIN_10_EXP);
      99           1 :     SetIntFlag(DBL_DIG);
     100           1 :     SetIntFlag(DBL_MANT_DIG);
     101           1 :     SetDblFlag(DBL_EPSILON);
     102           1 :     SetIntFlag(FLT_RADIX);
     103           1 :     SetIntFlag(FLT_ROUNDS);
     104             : #undef SetIntFlag
     105             : #undef SetDblFlag
     106             : 
     107           1 :     if (PyErr_Occurred()) {
     108           0 :         Py_CLEAR(floatinfo);
     109           0 :         return NULL;
     110             :     }
     111           1 :     return floatinfo;
     112             : }
     113             : 
     114             : PyObject *
     115         977 : PyFloat_FromDouble(double fval)
     116             : {
     117         977 :     register PyFloatObject *op = free_list;
     118         977 :     if (op != NULL) {
     119         957 :         free_list = (PyFloatObject *) Py_TYPE(op);
     120         957 :         numfree--;
     121             :     } else {
     122          20 :         op = (PyFloatObject*) PyObject_MALLOC(sizeof(PyFloatObject));
     123          20 :         if (!op)
     124           0 :             return PyErr_NoMemory();
     125             :     }
     126             :     /* Inline PyObject_New */
     127         977 :     PyObject_INIT(op, &PyFloat_Type);
     128         977 :     op->ob_fval = fval;
     129         977 :     return (PyObject *) op;
     130             : }
     131             : 
     132             : PyObject *
     133           0 : PyFloat_FromString(PyObject *v)
     134             : {
     135             :     const char *s, *last, *end;
     136             :     double x;
     137           0 :     PyObject *s_buffer = NULL;
     138             :     Py_ssize_t len;
     139           0 :     PyObject *result = NULL;
     140             : 
     141           0 :     if (PyUnicode_Check(v)) {
     142           0 :         s_buffer = _PyUnicode_TransformDecimalAndSpaceToASCII(v);
     143           0 :         if (s_buffer == NULL)
     144           0 :             return NULL;
     145           0 :         s = PyUnicode_AsUTF8AndSize(s_buffer, &len);
     146           0 :         if (s == NULL) {
     147           0 :             Py_DECREF(s_buffer);
     148           0 :             return NULL;
     149             :         }
     150             :     }
     151           0 :     else if (PyObject_AsCharBuffer(v, &s, &len)) {
     152           0 :         PyErr_SetString(PyExc_TypeError,
     153             :             "float() argument must be a string or a number");
     154           0 :         return NULL;
     155             :     }
     156           0 :     last = s + len;
     157             :     /* strip space */
     158           0 :     while (s < last && Py_ISSPACE(*s))
     159           0 :         s++;
     160           0 :     while (s < last - 1 && Py_ISSPACE(last[-1]))
     161           0 :         last--;
     162             :     /* We don't care about overflow or underflow.  If the platform
     163             :      * supports them, infinities and signed zeroes (on underflow) are
     164             :      * fine. */
     165           0 :     x = PyOS_string_to_double(s, (char **)&end, NULL);
     166           0 :     if (end != last) {
     167           0 :         PyErr_Format(PyExc_ValueError,
     168             :                      "could not convert string to float: "
     169             :                      "%R", v);
     170           0 :         result = NULL;
     171             :     }
     172           0 :     else if (x == -1.0 && PyErr_Occurred())
     173           0 :         result = NULL;
     174             :     else
     175           0 :         result = PyFloat_FromDouble(x);
     176             : 
     177           0 :     Py_XDECREF(s_buffer);
     178           0 :     return result;
     179             : }
     180             : 
     181             : static void
     182         961 : float_dealloc(PyFloatObject *op)
     183             : {
     184         961 :     if (PyFloat_CheckExact(op)) {
     185         961 :         if (numfree >= PyFloat_MAXFREELIST)  {
     186           0 :             PyObject_FREE(op);
     187         961 :             return;
     188             :         }
     189         961 :         numfree++;
     190         961 :         Py_TYPE(op) = (struct _typeobject *)free_list;
     191         961 :         free_list = op;
     192             :     }
     193             :     else
     194           0 :         Py_TYPE(op)->tp_free((PyObject *)op);
     195             : }
     196             : 
     197             : double
     198          90 : PyFloat_AsDouble(PyObject *op)
     199             : {
     200             :     PyNumberMethods *nb;
     201             :     PyFloatObject *fo;
     202             :     double val;
     203             : 
     204          90 :     if (op && PyFloat_Check(op))
     205          90 :         return PyFloat_AS_DOUBLE((PyFloatObject*) op);
     206             : 
     207           0 :     if (op == NULL) {
     208           0 :         PyErr_BadArgument();
     209           0 :         return -1;
     210             :     }
     211             : 
     212           0 :     if ((nb = Py_TYPE(op)->tp_as_number) == NULL || nb->nb_float == NULL) {
     213           0 :         PyErr_SetString(PyExc_TypeError, "a float is required");
     214           0 :         return -1;
     215             :     }
     216             : 
     217           0 :     fo = (PyFloatObject*) (*nb->nb_float) (op);
     218           0 :     if (fo == NULL)
     219           0 :         return -1;
     220           0 :     if (!PyFloat_Check(fo)) {
     221           0 :         PyErr_SetString(PyExc_TypeError,
     222             :                         "nb_float should return float object");
     223           0 :         return -1;
     224             :     }
     225             : 
     226           0 :     val = PyFloat_AS_DOUBLE(fo);
     227           0 :     Py_DECREF(fo);
     228             : 
     229           0 :     return val;
     230             : }
     231             : 
     232             : /* Macro and helper that convert PyObject obj to a C double and store
     233             :    the value in dbl.  If conversion to double raises an exception, obj is
     234             :    set to NULL, and the function invoking this macro returns NULL.  If
     235             :    obj is not of float, int or long type, Py_NotImplemented is incref'ed,
     236             :    stored in obj, and returned from the function invoking this macro.
     237             : */
     238             : #define CONVERT_TO_DOUBLE(obj, dbl)                     \
     239             :     if (PyFloat_Check(obj))                             \
     240             :         dbl = PyFloat_AS_DOUBLE(obj);                   \
     241             :     else if (convert_to_double(&(obj), &(dbl)) < 0)     \
     242             :         return obj;
     243             : 
     244             : /* Methods */
     245             : 
     246             : static int
     247           0 : convert_to_double(PyObject **v, double *dbl)
     248             : {
     249           0 :     register PyObject *obj = *v;
     250             : 
     251           0 :     if (PyLong_Check(obj)) {
     252           0 :         *dbl = PyLong_AsDouble(obj);
     253           0 :         if (*dbl == -1.0 && PyErr_Occurred()) {
     254           0 :             *v = NULL;
     255           0 :             return -1;
     256             :         }
     257             :     }
     258             :     else {
     259           0 :         Py_INCREF(Py_NotImplemented);
     260           0 :         *v = Py_NotImplemented;
     261           0 :         return -1;
     262             :     }
     263           0 :     return 0;
     264             : }
     265             : 
     266             : static PyObject *
     267           0 : float_repr(PyFloatObject *v)
     268             : {
     269             :     PyObject *result;
     270             :     char *buf;
     271             : 
     272           0 :     buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v),
     273             :                                 'r', 0,
     274             :                                 Py_DTSF_ADD_DOT_0,
     275             :                                 NULL);
     276           0 :     if (!buf)
     277           0 :         return PyErr_NoMemory();
     278           0 :     result = _PyUnicode_FromASCII(buf, strlen(buf));
     279           0 :     PyMem_Free(buf);
     280           0 :     return result;
     281             : }
     282             : 
     283             : /* Comparison is pretty much a nightmare.  When comparing float to float,
     284             :  * we do it as straightforwardly (and long-windedly) as conceivable, so
     285             :  * that, e.g., Python x == y delivers the same result as the platform
     286             :  * C x == y when x and/or y is a NaN.
     287             :  * When mixing float with an integer type, there's no good *uniform* approach.
     288             :  * Converting the double to an integer obviously doesn't work, since we
     289             :  * may lose info from fractional bits.  Converting the integer to a double
     290             :  * also has two failure modes:  (1) a long int may trigger overflow (too
     291             :  * large to fit in the dynamic range of a C double); (2) even a C long may have
     292             :  * more bits than fit in a C double (e.g., on a a 64-bit box long may have
     293             :  * 63 bits of precision, but a C double probably has only 53), and then
     294             :  * we can falsely claim equality when low-order integer bits are lost by
     295             :  * coercion to double.  So this part is painful too.
     296             :  */
     297             : 
     298             : static PyObject*
     299         196 : float_richcompare(PyObject *v, PyObject *w, int op)
     300             : {
     301             :     double i, j;
     302         196 :     int r = 0;
     303             : 
     304             :     assert(PyFloat_Check(v));
     305         196 :     i = PyFloat_AS_DOUBLE(v);
     306             : 
     307             :     /* Switch on the type of w.  Set i and j to doubles to be compared,
     308             :      * and op to the richcomp to use.
     309             :      */
     310         196 :     if (PyFloat_Check(w))
     311         185 :         j = PyFloat_AS_DOUBLE(w);
     312             : 
     313          11 :     else if (!Py_IS_FINITE(i)) {
     314           0 :         if (PyLong_Check(w))
     315             :             /* If i is an infinity, its magnitude exceeds any
     316             :              * finite integer, so it doesn't matter which int we
     317             :              * compare i with.  If i is a NaN, similarly.
     318             :              */
     319           0 :             j = 0.0;
     320             :         else
     321           0 :             goto Unimplemented;
     322             :     }
     323             : 
     324          11 :     else if (PyLong_Check(w)) {
     325          11 :         int vsign = i == 0.0 ? 0 : i < 0.0 ? -1 : 1;
     326          11 :         int wsign = _PyLong_Sign(w);
     327             :         size_t nbits;
     328             :         int exponent;
     329             : 
     330          11 :         if (vsign != wsign) {
     331             :             /* Magnitudes are irrelevant -- the signs alone
     332             :              * determine the outcome.
     333             :              */
     334          11 :             i = (double)vsign;
     335          11 :             j = (double)wsign;
     336             :             goto Compare;
     337             :         }
     338             :         /* The signs are the same. */
     339             :         /* Convert w to a double if it fits.  In particular, 0 fits. */
     340           0 :         nbits = _PyLong_NumBits(w);
     341           0 :         if (nbits == (size_t)-1 && PyErr_Occurred()) {
     342             :             /* This long is so large that size_t isn't big enough
     343             :              * to hold the # of bits.  Replace with little doubles
     344             :              * that give the same outcome -- w is so large that
     345             :              * its magnitude must exceed the magnitude of any
     346             :              * finite float.
     347             :              */
     348           0 :             PyErr_Clear();
     349           0 :             i = (double)vsign;
     350             :             assert(wsign != 0);
     351           0 :             j = wsign * 2.0;
     352             :             goto Compare;
     353             :         }
     354           0 :         if (nbits <= 48) {
     355           0 :             j = PyLong_AsDouble(w);
     356             :             /* It's impossible that <= 48 bits overflowed. */
     357             :             assert(j != -1.0 || ! PyErr_Occurred());
     358             :             goto Compare;
     359             :         }
     360             :         assert(wsign != 0); /* else nbits was 0 */
     361             :         assert(vsign != 0); /* if vsign were 0, then since wsign is
     362             :                              * not 0, we would have taken the
     363             :                              * vsign != wsign branch at the start */
     364             :         /* We want to work with non-negative numbers. */
     365           0 :         if (vsign < 0) {
     366             :             /* "Multiply both sides" by -1; this also swaps the
     367             :              * comparator.
     368             :              */
     369           0 :             i = -i;
     370           0 :             op = _Py_SwappedOp[op];
     371             :         }
     372             :         assert(i > 0.0);
     373           0 :         (void) frexp(i, &exponent);
     374             :         /* exponent is the # of bits in v before the radix point;
     375             :          * we know that nbits (the # of bits in w) > 48 at this point
     376             :          */
     377           0 :         if (exponent < 0 || (size_t)exponent < nbits) {
     378           0 :             i = 1.0;
     379           0 :             j = 2.0;
     380             :             goto Compare;
     381             :         }
     382           0 :         if ((size_t)exponent > nbits) {
     383           0 :             i = 2.0;
     384           0 :             j = 1.0;
     385             :             goto Compare;
     386             :         }
     387             :         /* v and w have the same number of bits before the radix
     388             :          * point.  Construct two longs that have the same comparison
     389             :          * outcome.
     390             :          */
     391             :         {
     392             :             double fracpart;
     393             :             double intpart;
     394           0 :             PyObject *result = NULL;
     395           0 :             PyObject *one = NULL;
     396           0 :             PyObject *vv = NULL;
     397           0 :             PyObject *ww = w;
     398             : 
     399           0 :             if (wsign < 0) {
     400           0 :                 ww = PyNumber_Negative(w);
     401           0 :                 if (ww == NULL)
     402           0 :                     goto Error;
     403             :             }
     404             :             else
     405           0 :                 Py_INCREF(ww);
     406             : 
     407           0 :             fracpart = modf(i, &intpart);
     408           0 :             vv = PyLong_FromDouble(intpart);
     409           0 :             if (vv == NULL)
     410           0 :                 goto Error;
     411             : 
     412           0 :             if (fracpart != 0.0) {
     413             :                 /* Shift left, and or a 1 bit into vv
     414             :                  * to represent the lost fraction.
     415             :                  */
     416             :                 PyObject *temp;
     417             : 
     418           0 :                 one = PyLong_FromLong(1);
     419           0 :                 if (one == NULL)
     420           0 :                     goto Error;
     421             : 
     422           0 :                 temp = PyNumber_Lshift(ww, one);
     423           0 :                 if (temp == NULL)
     424           0 :                     goto Error;
     425           0 :                 Py_DECREF(ww);
     426           0 :                 ww = temp;
     427             : 
     428           0 :                 temp = PyNumber_Lshift(vv, one);
     429           0 :                 if (temp == NULL)
     430           0 :                     goto Error;
     431           0 :                 Py_DECREF(vv);
     432           0 :                 vv = temp;
     433             : 
     434           0 :                 temp = PyNumber_Or(vv, one);
     435           0 :                 if (temp == NULL)
     436           0 :                     goto Error;
     437           0 :                 Py_DECREF(vv);
     438           0 :                 vv = temp;
     439             :             }
     440             : 
     441           0 :             r = PyObject_RichCompareBool(vv, ww, op);
     442           0 :             if (r < 0)
     443           0 :                 goto Error;
     444           0 :             result = PyBool_FromLong(r);
     445             :          Error:
     446           0 :             Py_XDECREF(vv);
     447           0 :             Py_XDECREF(ww);
     448           0 :             Py_XDECREF(one);
     449           0 :             return result;
     450             :         }
     451             :     } /* else if (PyLong_Check(w)) */
     452             : 
     453             :     else        /* w isn't float, int, or long */
     454           0 :         goto Unimplemented;
     455             : 
     456             :  Compare:
     457             :     PyFPE_START_PROTECT("richcompare", return NULL)
     458         196 :     switch (op) {
     459             :     case Py_EQ:
     460           0 :         r = i == j;
     461           0 :         break;
     462             :     case Py_NE:
     463         196 :         r = i != j;
     464         196 :         break;
     465             :     case Py_LE:
     466           0 :         r = i <= j;
     467           0 :         break;
     468             :     case Py_GE:
     469           0 :         r = i >= j;
     470           0 :         break;
     471             :     case Py_LT:
     472           0 :         r = i < j;
     473           0 :         break;
     474             :     case Py_GT:
     475           0 :         r = i > j;
     476           0 :         break;
     477             :     }
     478             :     PyFPE_END_PROTECT(r)
     479         196 :     return PyBool_FromLong(r);
     480             : 
     481             :  Unimplemented:
     482           0 :     Py_RETURN_NOTIMPLEMENTED;
     483             : }
     484             : 
     485             : static Py_hash_t
     486           0 : float_hash(PyFloatObject *v)
     487             : {
     488           0 :     return _Py_HashDouble(v->ob_fval);
     489             : }
     490             : 
     491             : static PyObject *
     492           0 : float_add(PyObject *v, PyObject *w)
     493             : {
     494             :     double a,b;
     495           0 :     CONVERT_TO_DOUBLE(v, a);
     496           0 :     CONVERT_TO_DOUBLE(w, b);
     497             :     PyFPE_START_PROTECT("add", return 0)
     498           0 :     a = a + b;
     499             :     PyFPE_END_PROTECT(a)
     500           0 :     return PyFloat_FromDouble(a);
     501             : }
     502             : 
     503             : static PyObject *
     504           0 : float_sub(PyObject *v, PyObject *w)
     505             : {
     506             :     double a,b;
     507           0 :     CONVERT_TO_DOUBLE(v, a);
     508           0 :     CONVERT_TO_DOUBLE(w, b);
     509             :     PyFPE_START_PROTECT("subtract", return 0)
     510           0 :     a = a - b;
     511             :     PyFPE_END_PROTECT(a)
     512           0 :     return PyFloat_FromDouble(a);
     513             : }
     514             : 
     515             : static PyObject *
     516           0 : float_mul(PyObject *v, PyObject *w)
     517             : {
     518             :     double a,b;
     519           0 :     CONVERT_TO_DOUBLE(v, a);
     520           0 :     CONVERT_TO_DOUBLE(w, b);
     521             :     PyFPE_START_PROTECT("multiply", return 0)
     522           0 :     a = a * b;
     523             :     PyFPE_END_PROTECT(a)
     524           0 :     return PyFloat_FromDouble(a);
     525             : }
     526             : 
     527             : static PyObject *
     528           0 : float_div(PyObject *v, PyObject *w)
     529             : {
     530             :     double a,b;
     531           0 :     CONVERT_TO_DOUBLE(v, a);
     532           0 :     CONVERT_TO_DOUBLE(w, b);
     533           0 :     if (b == 0.0) {
     534           0 :         PyErr_SetString(PyExc_ZeroDivisionError,
     535             :                         "float division by zero");
     536           0 :         return NULL;
     537             :     }
     538             :     PyFPE_START_PROTECT("divide", return 0)
     539           0 :     a = a / b;
     540             :     PyFPE_END_PROTECT(a)
     541           0 :     return PyFloat_FromDouble(a);
     542             : }
     543             : 
     544             : static PyObject *
     545           0 : float_rem(PyObject *v, PyObject *w)
     546             : {
     547             :     double vx, wx;
     548             :     double mod;
     549           0 :     CONVERT_TO_DOUBLE(v, vx);
     550           0 :     CONVERT_TO_DOUBLE(w, wx);
     551           0 :     if (wx == 0.0) {
     552           0 :         PyErr_SetString(PyExc_ZeroDivisionError,
     553             :                         "float modulo");
     554           0 :         return NULL;
     555             :     }
     556             :     PyFPE_START_PROTECT("modulo", return 0)
     557           0 :     mod = fmod(vx, wx);
     558           0 :     if (mod) {
     559             :         /* ensure the remainder has the same sign as the denominator */
     560           0 :         if ((wx < 0) != (mod < 0)) {
     561           0 :             mod += wx;
     562             :         }
     563             :     }
     564             :     else {
     565             :         /* the remainder is zero, and in the presence of signed zeroes
     566             :            fmod returns different results across platforms; ensure
     567             :            it has the same sign as the denominator. */
     568           0 :         mod = copysign(0.0, wx);
     569             :     }
     570             :     PyFPE_END_PROTECT(mod)
     571           0 :     return PyFloat_FromDouble(mod);
     572             : }
     573             : 
     574             : static PyObject *
     575           0 : float_divmod(PyObject *v, PyObject *w)
     576             : {
     577             :     double vx, wx;
     578             :     double div, mod, floordiv;
     579           0 :     CONVERT_TO_DOUBLE(v, vx);
     580           0 :     CONVERT_TO_DOUBLE(w, wx);
     581           0 :     if (wx == 0.0) {
     582           0 :         PyErr_SetString(PyExc_ZeroDivisionError, "float divmod()");
     583           0 :         return NULL;
     584             :     }
     585             :     PyFPE_START_PROTECT("divmod", return 0)
     586           0 :     mod = fmod(vx, wx);
     587             :     /* fmod is typically exact, so vx-mod is *mathematically* an
     588             :        exact multiple of wx.  But this is fp arithmetic, and fp
     589             :        vx - mod is an approximation; the result is that div may
     590             :        not be an exact integral value after the division, although
     591             :        it will always be very close to one.
     592             :     */
     593           0 :     div = (vx - mod) / wx;
     594           0 :     if (mod) {
     595             :         /* ensure the remainder has the same sign as the denominator */
     596           0 :         if ((wx < 0) != (mod < 0)) {
     597           0 :             mod += wx;
     598           0 :             div -= 1.0;
     599             :         }
     600             :     }
     601             :     else {
     602             :         /* the remainder is zero, and in the presence of signed zeroes
     603             :            fmod returns different results across platforms; ensure
     604             :            it has the same sign as the denominator. */
     605           0 :         mod = copysign(0.0, wx);
     606             :     }
     607             :     /* snap quotient to nearest integral value */
     608           0 :     if (div) {
     609           0 :         floordiv = floor(div);
     610           0 :         if (div - floordiv > 0.5)
     611           0 :             floordiv += 1.0;
     612             :     }
     613             :     else {
     614             :         /* div is zero - get the same sign as the true quotient */
     615           0 :         floordiv = copysign(0.0, vx / wx); /* zero w/ sign of vx/wx */
     616             :     }
     617             :     PyFPE_END_PROTECT(floordiv)
     618           0 :     return Py_BuildValue("(dd)", floordiv, mod);
     619             : }
     620             : 
     621             : static PyObject *
     622           0 : float_floor_div(PyObject *v, PyObject *w)
     623             : {
     624             :     PyObject *t, *r;
     625             : 
     626           0 :     t = float_divmod(v, w);
     627           0 :     if (t == NULL || t == Py_NotImplemented)
     628           0 :         return t;
     629             :     assert(PyTuple_CheckExact(t));
     630           0 :     r = PyTuple_GET_ITEM(t, 0);
     631           0 :     Py_INCREF(r);
     632           0 :     Py_DECREF(t);
     633           0 :     return r;
     634             : }
     635             : 
     636             : /* determine whether x is an odd integer or not;  assumes that
     637             :    x is not an infinity or nan. */
     638             : #define DOUBLE_IS_ODD_INTEGER(x) (fmod(fabs(x), 2.0) == 1.0)
     639             : 
     640             : static PyObject *
     641           0 : float_pow(PyObject *v, PyObject *w, PyObject *z)
     642             : {
     643             :     double iv, iw, ix;
     644           0 :     int negate_result = 0;
     645             : 
     646           0 :     if ((PyObject *)z != Py_None) {
     647           0 :         PyErr_SetString(PyExc_TypeError, "pow() 3rd argument not "
     648             :             "allowed unless all arguments are integers");
     649           0 :         return NULL;
     650             :     }
     651             : 
     652           0 :     CONVERT_TO_DOUBLE(v, iv);
     653           0 :     CONVERT_TO_DOUBLE(w, iw);
     654             : 
     655             :     /* Sort out special cases here instead of relying on pow() */
     656           0 :     if (iw == 0) {              /* v**0 is 1, even 0**0 */
     657           0 :         return PyFloat_FromDouble(1.0);
     658             :     }
     659           0 :     if (Py_IS_NAN(iv)) {        /* nan**w = nan, unless w == 0 */
     660           0 :         return PyFloat_FromDouble(iv);
     661             :     }
     662           0 :     if (Py_IS_NAN(iw)) {        /* v**nan = nan, unless v == 1; 1**nan = 1 */
     663           0 :         return PyFloat_FromDouble(iv == 1.0 ? 1.0 : iw);
     664             :     }
     665           0 :     if (Py_IS_INFINITY(iw)) {
     666             :         /* v**inf is: 0.0 if abs(v) < 1; 1.0 if abs(v) == 1; inf if
     667             :          *     abs(v) > 1 (including case where v infinite)
     668             :          *
     669             :          * v**-inf is: inf if abs(v) < 1; 1.0 if abs(v) == 1; 0.0 if
     670             :          *     abs(v) > 1 (including case where v infinite)
     671             :          */
     672           0 :         iv = fabs(iv);
     673           0 :         if (iv == 1.0)
     674           0 :             return PyFloat_FromDouble(1.0);
     675           0 :         else if ((iw > 0.0) == (iv > 1.0))
     676           0 :             return PyFloat_FromDouble(fabs(iw)); /* return inf */
     677             :         else
     678           0 :             return PyFloat_FromDouble(0.0);
     679             :     }
     680           0 :     if (Py_IS_INFINITY(iv)) {
     681             :         /* (+-inf)**w is: inf for w positive, 0 for w negative; in
     682             :          *     both cases, we need to add the appropriate sign if w is
     683             :          *     an odd integer.
     684             :          */
     685           0 :         int iw_is_odd = DOUBLE_IS_ODD_INTEGER(iw);
     686           0 :         if (iw > 0.0)
     687           0 :             return PyFloat_FromDouble(iw_is_odd ? iv : fabs(iv));
     688             :         else
     689           0 :             return PyFloat_FromDouble(iw_is_odd ?
     690           0 :                                       copysign(0.0, iv) : 0.0);
     691             :     }
     692           0 :     if (iv == 0.0) {  /* 0**w is: 0 for w positive, 1 for w zero
     693             :                          (already dealt with above), and an error
     694             :                          if w is negative. */
     695           0 :         int iw_is_odd = DOUBLE_IS_ODD_INTEGER(iw);
     696           0 :         if (iw < 0.0) {
     697           0 :             PyErr_SetString(PyExc_ZeroDivisionError,
     698             :                             "0.0 cannot be raised to a "
     699             :                             "negative power");
     700           0 :             return NULL;
     701             :         }
     702             :         /* use correct sign if iw is odd */
     703           0 :         return PyFloat_FromDouble(iw_is_odd ? iv : 0.0);
     704             :     }
     705             : 
     706           0 :     if (iv < 0.0) {
     707             :         /* Whether this is an error is a mess, and bumps into libm
     708             :          * bugs so we have to figure it out ourselves.
     709             :          */
     710           0 :         if (iw != floor(iw)) {
     711             :             /* Negative numbers raised to fractional powers
     712             :              * become complex.
     713             :              */
     714           0 :             return PyComplex_Type.tp_as_number->nb_power(v, w, z);
     715             :         }
     716             :         /* iw is an exact integer, albeit perhaps a very large
     717             :          * one.  Replace iv by its absolute value and remember
     718             :          * to negate the pow result if iw is odd.
     719             :          */
     720           0 :         iv = -iv;
     721           0 :         negate_result = DOUBLE_IS_ODD_INTEGER(iw);
     722             :     }
     723             : 
     724           0 :     if (iv == 1.0) { /* 1**w is 1, even 1**inf and 1**nan */
     725             :         /* (-1) ** large_integer also ends up here.  Here's an
     726             :          * extract from the comments for the previous
     727             :          * implementation explaining why this special case is
     728             :          * necessary:
     729             :          *
     730             :          * -1 raised to an exact integer should never be exceptional.
     731             :          * Alas, some libms (chiefly glibc as of early 2003) return
     732             :          * NaN and set EDOM on pow(-1, large_int) if the int doesn't
     733             :          * happen to be representable in a *C* integer.  That's a
     734             :          * bug.
     735             :          */
     736           0 :         return PyFloat_FromDouble(negate_result ? -1.0 : 1.0);
     737             :     }
     738             : 
     739             :     /* Now iv and iw are finite, iw is nonzero, and iv is
     740             :      * positive and not equal to 1.0.  We finally allow
     741             :      * the platform pow to step in and do the rest.
     742             :      */
     743           0 :     errno = 0;
     744             :     PyFPE_START_PROTECT("pow", return NULL)
     745           0 :     ix = pow(iv, iw);
     746             :     PyFPE_END_PROTECT(ix)
     747           0 :     Py_ADJUST_ERANGE1(ix);
     748           0 :     if (negate_result)
     749           0 :         ix = -ix;
     750             : 
     751           0 :     if (errno != 0) {
     752             :         /* We don't expect any errno value other than ERANGE, but
     753             :          * the range of libm bugs appears unbounded.
     754             :          */
     755           0 :         PyErr_SetFromErrno(errno == ERANGE ? PyExc_OverflowError :
     756             :                              PyExc_ValueError);
     757           0 :         return NULL;
     758             :     }
     759           0 :     return PyFloat_FromDouble(ix);
     760             : }
     761             : 
     762             : #undef DOUBLE_IS_ODD_INTEGER
     763             : 
     764             : static PyObject *
     765           0 : float_neg(PyFloatObject *v)
     766             : {
     767           0 :     return PyFloat_FromDouble(-v->ob_fval);
     768             : }
     769             : 
     770             : static PyObject *
     771           0 : float_abs(PyFloatObject *v)
     772             : {
     773           0 :     return PyFloat_FromDouble(fabs(v->ob_fval));
     774             : }
     775             : 
     776             : static int
     777           0 : float_bool(PyFloatObject *v)
     778             : {
     779           0 :     return v->ob_fval != 0.0;
     780             : }
     781             : 
     782             : static PyObject *
     783           0 : float_is_integer(PyObject *v)
     784             : {
     785           0 :     double x = PyFloat_AsDouble(v);
     786             :     PyObject *o;
     787             : 
     788           0 :     if (x == -1.0 && PyErr_Occurred())
     789           0 :         return NULL;
     790           0 :     if (!Py_IS_FINITE(x))
     791           0 :         Py_RETURN_FALSE;
     792           0 :     errno = 0;
     793             :     PyFPE_START_PROTECT("is_integer", return NULL)
     794           0 :     o = (floor(x) == x) ? Py_True : Py_False;
     795             :     PyFPE_END_PROTECT(x)
     796           0 :     if (errno != 0) {
     797           0 :         PyErr_SetFromErrno(errno == ERANGE ? PyExc_OverflowError :
     798             :                              PyExc_ValueError);
     799           0 :         return NULL;
     800             :     }
     801           0 :     Py_INCREF(o);
     802           0 :     return o;
     803             : }
     804             : 
     805             : #if 0
     806             : static PyObject *
     807             : float_is_inf(PyObject *v)
     808             : {
     809             :     double x = PyFloat_AsDouble(v);
     810             :     if (x == -1.0 && PyErr_Occurred())
     811             :         return NULL;
     812             :     return PyBool_FromLong((long)Py_IS_INFINITY(x));
     813             : }
     814             : 
     815             : static PyObject *
     816             : float_is_nan(PyObject *v)
     817             : {
     818             :     double x = PyFloat_AsDouble(v);
     819             :     if (x == -1.0 && PyErr_Occurred())
     820             :         return NULL;
     821             :     return PyBool_FromLong((long)Py_IS_NAN(x));
     822             : }
     823             : 
     824             : static PyObject *
     825             : float_is_finite(PyObject *v)
     826             : {
     827             :     double x = PyFloat_AsDouble(v);
     828             :     if (x == -1.0 && PyErr_Occurred())
     829             :         return NULL;
     830             :     return PyBool_FromLong((long)Py_IS_FINITE(x));
     831             : }
     832             : #endif
     833             : 
     834             : static PyObject *
     835          90 : float_trunc(PyObject *v)
     836             : {
     837          90 :     double x = PyFloat_AsDouble(v);
     838             :     double wholepart;           /* integral portion of x, rounded toward 0 */
     839             : 
     840          90 :     (void)modf(x, &wholepart);
     841             :     /* Try to get out cheap if this fits in a Python int.  The attempt
     842             :      * to cast to long must be protected, as C doesn't define what
     843             :      * happens if the double is too big to fit in a long.  Some rare
     844             :      * systems raise an exception then (RISCOS was mentioned as one,
     845             :      * and someone using a non-default option on Sun also bumped into
     846             :      * that).  Note that checking for >= and <= LONG_{MIN,MAX} would
     847             :      * still be vulnerable:  if a long has more bits of precision than
     848             :      * a double, casting MIN/MAX to double may yield an approximation,
     849             :      * and if that's rounded up, then, e.g., wholepart=LONG_MAX+1 would
     850             :      * yield true from the C expression wholepart<=LONG_MAX, despite
     851             :      * that wholepart is actually greater than LONG_MAX.
     852             :      */
     853          90 :     if (LONG_MIN < wholepart && wholepart < LONG_MAX) {
     854          90 :         const long aslong = (long)wholepart;
     855          90 :         return PyLong_FromLong(aslong);
     856             :     }
     857           0 :     return PyLong_FromDouble(wholepart);
     858             : }
     859             : 
     860             : /* double_round: rounds a finite double to the closest multiple of
     861             :    10**-ndigits; here ndigits is within reasonable bounds (typically, -308 <=
     862             :    ndigits <= 323).  Returns a Python float, or sets a Python error and
     863             :    returns NULL on failure (OverflowError and memory errors are possible). */
     864             : 
     865             : #ifndef PY_NO_SHORT_FLOAT_REPR
     866             : /* version of double_round that uses the correctly-rounded string<->double
     867             :    conversions from Python/dtoa.c */
     868             : 
     869             : static PyObject *
     870           0 : double_round(double x, int ndigits) {
     871             : 
     872             :     double rounded;
     873           0 :     Py_ssize_t buflen, mybuflen=100;
     874           0 :     char *buf, *buf_end, shortbuf[100], *mybuf=shortbuf;
     875             :     int decpt, sign;
     876           0 :     PyObject *result = NULL;
     877             :     _Py_SET_53BIT_PRECISION_HEADER;
     878             : 
     879             :     /* round to a decimal string */
     880           0 :     _Py_SET_53BIT_PRECISION_START;
     881           0 :     buf = _Py_dg_dtoa(x, 3, ndigits, &decpt, &sign, &buf_end);
     882           0 :     _Py_SET_53BIT_PRECISION_END;
     883           0 :     if (buf == NULL) {
     884           0 :         PyErr_NoMemory();
     885           0 :         return NULL;
     886             :     }
     887             : 
     888             :     /* Get new buffer if shortbuf is too small.  Space needed <= buf_end -
     889             :     buf + 8: (1 extra for '0', 1 for sign, 5 for exp, 1 for '\0').  */
     890           0 :     buflen = buf_end - buf;
     891           0 :     if (buflen + 8 > mybuflen) {
     892           0 :         mybuflen = buflen+8;
     893           0 :         mybuf = (char *)PyMem_Malloc(mybuflen);
     894           0 :         if (mybuf == NULL) {
     895           0 :             PyErr_NoMemory();
     896           0 :             goto exit;
     897             :         }
     898             :     }
     899             :     /* copy buf to mybuf, adding exponent, sign and leading 0 */
     900           0 :     PyOS_snprintf(mybuf, mybuflen, "%s0%se%d", (sign ? "-" : ""),
     901             :                   buf, decpt - (int)buflen);
     902             : 
     903             :     /* and convert the resulting string back to a double */
     904           0 :     errno = 0;
     905           0 :     _Py_SET_53BIT_PRECISION_START;
     906           0 :     rounded = _Py_dg_strtod(mybuf, NULL);
     907           0 :     _Py_SET_53BIT_PRECISION_END;
     908           0 :     if (errno == ERANGE && fabs(rounded) >= 1.)
     909           0 :         PyErr_SetString(PyExc_OverflowError,
     910             :                         "rounded value too large to represent");
     911             :     else
     912           0 :         result = PyFloat_FromDouble(rounded);
     913             : 
     914             :     /* done computing value;  now clean up */
     915           0 :     if (mybuf != shortbuf)
     916           0 :         PyMem_Free(mybuf);
     917             :   exit:
     918           0 :     _Py_dg_freedtoa(buf);
     919           0 :     return result;
     920             : }
     921             : 
     922             : #else /* PY_NO_SHORT_FLOAT_REPR */
     923             : 
     924             : /* fallback version, to be used when correctly rounded binary<->decimal
     925             :    conversions aren't available */
     926             : 
     927             : static PyObject *
     928             : double_round(double x, int ndigits) {
     929             :     double pow1, pow2, y, z;
     930             :     if (ndigits >= 0) {
     931             :         if (ndigits > 22) {
     932             :             /* pow1 and pow2 are each safe from overflow, but
     933             :                pow1*pow2 ~= pow(10.0, ndigits) might overflow */
     934             :             pow1 = pow(10.0, (double)(ndigits-22));
     935             :             pow2 = 1e22;
     936             :         }
     937             :         else {
     938             :             pow1 = pow(10.0, (double)ndigits);
     939             :             pow2 = 1.0;
     940             :         }
     941             :         y = (x*pow1)*pow2;
     942             :         /* if y overflows, then rounded value is exactly x */
     943             :         if (!Py_IS_FINITE(y))
     944             :             return PyFloat_FromDouble(x);
     945             :     }
     946             :     else {
     947             :         pow1 = pow(10.0, (double)-ndigits);
     948             :         pow2 = 1.0; /* unused; silences a gcc compiler warning */
     949             :         y = x / pow1;
     950             :     }
     951             : 
     952             :     z = round(y);
     953             :     if (fabs(y-z) == 0.5)
     954             :         /* halfway between two integers; use round-half-even */
     955             :         z = 2.0*round(y/2.0);
     956             : 
     957             :     if (ndigits >= 0)
     958             :         z = (z / pow2) / pow1;
     959             :     else
     960             :         z *= pow1;
     961             : 
     962             :     /* if computation resulted in overflow, raise OverflowError */
     963             :     if (!Py_IS_FINITE(z)) {
     964             :         PyErr_SetString(PyExc_OverflowError,
     965             :                         "overflow occurred during round");
     966             :         return NULL;
     967             :     }
     968             : 
     969             :     return PyFloat_FromDouble(z);
     970             : }
     971             : 
     972             : #endif /* PY_NO_SHORT_FLOAT_REPR */
     973             : 
     974             : /* round a Python float v to the closest multiple of 10**-ndigits */
     975             : 
     976             : static PyObject *
     977           0 : float_round(PyObject *v, PyObject *args)
     978             : {
     979             :     double x, rounded;
     980           0 :     PyObject *o_ndigits = NULL;
     981             :     Py_ssize_t ndigits;
     982             : 
     983           0 :     x = PyFloat_AsDouble(v);
     984           0 :     if (!PyArg_ParseTuple(args, "|O", &o_ndigits))
     985           0 :         return NULL;
     986           0 :     if (o_ndigits == NULL) {
     987             :         /* single-argument round: round to nearest integer */
     988           0 :         rounded = round(x);
     989           0 :         if (fabs(x-rounded) == 0.5)
     990             :             /* halfway case: round to even */
     991           0 :             rounded = 2.0*round(x/2.0);
     992           0 :         return PyLong_FromDouble(rounded);
     993             :     }
     994             : 
     995             :     /* interpret second argument as a Py_ssize_t; clips on overflow */
     996           0 :     ndigits = PyNumber_AsSsize_t(o_ndigits, NULL);
     997           0 :     if (ndigits == -1 && PyErr_Occurred())
     998           0 :         return NULL;
     999             : 
    1000             :     /* nans and infinities round to themselves */
    1001           0 :     if (!Py_IS_FINITE(x))
    1002           0 :         return PyFloat_FromDouble(x);
    1003             : 
    1004             :     /* Deal with extreme values for ndigits. For ndigits > NDIGITS_MAX, x
    1005             :        always rounds to itself.  For ndigits < NDIGITS_MIN, x always
    1006             :        rounds to +-0.0.  Here 0.30103 is an upper bound for log10(2). */
    1007             : #define NDIGITS_MAX ((int)((DBL_MANT_DIG-DBL_MIN_EXP) * 0.30103))
    1008             : #define NDIGITS_MIN (-(int)((DBL_MAX_EXP + 1) * 0.30103))
    1009           0 :     if (ndigits > NDIGITS_MAX)
    1010             :         /* return x */
    1011           0 :         return PyFloat_FromDouble(x);
    1012           0 :     else if (ndigits < NDIGITS_MIN)
    1013             :         /* return 0.0, but with sign of x */
    1014           0 :         return PyFloat_FromDouble(0.0*x);
    1015             :     else
    1016             :         /* finite x, and ndigits is not unreasonably large */
    1017           0 :         return double_round(x, (int)ndigits);
    1018             : #undef NDIGITS_MAX
    1019             : #undef NDIGITS_MIN
    1020             : }
    1021             : 
    1022             : static PyObject *
    1023           0 : float_float(PyObject *v)
    1024             : {
    1025           0 :     if (PyFloat_CheckExact(v))
    1026           0 :         Py_INCREF(v);
    1027             :     else
    1028           0 :         v = PyFloat_FromDouble(((PyFloatObject *)v)->ob_fval);
    1029           0 :     return v;
    1030             : }
    1031             : 
    1032             : /* turn ASCII hex characters into integer values and vice versa */
    1033             : 
    1034             : static char
    1035           0 : char_from_hex(int x)
    1036             : {
    1037             :     assert(0 <= x && x < 16);
    1038           0 :     return Py_hexdigits[x];
    1039             : }
    1040             : 
    1041             : static int
    1042           0 : hex_from_char(char c) {
    1043             :     int x;
    1044           0 :     switch(c) {
    1045             :     case '0':
    1046           0 :         x = 0;
    1047           0 :         break;
    1048             :     case '1':
    1049           0 :         x = 1;
    1050           0 :         break;
    1051             :     case '2':
    1052           0 :         x = 2;
    1053           0 :         break;
    1054             :     case '3':
    1055           0 :         x = 3;
    1056           0 :         break;
    1057             :     case '4':
    1058           0 :         x = 4;
    1059           0 :         break;
    1060             :     case '5':
    1061           0 :         x = 5;
    1062           0 :         break;
    1063             :     case '6':
    1064           0 :         x = 6;
    1065           0 :         break;
    1066             :     case '7':
    1067           0 :         x = 7;
    1068           0 :         break;
    1069             :     case '8':
    1070           0 :         x = 8;
    1071           0 :         break;
    1072             :     case '9':
    1073           0 :         x = 9;
    1074           0 :         break;
    1075             :     case 'a':
    1076             :     case 'A':
    1077           0 :         x = 10;
    1078           0 :         break;
    1079             :     case 'b':
    1080             :     case 'B':
    1081           0 :         x = 11;
    1082           0 :         break;
    1083             :     case 'c':
    1084             :     case 'C':
    1085           0 :         x = 12;
    1086           0 :         break;
    1087             :     case 'd':
    1088             :     case 'D':
    1089           0 :         x = 13;
    1090           0 :         break;
    1091             :     case 'e':
    1092             :     case 'E':
    1093           0 :         x = 14;
    1094           0 :         break;
    1095             :     case 'f':
    1096             :     case 'F':
    1097           0 :         x = 15;
    1098           0 :         break;
    1099             :     default:
    1100           0 :         x = -1;
    1101           0 :         break;
    1102             :     }
    1103           0 :     return x;
    1104             : }
    1105             : 
    1106             : /* convert a float to a hexadecimal string */
    1107             : 
    1108             : /* TOHEX_NBITS is DBL_MANT_DIG rounded up to the next integer
    1109             :    of the form 4k+1. */
    1110             : #define TOHEX_NBITS DBL_MANT_DIG + 3 - (DBL_MANT_DIG+2)%4
    1111             : 
    1112             : static PyObject *
    1113           0 : float_hex(PyObject *v)
    1114             : {
    1115             :     double x, m;
    1116             :     int e, shift, i, si, esign;
    1117             :     /* Space for 1+(TOHEX_NBITS-1)/4 digits, a decimal point, and the
    1118             :        trailing NUL byte. */
    1119             :     char s[(TOHEX_NBITS-1)/4+3];
    1120             : 
    1121           0 :     CONVERT_TO_DOUBLE(v, x);
    1122             : 
    1123           0 :     if (Py_IS_NAN(x) || Py_IS_INFINITY(x))
    1124           0 :         return float_repr((PyFloatObject *)v);
    1125             : 
    1126           0 :     if (x == 0.0) {
    1127           0 :         if (copysign(1.0, x) == -1.0)
    1128           0 :             return PyUnicode_FromString("-0x0.0p+0");
    1129             :         else
    1130           0 :             return PyUnicode_FromString("0x0.0p+0");
    1131             :     }
    1132             : 
    1133           0 :     m = frexp(fabs(x), &e);
    1134           0 :     shift = 1 - MAX(DBL_MIN_EXP - e, 0);
    1135           0 :     m = ldexp(m, shift);
    1136           0 :     e -= shift;
    1137             : 
    1138           0 :     si = 0;
    1139           0 :     s[si] = char_from_hex((int)m);
    1140           0 :     si++;
    1141           0 :     m -= (int)m;
    1142           0 :     s[si] = '.';
    1143           0 :     si++;
    1144           0 :     for (i=0; i < (TOHEX_NBITS-1)/4; i++) {
    1145           0 :         m *= 16.0;
    1146           0 :         s[si] = char_from_hex((int)m);
    1147           0 :         si++;
    1148           0 :         m -= (int)m;
    1149             :     }
    1150           0 :     s[si] = '\0';
    1151             : 
    1152           0 :     if (e < 0) {
    1153           0 :         esign = (int)'-';
    1154           0 :         e = -e;
    1155             :     }
    1156             :     else
    1157           0 :         esign = (int)'+';
    1158             : 
    1159           0 :     if (x < 0.0)
    1160           0 :         return PyUnicode_FromFormat("-0x%sp%c%d", s, esign, e);
    1161             :     else
    1162           0 :         return PyUnicode_FromFormat("0x%sp%c%d", s, esign, e);
    1163             : }
    1164             : 
    1165             : PyDoc_STRVAR(float_hex_doc,
    1166             : "float.hex() -> string\n\
    1167             : \n\
    1168             : Return a hexadecimal representation of a floating-point number.\n\
    1169             : >>> (-0.1).hex()\n\
    1170             : '-0x1.999999999999ap-4'\n\
    1171             : >>> 3.14159.hex()\n\
    1172             : '0x1.921f9f01b866ep+1'");
    1173             : 
    1174             : /* Convert a hexadecimal string to a float. */
    1175             : 
    1176             : static PyObject *
    1177           0 : float_fromhex(PyObject *cls, PyObject *arg)
    1178             : {
    1179             :     PyObject *result_as_float, *result;
    1180             :     double x;
    1181             :     long exp, top_exp, lsb, key_digit;
    1182             :     char *s, *coeff_start, *s_store, *coeff_end, *exp_start, *s_end;
    1183           0 :     int half_eps, digit, round_up, negate=0;
    1184             :     Py_ssize_t length, ndigits, fdigits, i;
    1185             : 
    1186             :     /*
    1187             :      * For the sake of simplicity and correctness, we impose an artificial
    1188             :      * limit on ndigits, the total number of hex digits in the coefficient
    1189             :      * The limit is chosen to ensure that, writing exp for the exponent,
    1190             :      *
    1191             :      *   (1) if exp > LONG_MAX/2 then the value of the hex string is
    1192             :      *   guaranteed to overflow (provided it's nonzero)
    1193             :      *
    1194             :      *   (2) if exp < LONG_MIN/2 then the value of the hex string is
    1195             :      *   guaranteed to underflow to 0.
    1196             :      *
    1197             :      *   (3) if LONG_MIN/2 <= exp <= LONG_MAX/2 then there's no danger of
    1198             :      *   overflow in the calculation of exp and top_exp below.
    1199             :      *
    1200             :      * More specifically, ndigits is assumed to satisfy the following
    1201             :      * inequalities:
    1202             :      *
    1203             :      *   4*ndigits <= DBL_MIN_EXP - DBL_MANT_DIG - LONG_MIN/2
    1204             :      *   4*ndigits <= LONG_MAX/2 + 1 - DBL_MAX_EXP
    1205             :      *
    1206             :      * If either of these inequalities is not satisfied, a ValueError is
    1207             :      * raised.  Otherwise, write x for the value of the hex string, and
    1208             :      * assume x is nonzero.  Then
    1209             :      *
    1210             :      *   2**(exp-4*ndigits) <= |x| < 2**(exp+4*ndigits).
    1211             :      *
    1212             :      * Now if exp > LONG_MAX/2 then:
    1213             :      *
    1214             :      *   exp - 4*ndigits >= LONG_MAX/2 + 1 - (LONG_MAX/2 + 1 - DBL_MAX_EXP)
    1215             :      *                    = DBL_MAX_EXP
    1216             :      *
    1217             :      * so |x| >= 2**DBL_MAX_EXP, which is too large to be stored in C
    1218             :      * double, so overflows.  If exp < LONG_MIN/2, then
    1219             :      *
    1220             :      *   exp + 4*ndigits <= LONG_MIN/2 - 1 + (
    1221             :      *                      DBL_MIN_EXP - DBL_MANT_DIG - LONG_MIN/2)
    1222             :      *                    = DBL_MIN_EXP - DBL_MANT_DIG - 1
    1223             :      *
    1224             :      * and so |x| < 2**(DBL_MIN_EXP-DBL_MANT_DIG-1), hence underflows to 0
    1225             :      * when converted to a C double.
    1226             :      *
    1227             :      * It's easy to show that if LONG_MIN/2 <= exp <= LONG_MAX/2 then both
    1228             :      * exp+4*ndigits and exp-4*ndigits are within the range of a long.
    1229             :      */
    1230             : 
    1231           0 :     s = _PyUnicode_AsStringAndSize(arg, &length);
    1232           0 :     if (s == NULL)
    1233           0 :         return NULL;
    1234           0 :     s_end = s + length;
    1235             : 
    1236             :     /********************
    1237             :      * Parse the string *
    1238             :      ********************/
    1239             : 
    1240             :     /* leading whitespace */
    1241           0 :     while (Py_ISSPACE(*s))
    1242           0 :         s++;
    1243             : 
    1244             :     /* infinities and nans */
    1245           0 :     x = _Py_parse_inf_or_nan(s, &coeff_end);
    1246           0 :     if (coeff_end != s) {
    1247           0 :         s = coeff_end;
    1248           0 :         goto finished;
    1249             :     }
    1250             : 
    1251             :     /* optional sign */
    1252           0 :     if (*s == '-') {
    1253           0 :         s++;
    1254           0 :         negate = 1;
    1255             :     }
    1256           0 :     else if (*s == '+')
    1257           0 :         s++;
    1258             : 
    1259             :     /* [0x] */
    1260           0 :     s_store = s;
    1261           0 :     if (*s == '0') {
    1262           0 :         s++;
    1263           0 :         if (*s == 'x' || *s == 'X')
    1264           0 :             s++;
    1265             :         else
    1266           0 :             s = s_store;
    1267             :     }
    1268             : 
    1269             :     /* coefficient: <integer> [. <fraction>] */
    1270           0 :     coeff_start = s;
    1271           0 :     while (hex_from_char(*s) >= 0)
    1272           0 :         s++;
    1273           0 :     s_store = s;
    1274           0 :     if (*s == '.') {
    1275           0 :         s++;
    1276           0 :         while (hex_from_char(*s) >= 0)
    1277           0 :             s++;
    1278           0 :         coeff_end = s-1;
    1279             :     }
    1280             :     else
    1281           0 :         coeff_end = s;
    1282             : 
    1283             :     /* ndigits = total # of hex digits; fdigits = # after point */
    1284           0 :     ndigits = coeff_end - coeff_start;
    1285           0 :     fdigits = coeff_end - s_store;
    1286           0 :     if (ndigits == 0)
    1287           0 :         goto parse_error;
    1288           0 :     if (ndigits > MIN(DBL_MIN_EXP - DBL_MANT_DIG - LONG_MIN/2,
    1289             :                       LONG_MAX/2 + 1 - DBL_MAX_EXP)/4)
    1290           0 :         goto insane_length_error;
    1291             : 
    1292             :     /* [p <exponent>] */
    1293           0 :     if (*s == 'p' || *s == 'P') {
    1294           0 :         s++;
    1295           0 :         exp_start = s;
    1296           0 :         if (*s == '-' || *s == '+')
    1297           0 :             s++;
    1298           0 :         if (!('0' <= *s && *s <= '9'))
    1299             :             goto parse_error;
    1300           0 :         s++;
    1301           0 :         while ('0' <= *s && *s <= '9')
    1302           0 :             s++;
    1303           0 :         exp = strtol(exp_start, NULL, 10);
    1304             :     }
    1305             :     else
    1306           0 :         exp = 0;
    1307             : 
    1308             : /* for 0 <= j < ndigits, HEX_DIGIT(j) gives the jth most significant digit */
    1309             : #define HEX_DIGIT(j) hex_from_char(*((j) < fdigits ?            \
    1310             :                      coeff_end-(j) :                                    \
    1311             :                      coeff_end-1-(j)))
    1312             : 
    1313             :     /*******************************************
    1314             :      * Compute rounded value of the hex string *
    1315             :      *******************************************/
    1316             : 
    1317             :     /* Discard leading zeros, and catch extreme overflow and underflow */
    1318           0 :     while (ndigits > 0 && HEX_DIGIT(ndigits-1) == 0)
    1319           0 :         ndigits--;
    1320           0 :     if (ndigits == 0 || exp < LONG_MIN/2) {
    1321           0 :         x = 0.0;
    1322           0 :         goto finished;
    1323             :     }
    1324           0 :     if (exp > LONG_MAX/2)
    1325           0 :         goto overflow_error;
    1326             : 
    1327             :     /* Adjust exponent for fractional part. */
    1328           0 :     exp = exp - 4*((long)fdigits);
    1329             : 
    1330             :     /* top_exp = 1 more than exponent of most sig. bit of coefficient */
    1331           0 :     top_exp = exp + 4*((long)ndigits - 1);
    1332           0 :     for (digit = HEX_DIGIT(ndigits-1); digit != 0; digit /= 2)
    1333           0 :         top_exp++;
    1334             : 
    1335             :     /* catch almost all nonextreme cases of overflow and underflow here */
    1336           0 :     if (top_exp < DBL_MIN_EXP - DBL_MANT_DIG) {
    1337           0 :         x = 0.0;
    1338           0 :         goto finished;
    1339             :     }
    1340           0 :     if (top_exp > DBL_MAX_EXP)
    1341           0 :         goto overflow_error;
    1342             : 
    1343             :     /* lsb = exponent of least significant bit of the *rounded* value.
    1344             :        This is top_exp - DBL_MANT_DIG unless result is subnormal. */
    1345           0 :     lsb = MAX(top_exp, (long)DBL_MIN_EXP) - DBL_MANT_DIG;
    1346             : 
    1347           0 :     x = 0.0;
    1348           0 :     if (exp >= lsb) {
    1349             :         /* no rounding required */
    1350           0 :         for (i = ndigits-1; i >= 0; i--)
    1351           0 :             x = 16.0*x + HEX_DIGIT(i);
    1352           0 :         x = ldexp(x, (int)(exp));
    1353           0 :         goto finished;
    1354             :     }
    1355             :     /* rounding required.  key_digit is the index of the hex digit
    1356             :        containing the first bit to be rounded away. */
    1357           0 :     half_eps = 1 << (int)((lsb - exp - 1) % 4);
    1358           0 :     key_digit = (lsb - exp - 1) / 4;
    1359           0 :     for (i = ndigits-1; i > key_digit; i--)
    1360           0 :         x = 16.0*x + HEX_DIGIT(i);
    1361           0 :     digit = HEX_DIGIT(key_digit);
    1362           0 :     x = 16.0*x + (double)(digit & (16-2*half_eps));
    1363             : 
    1364             :     /* round-half-even: round up if bit lsb-1 is 1 and at least one of
    1365             :        bits lsb, lsb-2, lsb-3, lsb-4, ... is 1. */
    1366           0 :     if ((digit & half_eps) != 0) {
    1367           0 :         round_up = 0;
    1368           0 :         if ((digit & (3*half_eps-1)) != 0 ||
    1369           0 :             (half_eps == 8 && (HEX_DIGIT(key_digit+1) & 1) != 0))
    1370           0 :             round_up = 1;
    1371             :         else
    1372           0 :             for (i = key_digit-1; i >= 0; i--)
    1373           0 :                 if (HEX_DIGIT(i) != 0) {
    1374           0 :                     round_up = 1;
    1375           0 :                     break;
    1376             :                 }
    1377           0 :         if (round_up) {
    1378           0 :             x += 2*half_eps;
    1379           0 :             if (top_exp == DBL_MAX_EXP &&
    1380           0 :                 x == ldexp((double)(2*half_eps), DBL_MANT_DIG))
    1381             :                 /* overflow corner case: pre-rounded value <
    1382             :                    2**DBL_MAX_EXP; rounded=2**DBL_MAX_EXP. */
    1383           0 :                 goto overflow_error;
    1384             :         }
    1385             :     }
    1386           0 :     x = ldexp(x, (int)(exp+4*key_digit));
    1387             : 
    1388             :   finished:
    1389             :     /* optional trailing whitespace leading to the end of the string */
    1390           0 :     while (Py_ISSPACE(*s))
    1391           0 :         s++;
    1392           0 :     if (s != s_end)
    1393           0 :         goto parse_error;
    1394           0 :     result_as_float = Py_BuildValue("(d)", negate ? -x : x);
    1395           0 :     if (result_as_float == NULL)
    1396           0 :         return NULL;
    1397           0 :     result = PyObject_CallObject(cls, result_as_float);
    1398           0 :     Py_DECREF(result_as_float);
    1399           0 :     return result;
    1400             : 
    1401             :   overflow_error:
    1402           0 :     PyErr_SetString(PyExc_OverflowError,
    1403             :                     "hexadecimal value too large to represent as a float");
    1404           0 :     return NULL;
    1405             : 
    1406             :   parse_error:
    1407           0 :     PyErr_SetString(PyExc_ValueError,
    1408             :                     "invalid hexadecimal floating-point string");
    1409           0 :     return NULL;
    1410             : 
    1411             :   insane_length_error:
    1412           0 :     PyErr_SetString(PyExc_ValueError,
    1413             :                     "hexadecimal string too long to convert");
    1414           0 :     return NULL;
    1415             : }
    1416             : 
    1417             : PyDoc_STRVAR(float_fromhex_doc,
    1418             : "float.fromhex(string) -> float\n\
    1419             : \n\
    1420             : Create a floating-point number from a hexadecimal string.\n\
    1421             : >>> float.fromhex('0x1.ffffp10')\n\
    1422             : 2047.984375\n\
    1423             : >>> float.fromhex('-0x1p-1074')\n\
    1424             : -4.9406564584124654e-324");
    1425             : 
    1426             : 
    1427             : static PyObject *
    1428           0 : float_as_integer_ratio(PyObject *v, PyObject *unused)
    1429             : {
    1430             :     double self;
    1431             :     double float_part;
    1432             :     int exponent;
    1433             :     int i;
    1434             : 
    1435             :     PyObject *prev;
    1436           0 :     PyObject *py_exponent = NULL;
    1437           0 :     PyObject *numerator = NULL;
    1438           0 :     PyObject *denominator = NULL;
    1439           0 :     PyObject *result_pair = NULL;
    1440           0 :     PyNumberMethods *long_methods = PyLong_Type.tp_as_number;
    1441             : 
    1442             : #define INPLACE_UPDATE(obj, call) \
    1443             :     prev = obj; \
    1444             :     obj = call; \
    1445             :     Py_DECREF(prev); \
    1446             : 
    1447           0 :     CONVERT_TO_DOUBLE(v, self);
    1448             : 
    1449           0 :     if (Py_IS_INFINITY(self)) {
    1450           0 :       PyErr_SetString(PyExc_OverflowError,
    1451             :                       "Cannot pass infinity to float.as_integer_ratio.");
    1452           0 :       return NULL;
    1453             :     }
    1454           0 :     if (Py_IS_NAN(self)) {
    1455           0 :       PyErr_SetString(PyExc_ValueError,
    1456             :                       "Cannot pass NaN to float.as_integer_ratio.");
    1457           0 :       return NULL;
    1458             :     }
    1459             : 
    1460             :     PyFPE_START_PROTECT("as_integer_ratio", goto error);
    1461           0 :     float_part = frexp(self, &exponent);        /* self == float_part * 2**exponent exactly */
    1462             :     PyFPE_END_PROTECT(float_part);
    1463             : 
    1464           0 :     for (i=0; i<300 && float_part != floor(float_part) ; i++) {
    1465           0 :         float_part *= 2.0;
    1466           0 :         exponent--;
    1467             :     }
    1468             :     /* self == float_part * 2**exponent exactly and float_part is integral.
    1469             :        If FLT_RADIX != 2, the 300 steps may leave a tiny fractional part
    1470             :        to be truncated by PyLong_FromDouble(). */
    1471             : 
    1472           0 :     numerator = PyLong_FromDouble(float_part);
    1473           0 :     if (numerator == NULL) goto error;
    1474             : 
    1475             :     /* fold in 2**exponent */
    1476           0 :     denominator = PyLong_FromLong(1);
    1477           0 :     py_exponent = PyLong_FromLong(labs((long)exponent));
    1478           0 :     if (py_exponent == NULL) goto error;
    1479           0 :     INPLACE_UPDATE(py_exponent,
    1480             :                    long_methods->nb_lshift(denominator, py_exponent));
    1481           0 :     if (py_exponent == NULL) goto error;
    1482           0 :     if (exponent > 0) {
    1483           0 :         INPLACE_UPDATE(numerator,
    1484             :                        long_methods->nb_multiply(numerator, py_exponent));
    1485           0 :         if (numerator == NULL) goto error;
    1486             :     }
    1487             :     else {
    1488           0 :         Py_DECREF(denominator);
    1489           0 :         denominator = py_exponent;
    1490           0 :         py_exponent = NULL;
    1491             :     }
    1492             : 
    1493           0 :     result_pair = PyTuple_Pack(2, numerator, denominator);
    1494             : 
    1495             : #undef INPLACE_UPDATE
    1496             : error:
    1497           0 :     Py_XDECREF(py_exponent);
    1498           0 :     Py_XDECREF(denominator);
    1499           0 :     Py_XDECREF(numerator);
    1500           0 :     return result_pair;
    1501             : }
    1502             : 
    1503             : PyDoc_STRVAR(float_as_integer_ratio_doc,
    1504             : "float.as_integer_ratio() -> (int, int)\n"
    1505             : "\n"
    1506             : "Returns a pair of integers, whose ratio is exactly equal to the original\n"
    1507             : "float and with a positive denominator.\n"
    1508             : "Raises OverflowError on infinities and a ValueError on NaNs.\n"
    1509             : "\n"
    1510             : ">>> (10.0).as_integer_ratio()\n"
    1511             : "(10, 1)\n"
    1512             : ">>> (0.0).as_integer_ratio()\n"
    1513             : "(0, 1)\n"
    1514             : ">>> (-.25).as_integer_ratio()\n"
    1515             : "(-1, 4)");
    1516             : 
    1517             : 
    1518             : static PyObject *
    1519             : float_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
    1520             : 
    1521             : static PyObject *
    1522           0 : float_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
    1523             : {
    1524           0 :     PyObject *x = Py_False; /* Integer zero */
    1525             :     static char *kwlist[] = {"x", 0};
    1526             : 
    1527           0 :     if (type != &PyFloat_Type)
    1528           0 :         return float_subtype_new(type, args, kwds); /* Wimp out */
    1529           0 :     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:float", kwlist, &x))
    1530           0 :         return NULL;
    1531             :     /* If it's a string, but not a string subclass, use
    1532             :        PyFloat_FromString. */
    1533           0 :     if (PyUnicode_CheckExact(x))
    1534           0 :         return PyFloat_FromString(x);
    1535           0 :     return PyNumber_Float(x);
    1536             : }
    1537             : 
    1538             : /* Wimpy, slow approach to tp_new calls for subtypes of float:
    1539             :    first create a regular float from whatever arguments we got,
    1540             :    then allocate a subtype instance and initialize its ob_fval
    1541             :    from the regular float.  The regular float is then thrown away.
    1542             : */
    1543             : static PyObject *
    1544           0 : float_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
    1545             : {
    1546             :     PyObject *tmp, *newobj;
    1547             : 
    1548             :     assert(PyType_IsSubtype(type, &PyFloat_Type));
    1549           0 :     tmp = float_new(&PyFloat_Type, args, kwds);
    1550           0 :     if (tmp == NULL)
    1551           0 :         return NULL;
    1552             :     assert(PyFloat_CheckExact(tmp));
    1553           0 :     newobj = type->tp_alloc(type, 0);
    1554           0 :     if (newobj == NULL) {
    1555           0 :         Py_DECREF(tmp);
    1556           0 :         return NULL;
    1557             :     }
    1558           0 :     ((PyFloatObject *)newobj)->ob_fval = ((PyFloatObject *)tmp)->ob_fval;
    1559           0 :     Py_DECREF(tmp);
    1560           0 :     return newobj;
    1561             : }
    1562             : 
    1563             : static PyObject *
    1564           0 : float_getnewargs(PyFloatObject *v)
    1565             : {
    1566           0 :     return Py_BuildValue("(d)", v->ob_fval);
    1567             : }
    1568             : 
    1569             : /* this is for the benefit of the pack/unpack routines below */
    1570             : 
    1571             : typedef enum {
    1572             :     unknown_format, ieee_big_endian_format, ieee_little_endian_format
    1573             : } float_format_type;
    1574             : 
    1575             : static float_format_type double_format, float_format;
    1576             : static float_format_type detected_double_format, detected_float_format;
    1577             : 
    1578             : static PyObject *
    1579           0 : float_getformat(PyTypeObject *v, PyObject* arg)
    1580             : {
    1581             :     char* s;
    1582             :     float_format_type r;
    1583             : 
    1584           0 :     if (!PyUnicode_Check(arg)) {
    1585           0 :         PyErr_Format(PyExc_TypeError,
    1586             :          "__getformat__() argument must be string, not %.500s",
    1587           0 :                          Py_TYPE(arg)->tp_name);
    1588           0 :         return NULL;
    1589             :     }
    1590           0 :     s = _PyUnicode_AsString(arg);
    1591           0 :     if (s == NULL)
    1592           0 :         return NULL;
    1593           0 :     if (strcmp(s, "double") == 0) {
    1594           0 :         r = double_format;
    1595             :     }
    1596           0 :     else if (strcmp(s, "float") == 0) {
    1597           0 :         r = float_format;
    1598             :     }
    1599             :     else {
    1600           0 :         PyErr_SetString(PyExc_ValueError,
    1601             :                         "__getformat__() argument 1 must be "
    1602             :                         "'double' or 'float'");
    1603           0 :         return NULL;
    1604             :     }
    1605             : 
    1606           0 :     switch (r) {
    1607             :     case unknown_format:
    1608           0 :         return PyUnicode_FromString("unknown");
    1609             :     case ieee_little_endian_format:
    1610           0 :         return PyUnicode_FromString("IEEE, little-endian");
    1611             :     case ieee_big_endian_format:
    1612           0 :         return PyUnicode_FromString("IEEE, big-endian");
    1613             :     default:
    1614           0 :         Py_FatalError("insane float_format or double_format");
    1615           0 :         return NULL;
    1616             :     }
    1617             : }
    1618             : 
    1619             : PyDoc_STRVAR(float_getformat_doc,
    1620             : "float.__getformat__(typestr) -> string\n"
    1621             : "\n"
    1622             : "You probably don't want to use this function.  It exists mainly to be\n"
    1623             : "used in Python's test suite.\n"
    1624             : "\n"
    1625             : "typestr must be 'double' or 'float'.  This function returns whichever of\n"
    1626             : "'unknown', 'IEEE, big-endian' or 'IEEE, little-endian' best describes the\n"
    1627             : "format of floating point numbers used by the C type named by typestr.");
    1628             : 
    1629             : static PyObject *
    1630           0 : float_setformat(PyTypeObject *v, PyObject* args)
    1631             : {
    1632             :     char* typestr;
    1633             :     char* format;
    1634             :     float_format_type f;
    1635             :     float_format_type detected;
    1636             :     float_format_type *p;
    1637             : 
    1638           0 :     if (!PyArg_ParseTuple(args, "ss:__setformat__", &typestr, &format))
    1639           0 :         return NULL;
    1640             : 
    1641           0 :     if (strcmp(typestr, "double") == 0) {
    1642           0 :         p = &double_format;
    1643           0 :         detected = detected_double_format;
    1644             :     }
    1645           0 :     else if (strcmp(typestr, "float") == 0) {
    1646           0 :         p = &float_format;
    1647           0 :         detected = detected_float_format;
    1648             :     }
    1649             :     else {
    1650           0 :         PyErr_SetString(PyExc_ValueError,
    1651             :                         "__setformat__() argument 1 must "
    1652             :                         "be 'double' or 'float'");
    1653           0 :         return NULL;
    1654             :     }
    1655             : 
    1656           0 :     if (strcmp(format, "unknown") == 0) {
    1657           0 :         f = unknown_format;
    1658             :     }
    1659           0 :     else if (strcmp(format, "IEEE, little-endian") == 0) {
    1660           0 :         f = ieee_little_endian_format;
    1661             :     }
    1662           0 :     else if (strcmp(format, "IEEE, big-endian") == 0) {
    1663           0 :         f = ieee_big_endian_format;
    1664             :     }
    1665             :     else {
    1666           0 :         PyErr_SetString(PyExc_ValueError,
    1667             :                         "__setformat__() argument 2 must be "
    1668             :                         "'unknown', 'IEEE, little-endian' or "
    1669             :                         "'IEEE, big-endian'");
    1670           0 :         return NULL;
    1671             : 
    1672             :     }
    1673             : 
    1674           0 :     if (f != unknown_format && f != detected) {
    1675           0 :         PyErr_Format(PyExc_ValueError,
    1676             :                      "can only set %s format to 'unknown' or the "
    1677             :                      "detected platform value", typestr);
    1678           0 :         return NULL;
    1679             :     }
    1680             : 
    1681           0 :     *p = f;
    1682           0 :     Py_RETURN_NONE;
    1683             : }
    1684             : 
    1685             : PyDoc_STRVAR(float_setformat_doc,
    1686             : "float.__setformat__(typestr, fmt) -> None\n"
    1687             : "\n"
    1688             : "You probably don't want to use this function.  It exists mainly to be\n"
    1689             : "used in Python's test suite.\n"
    1690             : "\n"
    1691             : "typestr must be 'double' or 'float'.  fmt must be one of 'unknown',\n"
    1692             : "'IEEE, big-endian' or 'IEEE, little-endian', and in addition can only be\n"
    1693             : "one of the latter two if it appears to match the underlying C reality.\n"
    1694             : "\n"
    1695             : "Overrides the automatic determination of C-level floating point type.\n"
    1696             : "This affects how floats are converted to and from binary strings.");
    1697             : 
    1698             : static PyObject *
    1699           0 : float_getzero(PyObject *v, void *closure)
    1700             : {
    1701           0 :     return PyFloat_FromDouble(0.0);
    1702             : }
    1703             : 
    1704             : static PyObject *
    1705           0 : float__format__(PyObject *self, PyObject *args)
    1706             : {
    1707             :     PyObject *format_spec;
    1708             :     _PyUnicodeWriter writer;
    1709             :     int ret;
    1710             : 
    1711           0 :     if (!PyArg_ParseTuple(args, "U:__format__", &format_spec))
    1712           0 :         return NULL;
    1713             : 
    1714           0 :     _PyUnicodeWriter_Init(&writer, 0);
    1715           0 :     ret = _PyFloat_FormatAdvancedWriter(
    1716             :         &writer,
    1717             :         self,
    1718           0 :         format_spec, 0, PyUnicode_GET_LENGTH(format_spec));
    1719           0 :     if (ret == -1) {
    1720           0 :         _PyUnicodeWriter_Dealloc(&writer);
    1721           0 :         return NULL;
    1722             :     }
    1723           0 :     return _PyUnicodeWriter_Finish(&writer);
    1724             : }
    1725             : 
    1726             : PyDoc_STRVAR(float__format__doc,
    1727             : "float.__format__(format_spec) -> string\n"
    1728             : "\n"
    1729             : "Formats the float according to format_spec.");
    1730             : 
    1731             : 
    1732             : static PyMethodDef float_methods[] = {
    1733             :     {"conjugate",       (PyCFunction)float_float,       METH_NOARGS,
    1734             :      "Returns self, the complex conjugate of any float."},
    1735             :     {"__trunc__",       (PyCFunction)float_trunc, METH_NOARGS,
    1736             :      "Returns the Integral closest to x between 0 and x."},
    1737             :     {"__round__",       (PyCFunction)float_round, METH_VARARGS,
    1738             :      "Returns the Integral closest to x, rounding half toward even.\n"
    1739             :      "When an argument is passed, works like built-in round(x, ndigits)."},
    1740             :     {"as_integer_ratio", (PyCFunction)float_as_integer_ratio, METH_NOARGS,
    1741             :      float_as_integer_ratio_doc},
    1742             :     {"fromhex", (PyCFunction)float_fromhex,
    1743             :      METH_O|METH_CLASS, float_fromhex_doc},
    1744             :     {"hex", (PyCFunction)float_hex,
    1745             :      METH_NOARGS, float_hex_doc},
    1746             :     {"is_integer",      (PyCFunction)float_is_integer,  METH_NOARGS,
    1747             :      "Returns True if the float is an integer."},
    1748             : #if 0
    1749             :     {"is_inf",          (PyCFunction)float_is_inf,      METH_NOARGS,
    1750             :      "Returns True if the float is positive or negative infinite."},
    1751             :     {"is_finite",       (PyCFunction)float_is_finite,   METH_NOARGS,
    1752             :      "Returns True if the float is finite, neither infinite nor NaN."},
    1753             :     {"is_nan",          (PyCFunction)float_is_nan,      METH_NOARGS,
    1754             :      "Returns True if the float is not a number (NaN)."},
    1755             : #endif
    1756             :     {"__getnewargs__",          (PyCFunction)float_getnewargs,  METH_NOARGS},
    1757             :     {"__getformat__",           (PyCFunction)float_getformat,
    1758             :      METH_O|METH_CLASS,                 float_getformat_doc},
    1759             :     {"__setformat__",           (PyCFunction)float_setformat,
    1760             :      METH_VARARGS|METH_CLASS,           float_setformat_doc},
    1761             :     {"__format__",          (PyCFunction)float__format__,
    1762             :      METH_VARARGS,                  float__format__doc},
    1763             :     {NULL,              NULL}           /* sentinel */
    1764             : };
    1765             : 
    1766             : static PyGetSetDef float_getset[] = {
    1767             :     {"real",
    1768             :      (getter)float_float, (setter)NULL,
    1769             :      "the real part of a complex number",
    1770             :      NULL},
    1771             :     {"imag",
    1772             :      (getter)float_getzero, (setter)NULL,
    1773             :      "the imaginary part of a complex number",
    1774             :      NULL},
    1775             :     {NULL}  /* Sentinel */
    1776             : };
    1777             : 
    1778             : PyDoc_STRVAR(float_doc,
    1779             : "float(x) -> floating point number\n\
    1780             : \n\
    1781             : Convert a string or number to a floating point number, if possible.");
    1782             : 
    1783             : 
    1784             : static PyNumberMethods float_as_number = {
    1785             :     float_add,          /*nb_add*/
    1786             :     float_sub,          /*nb_subtract*/
    1787             :     float_mul,          /*nb_multiply*/
    1788             :     float_rem,          /*nb_remainder*/
    1789             :     float_divmod,       /*nb_divmod*/
    1790             :     float_pow,          /*nb_power*/
    1791             :     (unaryfunc)float_neg, /*nb_negative*/
    1792             :     (unaryfunc)float_float, /*nb_positive*/
    1793             :     (unaryfunc)float_abs, /*nb_absolute*/
    1794             :     (inquiry)float_bool, /*nb_bool*/
    1795             :     0,                  /*nb_invert*/
    1796             :     0,                  /*nb_lshift*/
    1797             :     0,                  /*nb_rshift*/
    1798             :     0,                  /*nb_and*/
    1799             :     0,                  /*nb_xor*/
    1800             :     0,                  /*nb_or*/
    1801             :     float_trunc,        /*nb_int*/
    1802             :     0,                  /*nb_reserved*/
    1803             :     float_float,        /*nb_float*/
    1804             :     0,                  /* nb_inplace_add */
    1805             :     0,                  /* nb_inplace_subtract */
    1806             :     0,                  /* nb_inplace_multiply */
    1807             :     0,                  /* nb_inplace_remainder */
    1808             :     0,                  /* nb_inplace_power */
    1809             :     0,                  /* nb_inplace_lshift */
    1810             :     0,                  /* nb_inplace_rshift */
    1811             :     0,                  /* nb_inplace_and */
    1812             :     0,                  /* nb_inplace_xor */
    1813             :     0,                  /* nb_inplace_or */
    1814             :     float_floor_div, /* nb_floor_divide */
    1815             :     float_div,          /* nb_true_divide */
    1816             :     0,                  /* nb_inplace_floor_divide */
    1817             :     0,                  /* nb_inplace_true_divide */
    1818             : };
    1819             : 
    1820             : PyTypeObject PyFloat_Type = {
    1821             :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
    1822             :     "float",
    1823             :     sizeof(PyFloatObject),
    1824             :     0,
    1825             :     (destructor)float_dealloc,                  /* tp_dealloc */
    1826             :     0,                                          /* tp_print */
    1827             :     0,                                          /* tp_getattr */
    1828             :     0,                                          /* tp_setattr */
    1829             :     0,                                          /* tp_reserved */
    1830             :     (reprfunc)float_repr,                       /* tp_repr */
    1831             :     &float_as_number,                           /* tp_as_number */
    1832             :     0,                                          /* tp_as_sequence */
    1833             :     0,                                          /* tp_as_mapping */
    1834             :     (hashfunc)float_hash,                       /* tp_hash */
    1835             :     0,                                          /* tp_call */
    1836             :     (reprfunc)float_repr,                       /* tp_str */
    1837             :     PyObject_GenericGetAttr,                    /* tp_getattro */
    1838             :     0,                                          /* tp_setattro */
    1839             :     0,                                          /* tp_as_buffer */
    1840             :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
    1841             :     float_doc,                                  /* tp_doc */
    1842             :     0,                                          /* tp_traverse */
    1843             :     0,                                          /* tp_clear */
    1844             :     float_richcompare,                          /* tp_richcompare */
    1845             :     0,                                          /* tp_weaklistoffset */
    1846             :     0,                                          /* tp_iter */
    1847             :     0,                                          /* tp_iternext */
    1848             :     float_methods,                              /* tp_methods */
    1849             :     0,                                          /* tp_members */
    1850             :     float_getset,                               /* tp_getset */
    1851             :     0,                                          /* tp_base */
    1852             :     0,                                          /* tp_dict */
    1853             :     0,                                          /* tp_descr_get */
    1854             :     0,                                          /* tp_descr_set */
    1855             :     0,                                          /* tp_dictoffset */
    1856             :     0,                                          /* tp_init */
    1857             :     0,                                          /* tp_alloc */
    1858             :     float_new,                                  /* tp_new */
    1859             : };
    1860             : 
    1861             : void
    1862           1 : _PyFloat_Init(void)
    1863             : {
    1864             :     /* We attempt to determine if this machine is using IEEE
    1865             :        floating point formats by peering at the bits of some
    1866             :        carefully chosen values.  If it looks like we are on an
    1867             :        IEEE platform, the float packing/unpacking routines can
    1868             :        just copy bits, if not they resort to arithmetic & shifts
    1869             :        and masks.  The shifts & masks approach works on all finite
    1870             :        values, but what happens to infinities, NaNs and signed
    1871             :        zeroes on packing is an accident, and attempting to unpack
    1872             :        a NaN or an infinity will raise an exception.
    1873             : 
    1874             :        Note that if we're on some whacked-out platform which uses
    1875             :        IEEE formats but isn't strictly little-endian or big-
    1876             :        endian, we will fall back to the portable shifts & masks
    1877             :        method. */
    1878             : 
    1879             : #if SIZEOF_DOUBLE == 8
    1880             :     {
    1881           1 :         double x = 9006104071832581.0;
    1882           1 :         if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0)
    1883           0 :             detected_double_format = ieee_big_endian_format;
    1884           1 :         else if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0)
    1885           1 :             detected_double_format = ieee_little_endian_format;
    1886             :         else
    1887           0 :             detected_double_format = unknown_format;
    1888             :     }
    1889             : #else
    1890             :     detected_double_format = unknown_format;
    1891             : #endif
    1892             : 
    1893             : #if SIZEOF_FLOAT == 4
    1894             :     {
    1895           1 :         float y = 16711938.0;
    1896           1 :         if (memcmp(&y, "\x4b\x7f\x01\x02", 4) == 0)
    1897           0 :             detected_float_format = ieee_big_endian_format;
    1898           1 :         else if (memcmp(&y, "\x02\x01\x7f\x4b", 4) == 0)
    1899           1 :             detected_float_format = ieee_little_endian_format;
    1900             :         else
    1901           0 :             detected_float_format = unknown_format;
    1902             :     }
    1903             : #else
    1904             :     detected_float_format = unknown_format;
    1905             : #endif
    1906             : 
    1907           1 :     double_format = detected_double_format;
    1908           1 :     float_format = detected_float_format;
    1909             : 
    1910             :     /* Init float info */
    1911           1 :     if (FloatInfoType.tp_name == 0)
    1912           1 :         PyStructSequence_InitType(&FloatInfoType, &floatinfo_desc);
    1913           1 : }
    1914             : 
    1915             : int
    1916           0 : PyFloat_ClearFreeList(void)
    1917             : {
    1918           0 :     PyFloatObject *f = free_list, *next;
    1919           0 :     int i = numfree;
    1920           0 :     while (f) {
    1921           0 :         next = (PyFloatObject*) Py_TYPE(f);
    1922           0 :         PyObject_FREE(f);
    1923           0 :         f = next;
    1924             :     }
    1925           0 :     free_list = NULL;
    1926           0 :     numfree = 0;
    1927           0 :     return i;
    1928             : }
    1929             : 
    1930             : void
    1931           0 : PyFloat_Fini(void)
    1932             : {
    1933           0 :     (void)PyFloat_ClearFreeList();
    1934           0 : }
    1935             : 
    1936             : /* Print summary info about the state of the optimized allocator */
    1937             : void
    1938           0 : _PyFloat_DebugMallocStats(FILE *out)
    1939             : {
    1940           0 :     _PyDebugAllocatorStats(out,
    1941             :                            "free PyFloatObject",
    1942             :                            numfree, sizeof(PyFloatObject));
    1943           0 : }
    1944             : 
    1945             : 
    1946             : /*----------------------------------------------------------------------------
    1947             :  * _PyFloat_{Pack,Unpack}{4,8}.  See floatobject.h.
    1948             :  */
    1949             : int
    1950           0 : _PyFloat_Pack4(double x, unsigned char *p, int le)
    1951             : {
    1952           0 :     if (float_format == unknown_format) {
    1953             :         unsigned char sign;
    1954             :         int e;
    1955             :         double f;
    1956             :         unsigned int fbits;
    1957           0 :         int incr = 1;
    1958             : 
    1959           0 :         if (le) {
    1960           0 :             p += 3;
    1961           0 :             incr = -1;
    1962             :         }
    1963             : 
    1964           0 :         if (x < 0) {
    1965           0 :             sign = 1;
    1966           0 :             x = -x;
    1967             :         }
    1968             :         else
    1969           0 :             sign = 0;
    1970             : 
    1971           0 :         f = frexp(x, &e);
    1972             : 
    1973             :         /* Normalize f to be in the range [1.0, 2.0) */
    1974           0 :         if (0.5 <= f && f < 1.0) {
    1975           0 :             f *= 2.0;
    1976           0 :             e--;
    1977             :         }
    1978           0 :         else if (f == 0.0)
    1979           0 :             e = 0;
    1980             :         else {
    1981           0 :             PyErr_SetString(PyExc_SystemError,
    1982             :                             "frexp() result out of range");
    1983           0 :             return -1;
    1984             :         }
    1985             : 
    1986           0 :         if (e >= 128)
    1987             :             goto Overflow;
    1988           0 :         else if (e < -126) {
    1989             :             /* Gradual underflow */
    1990           0 :             f = ldexp(f, 126 + e);
    1991           0 :             e = 0;
    1992             :         }
    1993           0 :         else if (!(e == 0 && f == 0.0)) {
    1994           0 :             e += 127;
    1995           0 :             f -= 1.0; /* Get rid of leading 1 */
    1996             :         }
    1997             : 
    1998           0 :         f *= 8388608.0; /* 2**23 */
    1999           0 :         fbits = (unsigned int)(f + 0.5); /* Round */
    2000             :         assert(fbits <= 8388608);
    2001           0 :         if (fbits >> 23) {
    2002             :             /* The carry propagated out of a string of 23 1 bits. */
    2003           0 :             fbits = 0;
    2004           0 :             ++e;
    2005           0 :             if (e >= 255)
    2006             :                 goto Overflow;
    2007             :         }
    2008             : 
    2009             :         /* First byte */
    2010           0 :         *p = (sign << 7) | (e >> 1);
    2011           0 :         p += incr;
    2012             : 
    2013             :         /* Second byte */
    2014           0 :         *p = (char) (((e & 1) << 7) | (fbits >> 16));
    2015           0 :         p += incr;
    2016             : 
    2017             :         /* Third byte */
    2018           0 :         *p = (fbits >> 8) & 0xFF;
    2019           0 :         p += incr;
    2020             : 
    2021             :         /* Fourth byte */
    2022           0 :         *p = fbits & 0xFF;
    2023             : 
    2024             :         /* Done */
    2025           0 :         return 0;
    2026             : 
    2027             :     }
    2028             :     else {
    2029           0 :         float y = (float)x;
    2030           0 :         const char *s = (char*)&y;
    2031           0 :         int i, incr = 1;
    2032             : 
    2033           0 :         if (Py_IS_INFINITY(y) && !Py_IS_INFINITY(x))
    2034             :             goto Overflow;
    2035             : 
    2036           0 :         if ((float_format == ieee_little_endian_format && !le)
    2037           0 :             || (float_format == ieee_big_endian_format && le)) {
    2038           0 :             p += 3;
    2039           0 :             incr = -1;
    2040             :         }
    2041             : 
    2042           0 :         for (i = 0; i < 4; i++) {
    2043           0 :             *p = *s++;
    2044           0 :             p += incr;
    2045             :         }
    2046           0 :         return 0;
    2047             :     }
    2048             :   Overflow:
    2049           0 :     PyErr_SetString(PyExc_OverflowError,
    2050             :                     "float too large to pack with f format");
    2051           0 :     return -1;
    2052             : }
    2053             : 
    2054             : int
    2055           0 : _PyFloat_Pack8(double x, unsigned char *p, int le)
    2056             : {
    2057           0 :     if (double_format == unknown_format) {
    2058             :         unsigned char sign;
    2059             :         int e;
    2060             :         double f;
    2061             :         unsigned int fhi, flo;
    2062           0 :         int incr = 1;
    2063             : 
    2064           0 :         if (le) {
    2065           0 :             p += 7;
    2066           0 :             incr = -1;
    2067             :         }
    2068             : 
    2069           0 :         if (x < 0) {
    2070           0 :             sign = 1;
    2071           0 :             x = -x;
    2072             :         }
    2073             :         else
    2074           0 :             sign = 0;
    2075             : 
    2076           0 :         f = frexp(x, &e);
    2077             : 
    2078             :         /* Normalize f to be in the range [1.0, 2.0) */
    2079           0 :         if (0.5 <= f && f < 1.0) {
    2080           0 :             f *= 2.0;
    2081           0 :             e--;
    2082             :         }
    2083           0 :         else if (f == 0.0)
    2084           0 :             e = 0;
    2085             :         else {
    2086           0 :             PyErr_SetString(PyExc_SystemError,
    2087             :                             "frexp() result out of range");
    2088           0 :             return -1;
    2089             :         }
    2090             : 
    2091           0 :         if (e >= 1024)
    2092           0 :             goto Overflow;
    2093           0 :         else if (e < -1022) {
    2094             :             /* Gradual underflow */
    2095           0 :             f = ldexp(f, 1022 + e);
    2096           0 :             e = 0;
    2097             :         }
    2098           0 :         else if (!(e == 0 && f == 0.0)) {
    2099           0 :             e += 1023;
    2100           0 :             f -= 1.0; /* Get rid of leading 1 */
    2101             :         }
    2102             : 
    2103             :         /* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */
    2104           0 :         f *= 268435456.0; /* 2**28 */
    2105           0 :         fhi = (unsigned int)f; /* Truncate */
    2106             :         assert(fhi < 268435456);
    2107             : 
    2108           0 :         f -= (double)fhi;
    2109           0 :         f *= 16777216.0; /* 2**24 */
    2110           0 :         flo = (unsigned int)(f + 0.5); /* Round */
    2111             :         assert(flo <= 16777216);
    2112           0 :         if (flo >> 24) {
    2113             :             /* The carry propagated out of a string of 24 1 bits. */
    2114           0 :             flo = 0;
    2115           0 :             ++fhi;
    2116           0 :             if (fhi >> 28) {
    2117             :                 /* And it also progagated out of the next 28 bits. */
    2118           0 :                 fhi = 0;
    2119           0 :                 ++e;
    2120           0 :                 if (e >= 2047)
    2121           0 :                     goto Overflow;
    2122             :             }
    2123             :         }
    2124             : 
    2125             :         /* First byte */
    2126           0 :         *p = (sign << 7) | (e >> 4);
    2127           0 :         p += incr;
    2128             : 
    2129             :         /* Second byte */
    2130           0 :         *p = (unsigned char) (((e & 0xF) << 4) | (fhi >> 24));
    2131           0 :         p += incr;
    2132             : 
    2133             :         /* Third byte */
    2134           0 :         *p = (fhi >> 16) & 0xFF;
    2135           0 :         p += incr;
    2136             : 
    2137             :         /* Fourth byte */
    2138           0 :         *p = (fhi >> 8) & 0xFF;
    2139           0 :         p += incr;
    2140             : 
    2141             :         /* Fifth byte */
    2142           0 :         *p = fhi & 0xFF;
    2143           0 :         p += incr;
    2144             : 
    2145             :         /* Sixth byte */
    2146           0 :         *p = (flo >> 16) & 0xFF;
    2147           0 :         p += incr;
    2148             : 
    2149             :         /* Seventh byte */
    2150           0 :         *p = (flo >> 8) & 0xFF;
    2151           0 :         p += incr;
    2152             : 
    2153             :         /* Eighth byte */
    2154           0 :         *p = flo & 0xFF;
    2155             :         /* p += incr; */
    2156             : 
    2157             :         /* Done */
    2158           0 :         return 0;
    2159             : 
    2160             :       Overflow:
    2161           0 :         PyErr_SetString(PyExc_OverflowError,
    2162             :                         "float too large to pack with d format");
    2163           0 :         return -1;
    2164             :     }
    2165             :     else {
    2166           0 :         const char *s = (char*)&x;
    2167           0 :         int i, incr = 1;
    2168             : 
    2169           0 :         if ((double_format == ieee_little_endian_format && !le)
    2170           0 :             || (double_format == ieee_big_endian_format && le)) {
    2171           0 :             p += 7;
    2172           0 :             incr = -1;
    2173             :         }
    2174             : 
    2175           0 :         for (i = 0; i < 8; i++) {
    2176           0 :             *p = *s++;
    2177           0 :             p += incr;
    2178             :         }
    2179           0 :         return 0;
    2180             :     }
    2181             : }
    2182             : 
    2183             : double
    2184           0 : _PyFloat_Unpack4(const unsigned char *p, int le)
    2185             : {
    2186           0 :     if (float_format == unknown_format) {
    2187             :         unsigned char sign;
    2188             :         int e;
    2189             :         unsigned int f;
    2190             :         double x;
    2191           0 :         int incr = 1;
    2192             : 
    2193           0 :         if (le) {
    2194           0 :             p += 3;
    2195           0 :             incr = -1;
    2196             :         }
    2197             : 
    2198             :         /* First byte */
    2199           0 :         sign = (*p >> 7) & 1;
    2200           0 :         e = (*p & 0x7F) << 1;
    2201           0 :         p += incr;
    2202             : 
    2203             :         /* Second byte */
    2204           0 :         e |= (*p >> 7) & 1;
    2205           0 :         f = (*p & 0x7F) << 16;
    2206           0 :         p += incr;
    2207             : 
    2208           0 :         if (e == 255) {
    2209           0 :             PyErr_SetString(
    2210             :                 PyExc_ValueError,
    2211             :                 "can't unpack IEEE 754 special value "
    2212             :                 "on non-IEEE platform");
    2213           0 :             return -1;
    2214             :         }
    2215             : 
    2216             :         /* Third byte */
    2217           0 :         f |= *p << 8;
    2218           0 :         p += incr;
    2219             : 
    2220             :         /* Fourth byte */
    2221           0 :         f |= *p;
    2222             : 
    2223           0 :         x = (double)f / 8388608.0;
    2224             : 
    2225             :         /* XXX This sadly ignores Inf/NaN issues */
    2226           0 :         if (e == 0)
    2227           0 :             e = -126;
    2228             :         else {
    2229           0 :             x += 1.0;
    2230           0 :             e -= 127;
    2231             :         }
    2232           0 :         x = ldexp(x, e);
    2233             : 
    2234           0 :         if (sign)
    2235           0 :             x = -x;
    2236             : 
    2237           0 :         return x;
    2238             :     }
    2239             :     else {
    2240             :         float x;
    2241             : 
    2242           0 :         if ((float_format == ieee_little_endian_format && !le)
    2243           0 :             || (float_format == ieee_big_endian_format && le)) {
    2244             :             char buf[4];
    2245           0 :             char *d = &buf[3];
    2246             :             int i;
    2247             : 
    2248           0 :             for (i = 0; i < 4; i++) {
    2249           0 :                 *d-- = *p++;
    2250             :             }
    2251           0 :             memcpy(&x, buf, 4);
    2252             :         }
    2253             :         else {
    2254           0 :             memcpy(&x, p, 4);
    2255             :         }
    2256             : 
    2257           0 :         return x;
    2258             :     }
    2259             : }
    2260             : 
    2261             : double
    2262           1 : _PyFloat_Unpack8(const unsigned char *p, int le)
    2263             : {
    2264           1 :     if (double_format == unknown_format) {
    2265             :         unsigned char sign;
    2266             :         int e;
    2267             :         unsigned int fhi, flo;
    2268             :         double x;
    2269           0 :         int incr = 1;
    2270             : 
    2271           0 :         if (le) {
    2272           0 :             p += 7;
    2273           0 :             incr = -1;
    2274             :         }
    2275             : 
    2276             :         /* First byte */
    2277           0 :         sign = (*p >> 7) & 1;
    2278           0 :         e = (*p & 0x7F) << 4;
    2279             : 
    2280           0 :         p += incr;
    2281             : 
    2282             :         /* Second byte */
    2283           0 :         e |= (*p >> 4) & 0xF;
    2284           0 :         fhi = (*p & 0xF) << 24;
    2285           0 :         p += incr;
    2286             : 
    2287           0 :         if (e == 2047) {
    2288           0 :             PyErr_SetString(
    2289             :                 PyExc_ValueError,
    2290             :                 "can't unpack IEEE 754 special value "
    2291             :                 "on non-IEEE platform");
    2292           0 :             return -1.0;
    2293             :         }
    2294             : 
    2295             :         /* Third byte */
    2296           0 :         fhi |= *p << 16;
    2297           0 :         p += incr;
    2298             : 
    2299             :         /* Fourth byte */
    2300           0 :         fhi |= *p  << 8;
    2301           0 :         p += incr;
    2302             : 
    2303             :         /* Fifth byte */
    2304           0 :         fhi |= *p;
    2305           0 :         p += incr;
    2306             : 
    2307             :         /* Sixth byte */
    2308           0 :         flo = *p << 16;
    2309           0 :         p += incr;
    2310             : 
    2311             :         /* Seventh byte */
    2312           0 :         flo |= *p << 8;
    2313           0 :         p += incr;
    2314             : 
    2315             :         /* Eighth byte */
    2316           0 :         flo |= *p;
    2317             : 
    2318           0 :         x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */
    2319           0 :         x /= 268435456.0; /* 2**28 */
    2320             : 
    2321           0 :         if (e == 0)
    2322           0 :             e = -1022;
    2323             :         else {
    2324           0 :             x += 1.0;
    2325           0 :             e -= 1023;
    2326             :         }
    2327           0 :         x = ldexp(x, e);
    2328             : 
    2329           0 :         if (sign)
    2330           0 :             x = -x;
    2331             : 
    2332           0 :         return x;
    2333             :     }
    2334             :     else {
    2335             :         double x;
    2336             : 
    2337           1 :         if ((double_format == ieee_little_endian_format && !le)
    2338           1 :             || (double_format == ieee_big_endian_format && le)) {
    2339             :             char buf[8];
    2340           0 :             char *d = &buf[7];
    2341             :             int i;
    2342             : 
    2343           0 :             for (i = 0; i < 8; i++) {
    2344           0 :                 *d-- = *p++;
    2345             :             }
    2346           0 :             memcpy(&x, buf, 8);
    2347             :         }
    2348             :         else {
    2349           1 :             memcpy(&x, p, 8);
    2350             :         }
    2351             : 
    2352           1 :         return x;
    2353             :     }
    2354             : }

Generated by: LCOV version 1.10