Package qubx :: Module ulp_diff
[hide private]
[frames] | no frames]

Source Code for Module qubx.ulp_diff

 1  import struct 
 2  from functools import partial 
 3   
 4  # (c) 2010 Eric L. Frederich 
 5  # 
 6  # Python implementation of algorithms detailed here... 
 7  # from http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm 
 8   
9 -def c_mem_cast(x, f=None, t=None):
10 ''' 11 do a c-style memory cast 12 13 In Python... 14 15 x = 12.34 16 y = c_mem_cast(x, 'd', 'l') 17 18 ... should be equivilent to the following in c... 19 20 double x = 12.34; 21 long y = *(long*)&x; 22 ''' 23 return struct.unpack(t, struct.pack(f, x))[0]
24 25 dbl_to_lng = partial(c_mem_cast, f='d', t='l') 26 lng_to_dbl = partial(c_mem_cast, f='l', t='d') 27 flt_to_int = partial(c_mem_cast, f='f', t='i') 28 int_to_flt = partial(c_mem_cast, f='i', t='f') 29
30 -def ulp_diff_maker(converter, negative_zero):
31 ''' 32 Getting the ulp difference of floats and doubles is similar. 33 Only difference if the offset and converter. 34 ''' 35 def the_diff(a, b): 36 37 # Make a integer lexicographically ordered as a twos-complement int 38 ai = converter(a) 39 if ai < 0: 40 ai = negative_zero - ai 41 42 # Make b integer lexicographically ordered as a twos-complement int 43 bi = converter(b) 44 if bi < 0: 45 bi = negative_zero - bi 46 47 return abs(ai - bi)
48 49 return the_diff 50 51 # double ULP difference 52 dulpdiff = ulp_diff_maker(dbl_to_lng, 0x8000000000000000) 53 # float ULP difference 54 fulpdiff = ulp_diff_maker(flt_to_int, 0x80000000 ) 55 56 # default to double ULP difference 57 ulpdiff = dulpdiff 58 ulpdiff.__doc__ = ''' 59 Get the number of doubles between two doubles. 60 ''' 61