This is Python 3.5 code.
I have attempted to develop my own frexp()
function that mimics the functionality of Python standard library's math.frexp()
.
I'm interested in suggestions for how improve my code style to become more Pythonic and how to achieve better performance and precision for this function.
My code:
import ctypes
def frexp(x):
*binstr, = bin(ctypes.c_int.from_buffer(ctypes.c_float(x)).value)
if binstr[0] == '-' : binstr.pop(0)
exponent = int ( (''.join(binstr))[2:10], 2 ) - 127
mantissa = 1
for index, item in enumerate(''.join(binstr)[10:]):
if item == '1':
mantissa += 2 ** ( -(index + 1) )
return mantissa, exponent
Precision: not accurate
>>> import random
>>> testednumber = random.random() + random.random() * ( 10 ** 10 )
>>> testednumber
5478324268.848498
>>> # This is my code's output
>>> import mymath
>>> mymath.frexp(testednumber)
(1.2755217552185059, 32)
>>> # This is Python's frexp() output
>>> import math
>>> math.frexp(testednumber)
(0.6377608828303053, 33)
>>> # my result:
>>> (1.2755217552185059) * ( 2 ** 32 )
5478324224.0
>>> # Python's frexp() result:
>>> (0.6377608828303053) * ( 2 ** 33 )
5478324268.848498
Speed: 55 times slower than math.frexp()
>>> # This is my minimum speed
>>> print(min(timeit.Timer("mymath.frexp(testednumber)", setup="import mymath; testednumber = 5478324268.848498").repeat(7,1000)))
0.01864783600103692
>>> print(min(timeit.Timer("mymath.frexp(testednumber)", setup="import mymath; testednumber = 5478324268.848498").repeat(7,1000)))
0.01870606800002861
>>> print(min(timeit.Timer("mymath.frexp(testednumber)", setup="import mymath; testednumber = 5478324268.848498").repeat(7,1000)))
0.018558342000687844
>>> # This is Python's frexp() minimum speed
>>> print(min(timeit.Timer("math.frexp(testednumber)", setup="import math; testednumber = 5478324268.848498").repeat(7,1000)))
0.0003347589990880806
>>> print(min(timeit.Timer("math.frexp(testednumber)", setup="import math; testednumber = 5478324268.848498").repeat(7,1000)))
0.0003345459990669042
>>> print(min(timeit.Timer("math.frexp(testednumber)", setup="import math; testednumber = 5478324268.848498").repeat(7,1000)))
0.0003347729998495197