edward.dauvergne@xxxxxxxxx wrote:
Author: bugman Date: Sat Nov 11 10:57:35 2006 New Revision: 2801
URL: http://svn.gna.org/viewcvs/relax?rev=2801&view=rev Log: Two functions for converting a string bit pattern to a float and a number of IEEE-754 constants.
The fucntions 'bitpatternToFloat()' and 'bitpatternToInt()' have been added to 'float.py'. The
first converts a 64 bit IEEE-754 bit pattern in the form of a string into a 64 bit Python float.
The second converts an arbitrary bit pattern into its integer representation. By looping over each
8 characters of the string (1 byte), 'bitpatternToFloat()' calls 'bitpatternToInt()' to create an
array of integers. Then 'packBytesAsPyFloat()' is called to convert the byte array into the float.
These two functions convert between big and little endian when necessary.
Nice functions! However, I would suggest that these should go in utility functions or the test suite.... I am trying to keep float.py as the bare minimum file for testing floating point numbers and floating point constants
A couple of other matters as well
1. the constants are not much use at the end of the file as if anything else in the file wants to refer to them they won't be able to 2. I was thinking of a test case with random numbers in the exponent of the nan and then reporting what the bit pattern that failed was.... 3. I was also thinking of having test caseswith minimum and maximum bit patterns e.g. max denorm min denorm nan with highest mantissa bit set nan with smallest mantissa bit set etc
By passing big-endian 64 bit patterns to the 'bitpatternToFloat()' function, the following IEEE-754 constants are defined: PosZero: 0000000000000000000000000000000000000000000000000000000000000000 NegZero: 1000000000000000000000000000000000000000000000000000000000000000 PosEpsilonDenorm: 0000000000000000000000000000000000000000000000000000000000000001 NegEpsilonDenorm: 1000000000000000000000000000000000000000000000000000000000000001 PosEpsilonNorm: 0000000000010000000000000000000000000000000000000000000000000001 NegEpsilonNorm: 1000000000010000000000000000000000000000000000000000000000000001 PosMax: 0111111111101111111111111111111111111111111111111111111111111111 NegMin: 1111111111101111111111111111111111111111111111111111111111111111 PosInf: 0111111111110000000000000000000000000000000000000000000000000000 NegInf: 1111111111110000000000000000000000000000000000000000000000000000 PosNaN_A: 0111111111110000000000000000000000000000001000000000000000000000 NegNaN_A: 1111111111110000000000000000000000000000001000000000000000000000 PosNaN_B: 0111111111110000000000000000011111111111111111111110000000000000 NegNaN_B: 1111111111110000000000000000011111111111111111111110000000000000 PosNaN_C: 0111111111110101010101010101010101010101010101010101010101010101 NegNaN_C: 1111111111110101010101010101010101010101010101010101010101010101 PosNaN = PosNaN_C NegNaN = NegNaN_C
I have some code that reads and displays these as octes which makes life easier...
11111111 11110101 01010101 01010101 01010101 01010101 01010101 01010101
Modified: branches/test_suite/float.py
Modified: branches/test_suite/float.py
URL: http://svn.gna.org/viewcvs/relax/branches/test_suite/float.py?rev=2801&r1=2800&r2=2801&view=diff
==============================================================================
--- branches/test_suite/float.py (original)
+++ branches/test_suite/float.py Sat Nov 11 10:57:35 2006
@@ -637,6 +637,7 @@
''' return isInf(obj) and isPositive(obj)
+
def isNegInf(obj):
''' check to see if a python float is negative infinity @@ -647,11 +648,124 @@
throws -- throws a TypeError if obj isn't a python float '''
- - return isInf(obj) and not isPositive(obj) - -
- -
-
-
+
+ return isInf(obj) and not isPositive(obj)
+
+
+def bitpatternToFloat(string, endian='big'):
+ """Convert a 64 bit IEEE-754 ascii bit pattern into a 64 bit Python float.
+
+ @param string: The ascii bit pattern repesenting the IEEE-754 float.
+ @type string: str
+ @param endian: The endianness of the bit pattern (can be 'big' or 'little').
+ @type endian: str
+ @return: The 64 bit float corresponding to the IEEE-754 bit pattern.
+ @returntype: float
+ @raise: TypeError if 'string' is not a string, the length of the 'string' is not 64, or
+ if 'string' does not consist solely of the characters '0' and '1'.
+ """
+
+ # Test that the bit pattern is a string.
+ if type(string) != str:
+ raise TypeError, "The string argument '%s' is not a string." % string
I think this is to restrictive opther things can act as sequences...
+
+ # Test the length of the bit pattern.
+ if len(string) != 64:
+ raise TypeError, "The string '%s' is not 64 characters long." % string
+
+ # Test that the string consists solely of zeros and ones.
+ for char in string:
+ if char not in ['0', '1']:
+ raise TypeError, "The string '%s' should be composed solely of the characters '0' and '1'." % string
+
+ # Reverse the byte order as neccessary.
+ if endian == 'big' and sys.byteorder == 'little':
+ string = string[::-1]
+ elif endian == 'little' and sys.byteorder == 'big':
+ string = string[::-1]
+
this could be better written as
# Reverse the byte order as neccessary. if endian != sys.byteorder: string = string[::-1]
and then add an assert effectivley of the form endian..tolower() in ('little','big')
+ # Convert the bit pattern into a byte array (of integers). + bytes = [] + for i in xrange(8): + bytes.append(bitpatternToInt(string[i*8:i*8+8], endian=sys.byteorder)) + + # Pack the byte array into a float and return it. + return packBytesAsPyFloat(bytes) + + +def bitpatternToInt(string, endian='big'): + """Convert a bit pattern into its integer representation. + + @param string: The ascii string repesenting binary data. + @type string: str + @param endian: The endianness of the bit pattern (can be 'big' or 'little'). + @type endian: str + @return: The integer value. + @returntype: int + """ + + # Test that the bit pattern is a string. + if type(string) != str: + raise TypeError, "The string argument '%s' is not a string." % string + + # Test that the string consists solely of zeros and ones. + for char in string: + if char not in ['0', '1']: + raise TypeError, "The string '%s' should be composed solely of the characters '0' and '1'." % string + + # Reverse the byte order as neccessary. + if endian == 'big' and sys.byteorder == 'little': + string = string[::-1] + elif endian == 'little' and sys.byteorder == 'big': + string = string[::-1] + + # Calculate the integer corresponding to the string. + int_val = 0 + for i in xrange(len(string)): + if int(string[i]): + int_val = int_val + 2**i + + # Return the integer value. + return int_val + + +# IEEE-754 Constants. +##################### + +# The following bit patterns are to be read from right to left (big-endian). +# Hence bit positions 0 and 63 are to the far right and far left respectively. +PosZero = bitpatternToFloat('0000000000000000000000000000000000000000000000000000000000000000', endian='big') +NegZero = bitpatternToFloat('1000000000000000000000000000000000000000000000000000000000000000', endian='big') +PosEpsilonDenorm = bitpatternToFloat('0000000000000000000000000000000000000000000000000000000000000001', endian='big') +NegEpsilonDenorm = bitpatternToFloat('1000000000000000000000000000000000000000000000000000000000000001', endian='big') +PosEpsilonNorm = bitpatternToFloat('0000000000010000000000000000000000000000000000000000000000000001', endian='big') +NegEpsilonNorm = bitpatternToFloat('1000000000010000000000000000000000000000000000000000000000000001', endian='big') +PosMax = bitpatternToFloat('0111111111101111111111111111111111111111111111111111111111111111', endian='big') +NegMin = bitpatternToFloat('1111111111101111111111111111111111111111111111111111111111111111', endian='big') +PosInf = bitpatternToFloat('0111111111110000000000000000000000000000000000000000000000000000', endian='big') +NegInf = bitpatternToFloat('1111111111110000000000000000000000000000000000000000000000000000', endian='big') +PosNaN_A = bitpatternToFloat('0111111111110000000000000000000000000000001000000000000000000000', endian='big') +NegNaN_A = bitpatternToFloat('1111111111110000000000000000000000000000001000000000000000000000', endian='big') +PosNaN_B = bitpatternToFloat('0111111111110000000000000000011111111111111111111110000000000000', endian='big') +NegNaN_B = bitpatternToFloat('1111111111110000000000000000011111111111111111111110000000000000', endian='big') +PosNaN_C = bitpatternToFloat('0111111111110101010101010101010101010101010101010101010101010101', endian='big') +NegNaN_C = bitpatternToFloat('1111111111110101010101010101010101010101010101010101010101010101', endian='big') +PosNaN = PosNaN_C +NegNaN = NegNaN_C + +#print "%-30s%-20.40g" % ("Pos zero: ", PosZero) +#print "%-30s%-20.40g" % ("Neg zero: ", NegZero) +#print "%-30s%-20.40g" % ("Pos epsilon denorm: ", PosEpsilonDenorm) +#print "%-30s%-20.40g" % ("Neg epsilon denorm: ", NegEpsilonDenorm) +#print "%-30s%-20.40g" % ("Pos epsilon norm: ", PosEpsilonNorm) +#print "%-30s%-20.40g" % ("Neg epsilon norm: ", NegEpsilonNorm) +#print "%-30s%-20.40g" % ("Max: ", PosMax) +#print "%-30s%-20.40g" % ("Min: ", NegMin) +#print "%-30s%-20.40g" % ("Pos inf: ", PosInf) +#print "%-30s%-20.40g" % ("Neg inf: ", NegInf) +#print "%-30s%-20.40g" % ("Pos NaN (A): ", PosNaN_A) +#print "%-30s%-20.40g" % ("Neg NaN (A): ", NegNaN_A) +#print "%-30s%-20.40g" % ("Pos NaN (B): ", PosNaN_B) +#print "%-30s%-20.40g" % ("Neg NaN (B): ", NegNaN_B) +#print "%-30s%-20.40g" % ("Pos NaN (C): ", PosNaN_C) +#print "%-30s%-20.40g" % ("Neg NaN (C): ", NegNaN_C)
_______________________________________________ relax (http://nmr-relax.com)
This is the relax-commits mailing list relax-commits@xxxxxxx
To unsubscribe from this list, get a password reminder, or change your subscription options, visit the list information page at https://mail.gna.org/listinfo/relax-commits
.
regards gary
-- ------------------------------------------------------------------- Dr Gary Thompson Astbury Centre for Structural Molecular Biology, University of Leeds, Astbury Building, Leeds, LS2 9JT, West-Yorkshire, UK Tel. +44-113-3433024 email: garyt@xxxxxxxxxxxxxxx Fax +44-113-2331407 -------------------------------------------------------------------