Reputation: 31614
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?
Upvotes: 2
Views: 2021
Reputation: 95991
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.
Upvotes: 1
Reputation: 54097
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!
Upvotes: 1
Reputation: 49813
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.");
Upvotes: 5