1 """Utilities for handling IEEE 754 floating point special values
3 This python module implements constants and functions for working with
4 IEEE754 double-precision special values. It provides constants for
5 Not-a-Number (NaN), Positive Infinity (PosInf), and Negative Infinity
6 (NegInf), as well as functions to test for these values.
8 The code is implemented in pure python by taking advantage of the
9 'struct' standard module. Care has been taken to generate proper
10 results on both big-endian and little-endian machines. Some efficiency
11 could be gained by translating the core routines into C.
13 See <http://babbage.cs.qc.edu/courses/cs341/IEEE-754references.html>
14 for reference material on the IEEE 754 floating point standard.
16 Further information on this package is available at
17 <http://software.biostat.washington.edu/statsoft/snake/fpconst>.
19 Author: Gregory R. Warnes <gregory_r_warnes@groton.pfizer.com>
21 Copyright: (c) 2003, Pfizer, Inc.
25 ident = "$Id: fpconst.py,v 1.8 2003/05/12 15:14:00 warnes Exp $"
30 _big_endian = struct.pack('i',1)[0] != '\x01'
32 # and define appropriate constants
37 NaN = struct.unpack('d', '\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF')[0]
38 PosInf = struct.unpack('d', '\x7F\xF0\x00\x00\x00\x00\x00\x00')[0]
45 NaN = struct.unpack('d', '\x00\x00\x00\x00\x00\x00\xf8\xff')[0]
46 PosInf = struct.unpack('d', '\x00\x00\x00\x00\x00\x00\xf0\x7f')[0]
49 def _double_as_longs(dval):
50 "Use struct.unpack to decode a double precision float into two longs"
51 tmp = struct.unpack('ll',struct.pack('d', dval))
52 return (tmp[_HW], tmp[_LW])
56 ## Functions to extract components of the IEEE 754 floating point format
60 "Extract the sign bit from a double-precision floating point value"
61 ll = _double_as_longs(dval)
62 return ll[0] >> 31 & 0x01
65 """Extract the exponentent bits from a double-precision floating
68 Note that for normalized values, the exponentdent bits have an offset
69 of 1023. As a consequence, the actual exponentent is obtained
70 by subtracting 1023 for the value returned by this function
72 ll = _double_as_longs(dval)
73 return (ll[0] >> 20) & 0x7ff
76 """Extract the _mantissa bits from a double-precision floating
79 ll = _double_as_longs(dval)
80 mantissa0 = (ll[0] & 0x000fffffL) << 32
82 return mantissa0 + mantissa1
85 ## Functions to test for IEEE 754 special values
89 "Determine if the argument is a IEEE 754 NaN (Not a Number) value."
90 return (_exponent(value)==0x7ff and _mantissa(value)!=0)
93 """Determine if the argument is an infinite IEEE 754 value (positive
94 or negative inifinity)"""
95 return (_exponent(value)==0x7ff and _mantissa(value)== 0)
98 """Determine if the argument is an finite IEEE 754 value (i.e., is
99 not NaN, positive or negative inifinity)"""
100 return (_exponent(value)!=0x7ff)
104 "Determine if the argument is a IEEE 754 positive infinity value"
105 return (_sign(value)==0 and _exponent(value)==0x7ff and \
106 _mantissa(value)== 0)
109 "Determine if the argument is a IEEE 754 negative infinity value"
110 return (_sign(value)==1 and _exponent(value)==0x7ff and \
111 _mantissa(value)== 0)