views:

146

answers:

3

The python frexp and ldexp functions splits floats into mantissa and exponent. Do anybody know if this process exposes the actual float structure, or if it requires python to do expensive logarithmic calls?

+3  A: 

Python 2.6's math.frexp just calls the underlying C library frexp directly. We must assume that the C library simply uses the float representation's parts directly instead of calculating if avaliable (IEEE 754).

static PyObject *
math_frexp(PyObject *self, PyObject *arg)
{
        int i;
        double x = PyFloat_AsDouble(arg);
        if (x == -1.0 && PyErr_Occurred())
                return NULL;
        /* deal with special cases directly, to sidestep platform
           differences */
        if (Py_IS_NAN(x) || Py_IS_INFINITY(x) || !x) {
                i = 0;
        }
        else {  
                PyFPE_START_PROTECT("in math_frexp", return 0);
                x = frexp(x, &i);
                PyFPE_END_PROTECT(x);
        }
        return Py_BuildValue("(di)", x, i);
}

PyDoc_STRVAR(math_frexp_doc,
"frexp(x)\n"
"\n"
"Return the mantissa and exponent of x, as pair (m, e).\n"
"m is a float and e is an int, such that x = m * 2.**e.\n"
"If x is 0, m and e are both 0.  Else 0.5 <= abs(m) < 1.0.");
kaizer.se
As the routine is slower than the logarithm, it would seam like the PyFloat_AsDouble is quite heavy.
Thomas Ahle
`Py_BuildValue` might be comparatively expensive.
kaizer.se
Yes, I suppose python is just not the language to look for, when you want to do performance hacks :)
Thomas Ahle
+1  A: 

As for speed, here is a quick comparison

$ python -m timeit -c 'from math import frexp' 'frexp(1.1)'
100000 loops, best of 3: 3.7 usec per loop

$ python -m timeit -c 'from math import log' 'log(1.1)'
100000 loops, best of 3: 3.7 usec per loop

$ python -m timeit -c 'from math import ldexp' 'ldexp(1.1,2)'
100000 loops, best of 3: 3.5 usec per loop

So there isn't a lot of difference detectable in python between frexp, log and ldexp in terms of speed. Not sure that tells you anything about the implementation though!

Nick Craig-Wood
+1  A: 

This is a question you can easily answer yourself:

$ python
>>> import math
>>> help(math.frexp)
Help on built-in function frexp in module math:

Notice the built-in. It's in C.

>>> import urllib
>>> help(urllib.urlopen)
Help on function urlopen in module urllib:

No built-in here. It's in Python.

ΤΖΩΤΖΙΟΥ