On 2007-09-20, Joshua J. Kugler <[EMAIL PROTECTED]> wrote: >> import struct >> >> pack_double_workaround = { >> 'inf': struct.pack('Q', 0x7ff0000000000000L), >> '-inf': struct.pack('Q', 0xfff0000000000000L), >> 'nan': struct.pack('Q', 0x7ff8000000000000L) >> } >> >> def pack_one_safe(f, a): >> if f == 'd' and str(f) in pack_double_workaround: >> return pack_double_workaround[str(f)] >> return struct.pack(f, a) >> >> def pack(fmt, *args): >> return ''.join(pack_one_safe(f, a) for f, a in zip(fmt, args))
NB: the strings returned by str() when passed a NaN or Inf are system dependent and aren't guaranteed to be consistent from one day to the next unless you've overridden the floating point object's __repr__ method to make sure. >> Unpacking is similar: unpack doubles with 'Q' and test the >> long for equality with +-inf, and find nan's by checking bits >> 52 to 62. If the number's ok, unpack again using 'd'. Here are the tests I use for 32-bit work: def isNaN(u): return ((u & 0x7f800000) == 0x7f800000) and (u & 0x7fffff) def isInf(u): return ((u & 0x7f800000) == 0x7f800000) and ((u & 0x7fffff)==0) def isNeg(u): return (u & 0x80000000) >> You can get python values for nan, -inf and inf by using >> float('nan'), float('-inf'), float('inf'). >> >> I've not been able to properly test this, as struct seems >> to work fine in Python 2.3 and 2.4 on MacOS X. > > Thanks for the ideas, Paul! I came up with something that > works for me, but this has a few ideas that I'm going to > implement in my wrapper to make for cleaner code. > > As to testing it on MacOS X: yeah, it can be a somewhat > system-dependent problem, It shouldn't be, but unfortunately it is. If you're careful, you can come up with something that's fairly portable (I've got a wrapped pickle/unpickle that's nan/inf aware and works on both Win32 and Linux. Holler if you want it. > Thanks for the tips! -- Grant Edwards grante Yow! I Know A Joke!! at visi.com -- http://mail.python.org/mailman/listinfo/python-list