root/galaxy-central/lib/fpconst.py

リビジョン 2, 4.9 KB (コミッタ: hatakeyama, 14 年 前)

import galaxy-central

行番号 
1"""Utilities for handling IEEE 754 floating point special values
2
3This python module implements constants and functions for working with
4IEEE754 double-precision special values.  It provides constants for
5Not-a-Number (NaN), Positive Infinity (PosInf), and Negative Infinity
6(NegInf), as well as functions to test for these values.
7
8The code is implemented in pure python by taking advantage of the
9'struct' standard module. Care has been taken to generate proper
10results on both big-endian and little-endian machines. Some efficiency
11could be gained by translating the core routines into C.
12
13See <http://babbage.cs.qc.edu/courses/cs341/IEEE-754references.html>
14for reference material on the IEEE 754 floating point standard.
15
16Further information on this package is available at
17<http://www.analytics.washington.edu/statcomp/projects/rzope/fpconst/>.
18
19Author:    Gregory R. Warnes <gregory_r_warnes@groton.pfizer.com>
20Date::     2003-04-08
21Copyright: (c) 2003, Pfizer, Inc.
22"""
23
24__version__ = "0.7.0"
25ident = "$Id: fpconst.py,v 1.12 2004/05/22 04:38:17 warnes Exp $"
26
27import struct, operator
28
29# check endianess
30_big_endian = struct.pack('i',1)[0] != '\x01'
31
32# and define appropriate constants
33if(_big_endian):
34    NaN    = struct.unpack('d', '\x7F\xF8\x00\x00\x00\x00\x00\x00')[0]
35    PosInf = struct.unpack('d', '\x7F\xF0\x00\x00\x00\x00\x00\x00')[0]
36    NegInf = -PosInf
37else:
38    NaN    = struct.unpack('d', '\x00\x00\x00\x00\x00\x00\xf8\xff')[0]
39    PosInf = struct.unpack('d', '\x00\x00\x00\x00\x00\x00\xf0\x7f')[0]
40    NegInf = -PosInf
41
42def _double_as_bytes(dval):
43    "Use struct.unpack to decode a double precision float into eight bytes"
44    tmp = list(struct.unpack('8B',struct.pack('d', dval)))
45    if not _big_endian:
46        tmp.reverse()
47    return tmp
48
49##
50## Functions to extract components of the IEEE 754 floating point format
51##
52
53def _sign(dval):
54    "Extract the sign bit from a double-precision floating point value"
55    bb = _double_as_bytes(dval)
56    return bb[0] >> 7 & 0x01
57
58def _exponent(dval):
59    """Extract the exponentent bits from a double-precision floating
60    point value.
61
62    Note that for normalized values, the exponent bits have an offset
63    of 1023. As a consequence, the actual exponentent is obtained
64    by subtracting 1023 from the value returned by this function
65    """
66    bb = _double_as_bytes(dval)
67    return (bb[0] << 4 | bb[1] >> 4) & 0x7ff
68
69def _mantissa(dval):
70    """Extract the _mantissa bits from a double-precision floating
71    point value."""
72
73    bb = _double_as_bytes(dval)
74    mantissa =  bb[1] & 0x0f << 48
75    mantissa += bb[2] << 40
76    mantissa += bb[3] << 32
77    mantissa += bb[4]
78    return mantissa
79
80def _zero_mantissa(dval):
81    """Determine whether the mantissa bits of the given double are all
82    zero."""
83    bb = _double_as_bytes(dval)
84    return ((bb[1] & 0x0f) | reduce(operator.or_, bb[2:])) == 0
85
86##
87## Functions to test for IEEE 754 special values
88##
89
90def isNaN(value):
91    "Determine if the argument is a IEEE 754 NaN (Not a Number) value."
92    return (_exponent(value)==0x7ff and not _zero_mantissa(value))
93
94def isInf(value):
95    """Determine if the argument is an infinite IEEE 754 value (positive
96    or negative inifinity)"""
97    return (_exponent(value)==0x7ff and _zero_mantissa(value))
98
99def isFinite(value):
100    """Determine if the argument is an finite IEEE 754 value (i.e., is
101    not NaN, positive or negative inifinity)"""
102    return (_exponent(value)!=0x7ff)
103
104def isPosInf(value):
105    "Determine if the argument is a IEEE 754 positive infinity value"
106    return (_sign(value)==0 and _exponent(value)==0x7ff and \
107            _zero_mantissa(value))
108
109def isNegInf(value):
110    "Determine if the argument is a IEEE 754 negative infinity value"
111    return (_sign(value)==1 and _exponent(value)==0x7ff and \
112            _zero_mantissa(value))
113
114##
115## Functions to test public functions.
116##
117
118def test_isNaN():
119    assert( not isNaN(PosInf) )
120    assert( not isNaN(NegInf) )
121    assert(     isNaN(NaN   ) )
122    assert( not isNaN(   1.0) )
123    assert( not isNaN(  -1.0) )
124
125def test_isInf():
126    assert(     isInf(PosInf) )
127    assert(     isInf(NegInf) )
128    assert( not isInf(NaN   ) )
129    assert( not isInf(   1.0) )
130    assert( not isInf(  -1.0) )
131
132def test_isFinite():
133    assert( not isFinite(PosInf) )
134    assert( not isFinite(NegInf) )
135    assert( not isFinite(NaN   ) )
136    assert(     isFinite(   1.0) )
137    assert(     isFinite(  -1.0) )
138
139def test_isPosInf():
140    assert(     isPosInf(PosInf) )
141    assert( not isPosInf(NegInf) )
142    assert( not isPosInf(NaN   ) )
143    assert( not isPosInf(   1.0) )
144    assert( not isPosInf(  -1.0) )
145
146def test_isNegInf():
147    assert( not isNegInf(PosInf) )
148    assert(     isNegInf(NegInf) )
149    assert( not isNegInf(NaN   ) )
150    assert( not isNegInf(   1.0) )
151    assert( not isNegInf(  -1.0) )
152
153# overall test
154def test():
155    test_isNaN()
156    test_isInf()
157    test_isFinite()
158    test_isPosInf()
159    test_isNegInf()
160   
161if __name__ == "__main__":
162    test()
163
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。