You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

115 lines
3.2 KiB

  1. """Utilities for handling IEEE 754 floating point special values
  2. This class implements constants and functions for working with IEEE754
  3. double-precision special values. It provides constants for NaN (Not a
  4. Number), NegInf (Negative Infinity), PosInf (Positive Infinity), and
  5. Inf (also Positive Infinity), as well as functions to test for these
  6. values.
  7. The code is implemented in pure python by taking advantage of the
  8. 'struct' standard module. Some efficiency could be gained by
  9. translating the core routines into C.
  10. See <http://babbage.cs.qc.edu/courses/cs341/IEEE-754references.html>
  11. for a description of the IEEE 754 floating point standard.
  12. Author: Gregory R. Warnes <gregory_r_warnes@groton.pfizer.com>
  13. Date:: 2003-03-25
  14. Version 0.5.0
  15. """
  16. ident = "$Id$"
  17. __version__ = "0.5.0"
  18. from struct import pack, unpack
  19. # check endianess
  20. _big_endian = pack('i',1)[0] != '\x01'
  21. # and define appropriate constants
  22. if(_big_endian):
  23. HW=0
  24. LW=1
  25. NaN = unpack('d', '\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF')[0]
  26. Inf = unpack('d', '\x7F\xF0\x00\x00\x00\x00\x00\x00')[0]
  27. PosInf = Inf
  28. NegInf = -Inf
  29. else:
  30. HW=1
  31. LW=0
  32. NaN = unpack('d', '\x00\x00\x00\x00\x00\x00\xf8\xff')[0]
  33. Inf = unpack('d', '\x00\x00\x00\x00\x00\x00\xf0\x7f')[0]
  34. PosInf = Inf
  35. NegInf = -Inf
  36. def _double_as_longs(dval):
  37. "Use unpack to decode a double precision float into two long integers"
  38. tmp = unpack('ll',pack('d', dval))
  39. return (tmp[HW], tmp[LW] )
  40. ##
  41. ## Functions to extract components of the IEEE 754 floating point format
  42. ##
  43. def sign(dval):
  44. "Extract the sign bit from a double-precision floating point value"
  45. ll = _double_as_longs(dval)
  46. return ll[0] >> 31 & 0x01
  47. def exponent(dval):
  48. """Extract the exponentent bits from a double-precision floating
  49. point value.
  50. Note that for normalized values, the exponentdent bits have an offset
  51. of 1023. As a consequence, the actual exponentent is obtained
  52. by subtracting 1023 for the value returned by this function
  53. """
  54. ll = _double_as_longs(dval)
  55. return ( ll[0] >> 20 ) & 0x7ff
  56. def mantissa(dval):
  57. ll = _double_as_longs(dval)
  58. mantissa1 = ( ll[0] & 0xfffffL ) << 32
  59. mantissa2 = ll[1]
  60. return mantissa1 + mantissa2
  61. ##
  62. ## Functions to test for IEEE 754 special values
  63. ##
  64. def is_NaN(value):
  65. "Determine if the argument is a IEEE 754 NaN (Not a Number) value."
  66. return ( exponent(value)==0x7ff and mantissa(value)!=0 )
  67. def is_Infinite(value):
  68. """Determine if the argument is an infinite IEEE 754 value (positive
  69. or negative inifinity)"""
  70. return ( exponent(value)==0x7ff and mantissa(value)== 0 )
  71. def is_Finite(value):
  72. """Determine if the argument is an finite IEEE 754 value (i.e., is
  73. not NaN, positive or negative inifinity)"""
  74. return ( exponent(value)!=0x7ff )
  75. def is_Inf(value):
  76. "Determine if the argument is a IEEE 754 positive infinity value"
  77. return ( sign(value)==0 and exponent(value)==0x7ff \
  78. and mantissa(value)== 0 )
  79. is_PosInf = is_Inf
  80. def is_NegInf(value):
  81. "Determine if the argument is a IEEE 754 negative infinity value"
  82. return ( sign(value)==1 and exponent(value)==0x7ff and \
  83. mantissa(value)== 0 )