Package lib :: Module float
[hide private]
[frames] | no frames]

Source Code for Module lib.float

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2006 Gary Thompson                                            # 
  4  # Copyright (C) 2006-2008,2012-2013 Edward d'Auvergne                         # 
  5  #                                                                             # 
  6  # This file is part of the program relax (http://www.nmr-relax.com).          # 
  7  #                                                                             # 
  8  # This program is free software: you can redistribute it and/or modify        # 
  9  # it under the terms of the GNU General Public License as published by        # 
 10  # the Free Software Foundation, either version 3 of the License, or           # 
 11  # (at your option) any later version.                                         # 
 12  #                                                                             # 
 13  # This program is distributed in the hope that it will be useful,             # 
 14  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 15  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 16  # GNU General Public License for more details.                                # 
 17  #                                                                             # 
 18  # You should have received a copy of the GNU General Public License           # 
 19  # along with this program.  If not, see <http://www.gnu.org/licenses/>.       # 
 20  #                                                                             # 
 21  ############################################################################### 
 22   
 23  # Module docstring. 
 24  """ieeefloat a set of functions for dealing with IEEE-754 float objects. 
 25   
 26  On most platforms Python uses IEEE-754 double objects of length 64 bits to represent floats (some 
 27  architectures such as older Crays and Vaxes don't).  Thus an IEEE-754 double is the implementation 
 28  of a python float object on most platforms. 
 29   
 30  IEEE-74 uses special bit patterns to represent the following states or classes of IEEE floating 
 31  point numbers (IEEE-class): 
 32      - +/- NaN:    Not a number (e.g. 0.0/0.0). 
 33      - inf:        Positive or negative infinity (1.0/0.0). 
 34      - +/- zero:   Zero maybe positive or negative under IEEE-754. 
 35   
 36  This module provides functions for working with python floats and their special values, if they 
 37  contain IEEE-754 formatted values.  Specifically: 
 38      - Pack and unpack a list of bytes representing an IEEE-754 double to a python float (takes care 
 39        of little endian/big endian issues). 
 40      - Get the sign bit of a python float. 
 41      - Check the ordering of python floats allowing for NaNs (NaNs cannot normally be compared). 
 42      - Check if a value is finite (as opposed to NaN or inf). 
 43      - Copy the sign of one float to another irrespective of if it's IEEE-class. 
 44      - Check if a float is denormalised (and might be about to underflow). 
 45      - Check the IEEE-class of a python float (NaN, pos-inf, neg-inf, pos-zero, neg-zero, ...). 
 46      - Check that the current python float implementations uses IEEE-754 doubles. 
 47   
 48  It also provides constants containg specific bit patterns for NaN and +-inf as these values cannot 
 49  be generated from strings via the constructor float(x) with some compiler implementations (typically 
 50  older Microsoft Windows compilers). 
 51   
 52  As a convenience the names of functions and constants conform to those defined in the draft python 
 53  PEP 754 'IEEE 754 Floating Point Special Values'. 
 54   
 55  Notes: 
 56      1.  Binary data is documented as binary strings e.g. 0xF0 = 0b11110000. 
 57      2.  The module doesn't support all the functions recommended by IEEE-754, the following features 
 58          are missing: 
 59              - Control of exception and rounding modes. 
 60              - scalb(y, N). 
 61              - logb(x). 
 62              - nextafter(x,y). 
 63              - Next towards. 
 64      3.  Division by zero currently (python 2.5) raises exception and the resulting inf/NaN cannot be 
 65          propogated. 
 66      4.  A second module ieeefloatcapabilities (currently incomplete) provides tests of the 
 67          capabilities of a floating point implementation on a specific python platform. 
 68      5.  Development and conventions on byte order come from a little endian (Intel) platform. 
 69      6.  To reduce overheads all functions that take python float arguments do _no type_ conversion 
 70          thus if other numeric types are passed the functions will raise exceptions, (I am not sure 
 71          this is the best behaviour however, as python functions should be polymorphic...). 
 72      7.  In most cases conversion to C code for performance reasons would be trivial. 
 73   
 74  IEEE-754 double format: 
 75      - 63 sign bit. 
 76      - 62-52 exponent (offset by 1023 value - field-1023). 
 77      - 51-0 mantissa each bit n counts as 1/2^n, running from 1/2 which is the most significant bit 
 78        to 1/2^51, The 1/0 bit is defined by the exponent field if it has any bits set if it has bits 
 79        set then precede the mantissa with a 1 (normalised otherwise precede it by a 0 (denormalised). 
 80   
 81   
 82  Todo: 
 83      - Unit test suite. 
 84      - Test under Windows. 
 85      - Test under a Solaris Sparc box (big endian). 
 86      - Add example IEEE double. 
 87      - Check byte/nibble attributions. 
 88  """ 
 89   
 90  # Python module imports. 
 91  from struct import pack, unpack 
 92  import sys 
 93   
 94  # relax module imports. 
 95  from lib.check_types import is_float 
 96   
 97   
 98  SIGNBIT = 0x80 
 99  """Bit pattern for the sign bit in byte 8 0b00000001 of a IEEE-754 double.""" 
100   
101   
102  EXPONENT_ALL_ONES_BYTE_1 = 0x7F 
103  """Value of the first byte (byte 8) in the mantissa of a IEEE-754 double that is all ones 
104  (0b11111110).""" 
105   
106  EXPONENT_ALL_ONES_BYTE_0 = 0xF << 4 
107  """Value of the second byte (byte 7) in the mantissa of a IEEE-754 double that is all ones 
108  (0b00001111).""" 
109   
110   
111  MANTISSA_NIBBLE_MASK=0x0F 
112  """Mask to select the bits from the first nibble of  byte 7 of an IEEE-754 which is part of the 
113  mantissa (0b00001111).""" 
114   
115  EXPONENT_NIBBLE_MASK=0xF0 
116  """Mask to select the bits from the second nibble of  byte 7 of an IEEE-754 which is part of the 
117  exponent (0b11110000).""" 
118   
119   
120  EXPONENT_SIGN_MASK= 0x7F 
121  """Mask to select only bits from byte 8 of an IEEE-754 double that are not part of the sign bit 
122  (0b11111110).""" 
123   
124  """Classes of floating point numbers.""" 
125  CLASS_POS_INF = 1 
126  CLASS_NEG_INF = 2 
127  CLASS_POS_NORMAL = 4 
128  CLASS_NEG_NORMAL = 8 
129  CLASS_POS_DENORMAL = 16 
130  CLASS_NEG_DENORMAL = 32 
131  CLASS_QUIET_NAN =  64 
132  CLASS_SIGNAL_NAN = 128 
133  CLASS_POS_ZERO =  256 
134  CLASS_NEG_ZERO = 512 
135   
136   
137 -def isZero(float):
138 return isMantissaAllZeros(float) and isExpAllZeros(float)
139 140
141 -def getFloatClass(float):
142 """Get the IEEE-class (NaN, inf etc) of a python float. 143 144 @param float: Python float object. 145 @type float: float 146 @return: An IEEE class value. 147 @rtype: int 148 @raise TypeError: If float is not a python float object. 149 """ 150 151 result = None 152 153 # check finite 154 if isFinite(float): 155 # check and store is positive 156 positive = isPositive(float) 157 if isZero(float): 158 if positive: 159 result = CLASS_POS_ZERO 160 else: 161 result = CLASS_NEG_ZERO 162 elif isDenormalised(float): 163 if positive: 164 result = CLASS_POS_DENORMAL 165 else: 166 result = CLASS_NEG_DENORMAL 167 else: 168 if positive: 169 result = CLASS_POS_NORMAL 170 else: 171 result = CLASS_NEG_NORMAL 172 else: 173 if isNaN(float): 174 # we don't currently test the type of NaN signalling vs quiet 175 # so we always assume a quiet NaN 176 result = CLASS_QUIET_NAN 177 elif isPosInf(float): 178 result = CLASS_POS_INF 179 elif isNegInf(float): 180 result = CLASS_NEG_INF 181 return result
182 183
184 -def packBytesAsPyFloat(bytes):
185 """Pack 8 bytes into a python float. 186 187 The function is endian aware and the data should be input in little endian format. Thus byte 8 188 contains the most significant bit of the exponent and the sign bit. 189 190 @param bytes: 8 bytes to pack into a python (IEEE 754 double) float. 191 @type bytes: float 192 @return: A python float 193 @rtype: float 194 @raise TypeError: If bytes contains < 8 bytes type of exception not determined. 195 """ 196 197 # pack bytes into binary string 198 doubleString=pack('8B',*bytes) 199 200 #change byte order to little endian by reversing string 201 if sys.byteorder == 'big': 202 doubleString = doubleString[::-1] 203 204 # unpack binary string to a python float 205 return unpack('d', doubleString)[0]
206 207 208 NAN_BYTES = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x7F] 209 """Bytes for an arbitary IEEE-754 not a number (NaN) in little endian format 210 0b00000000 00000000 00000000 00000000 00000000 00000000 00011111 11111110.""" 211 212 213 INF_BYTES = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x7F] 214 """Bytes for IEEE-754 positive infinity (inf) in little endian format 215 0b00000000 00000000 00000000 00000000 00000000 00000000 00001111 11111110.""" 216 217 218 nan = packBytesAsPyFloat(NAN_BYTES) 219 """One of a number of possible bit patterns used to represent an IEEE-754 double as a python float. 220 Do not use this value for comparisons of the form x==NaN as it will fail on some platforms use 221 function isNaN instead.""" 222 223 224 pos_inf = packBytesAsPyFloat(INF_BYTES) 225 """The value of a positive IEEE-754 double infinity as a python float.""" 226 227 228 neg_inf = -1 * pos_inf 229 """The value of a negative IEEE-754 double infinity as a python float.""" 230 231
232 -def floatToBinaryString(obj):
233 """Pack a python float into a binary string. 234 235 This function assumes that the python type float it represents a 64bit double of 8 bytes. This 236 function reverses the resulting string if the current architecture is big endian. 237 238 @param obj: A python float to pack. 239 @type obj: float 240 @return: A string of 8 bytes. 241 @rtype: str 242 @raise TypeError: If the input object isn't a python float. 243 """ 244 245 if not is_float(obj): 246 raise TypeError('the object recieved wasn\'t a float, type was: %s' % type(obj)) 247 248 # pack float into binary string 249 packed =pack('d', obj) 250 251 #change byte order to little endian by reversing string 252 if sys.byteorder == 'big': 253 packed = packed[::-1] 254 255 return packed
256 257
258 -def floatAsByteArray(obj):
259 """Unpack a python float as a list of 8 bytes. 260 261 This function assumes that the python type float it represents a 64bit double of 8 bytes. 262 263 @param obj: A python float to unpack. 264 @type obj: float 265 @return: A list of 7 bytes. 266 @rtype: list of str 267 @raise TypeError: If obj is not composed of 8 bytes. 268 """ 269 270 # unpack bytes to a binary string (takes care of byte order) 271 binaryString = floatToBinaryString(obj) 272 273 # convert the binary string to an array of 8 bytes 274 bytes = unpack('8B', binaryString) 275 276 #convert bytes to a list for ease of editing 277 return list(bytes)
278 279
280 -def getSignBit(obj):
281 """Get the sign bit from a python float. 282 283 @param obj: A python float object. 284 @type obj: float 285 @return: The float's sign bit, this has the value 1 if the float is negative 286 otherwise 0 (positive). 287 @rtype: bit 288 @raise TypeError: If the input object isn't a python float. 289 """ 290 291 # unpack float to bytes 292 unpacked = floatAsByteArray(obj) 293 294 # grab last byte and check if sign bit is set 295 return unpacked[7] & SIGNBIT
296 297
298 -def isPositive(obj):
299 """Test if a python float is positive. 300 301 @param obj: A python float object. 302 @type obj: float 303 @return: True if the float is positive otherwise False. 304 @rtype: bool 305 @raise TypeError: If the input object isn't a python float. 306 """ 307 308 if getSignBit(obj): 309 return False 310 else: 311 return True
312 313
314 -def isNegative(obj):
315 """Test if a python float 64 bit IEEE-74 double is negative. 316 317 @param obj: A python float object. 318 @type obj: float 319 @return: True if the float is negative. 320 @rtype: bool 321 @raise TypeError: If the input object isn't a python float. 322 """ 323 324 return not isPositive(obj)
325 326
327 -def areUnordered(obj1, obj2):
328 """Test to see if two python float are unordered. 329 330 Float comparison is unordered if either or both of the objects is 'not a number' (NaN). 331 332 @param obj1: A python float object 333 @type obj1: float 334 @param obj2: A python float object 335 @type obj2: float 336 @return: True if one of the args is a NaN. 337 @rtype: bool 338 @raise TypeError: If the input objects aren't python floats. 339 """ 340 341 # check to see if objects are NaNs 342 nanTest1 = isNaN(obj1) 343 nanTest2 = isNaN(obj2) 344 345 # if either object is a NaN we are unordered 346 if nanTest1 or nanTest2: 347 return True 348 else: 349 return False
350 351
352 -def isFinite(obj):
353 """Test to see if a python float is finite. 354 355 To be finite a number mustn't be a NaN or +/- inf. A result of True guarantees that the number 356 is bounded by +/- inf, -inf < x < inf. 357 358 @param obj: A python float object. 359 @type obj: float 360 @return: True if the float is finite. 361 @rtype: bool 362 @raise TypeError: If the input object isn't a python float. 363 """ 364 365 result = True 366 if isNaN(obj): 367 result = False 368 if isInf(obj): 369 result = False 370 371 372 return result
373 374
375 -def copySign(fromNumber, toDouble):
376 """Copy the sign bit from one python float to another. 377 378 This function is class agnostic the sign bit can be copied freely between ordinary floats, NaNs 379 and +/- inf. 380 381 @param fromNumber: The python float to copy the sign bit from. 382 @type fromNumber: float 383 @param toDouble: The python float to copy the sign bit to. 384 @type toDouble: float 385 @raise TypeError: If toDouble isn't a python float or if fromNumber can't be converted to a 386 float. 387 """ 388 389 #convert first number to a float so as to use facilities 390 fromNumber = float(fromNumber) 391 392 # check signs of numbers 393 fromIsPositive = isPositive(fromNumber) 394 toIsPositive = isPositive(toDouble) 395 396 # convert the float to an array of 8 bytes 397 toBytes = floatAsByteArray(toDouble) 398 399 if not toIsPositive and fromIsPositive: 400 # unset the sign bit of the number 401 toBytes[7] &= EXPONENT_SIGN_MASK 402 403 elif toIsPositive and not fromIsPositive: 404 # set the sign bit 405 toBytes[7] = toBytes[7] + 0x80 406 407 #repack bytes to float 408 return packBytesAsPyFloat(toBytes)
409 410
411 -def isDenormalised(obj):
412 """Check to see if a python float is denormalised. 413 414 Denormalisation indicates that the number has no exponent set and all the precision is in the 415 mantissa, this is an indication that the number is tending to towards underflow. 416 417 @param obj: Python float object to check. 418 @type obj: float 419 @return: True if the number is denormalised. 420 @rtype: bool 421 @raise TypeError: If toDouble isn't a python float or if obj isn't a float. 422 """ 423 424 result = True 425 # check to see if the exponent is all zeros (a denorm doesn't have a 426 # finite exponent) Note we ignore the sign of the float 427 if not isExpAllZeros(obj): 428 result = False 429 430 # check to see if this is zero (which is in some ways a special 431 # class of denorm... but isn't counted in this case) 432 # if it isn't zero it must be a 'general' denorm 433 if isZero(obj): 434 result = False 435 436 return result
437 438
439 -def getMantissaBytes(obj):
440 """Get the 7 bytes that makeup the mantissa of float. 441 442 The mantissa is returned as the 7 bytes in the mantissa in little endian order in the 7th byte 443 the 2nd nibble of the byte is masked off as it contains part of the exponent. The second nibble 444 of the 7th byte is therefore always has the value 0x0. 445 446 @param obj: Float object to extract the mantissa from. 447 @type obj: float 448 @return: A list of 7 bytes in little endian order. 449 @rtype: list of 7 bytes 450 @raise TypeError: If obj isn't a python float. 451 """ 452 453 # unpack float to bytes 454 bytes = floatAsByteArray(obj) 455 456 # mask out overlap from exponent 457 bytes[6] = bytes[6] & MANTISSA_NIBBLE_MASK 458 459 # remove the exponent bytes that can be removed 460 return bytes[:7]
461 462
463 -def getExponentBytes(obj):
464 """Get the 2 bytes that makeup the exponent of a float. 465 466 The exponent is returned as the 2 bytes in the exponent in little endian order in the 2nd byte 467 the last bit is masked off as this is the sign bit. Therefore all values have the last bit set 468 to zero. In the first byte the first nibble of the byte is also masked off as it contains part 469 of the mantissa and thus always has the value 0x0. 470 471 @param obj: Float object to extract the exponent from. 472 @type obj: float 473 @return: A list of 2 bytes in little endian order. 474 @rtype: list of 2 bytes 475 @raise TypeError: If obj isn't a python float. 476 """ 477 478 # unpack float to bytes 479 bytes = floatAsByteArray(obj) 480 481 # mask out the ovberlap with the mantissa 482 bytes[6] = bytes[6] & EXPONENT_NIBBLE_MASK 483 484 # mask out the sign bit 485 bytes[7] = bytes[7] & EXPONENT_SIGN_MASK 486 487 # remove the mantissa bytes that can be removed 488 return bytes[6:]
489 490
491 -def isExpAllZeros(obj):
492 """Check if the bits of the exponent of a float is zero. 493 494 @param obj: Float object to check exponent for zero value. 495 @type obj: float 496 @return: True if the exponent is zero. 497 @rtype: bool 498 @raise TypeError: If obj isn't a python float. 499 """ 500 501 result = True 502 503 # get the exponent as a byte array porperly masked 504 expBytes = getExponentBytes(obj) 505 506 # check to see if any of the bytes in the exponent are not zero 507 if expBytes[0] > 0 or expBytes[1] > 0: 508 result = False 509 510 return result
511 512
513 -def isMantissaAllZeros(obj):
514 """Check if the bits of the mantissa of a float is zero. 515 516 @param obj: Float object to check mantissa for zero value. 517 @type obj: float 518 @return: True if the mantissa is zero. 519 @rtype: bool 520 @raise TypeError: If obj isn't a python float. 521 """ 522 523 result = True 524 525 # get the mantissa as a byte array properly masked 526 mantissaBytes = getMantissaBytes(obj) 527 528 # check if any of the mantissa bytes are greater than zero 529 for byte in mantissaBytes: 530 if byte != 0: 531 result = False 532 break 533 534 return result
535 536
537 -def isExpAllOnes(obj):
538 """Check if the bits of the exponent of a float is all 1 bits. 539 540 @param obj: Float object to check exponent for 1 bits. 541 @type obj: float 542 @return: True if all the bits in the exponent are one. 543 @rtype: bool 544 @raise TypeError: If obj isn't a python float. 545 """ 546 547 result = False 548 549 # get the exponent as a byte array properly masked 550 expBytes = getExponentBytes(obj) 551 552 # check against masks to see if all the correct bits are set 553 if expBytes[0] == EXPONENT_ALL_ONES_BYTE_0 and expBytes[1] == EXPONENT_ALL_ONES_BYTE_1: 554 result = True 555 556 return result
557 558
559 -def isNaN(obj):
560 """Check to see if a python float is an IEEE-754 double not a number (NaN). 561 562 @param obj: Float object to check for not a number. 563 @type obj: float 564 @return: True if object is not a number. 565 @rtype: bool 566 @raise TypeError: If obj isn't a python float. 567 """ 568 569 # Catch None. 570 if obj == None: 571 return False 572 573 # bad result for code checking 574 result = None 575 576 # check to see if exponent is all ones (excluding sign bit) 577 # if exponent is not all ones this can't be a NaN 578 if not isExpAllOnes(obj): 579 result = False 580 else: 581 # get the mantissa as a byte array properly masked 582 manBytes = getMantissaBytes(obj) 583 584 # check if any of the unmasked mantissa bytes are not zero 585 # to be a NaN the mantissa must be non zero 586 for byte in manBytes: 587 if byte > 0: 588 result = True 589 break 590 # todo NOT NEEDED, UNITTEST!!!! 591 # check to see if the mantissa nibble that overlaps with the 592 #if (manBytes[6] & MANTISSA_NIBBLE_MASK) > 0: 593 # result = True 594 return result
595 596
597 -def isInf(obj):
598 """Check to see if a python float is an infinity. 599 600 The check returns true for either positive or negative infinities. 601 602 @param obj: Float object to check for infinity. 603 @type obj: float 604 @return: True if object is an infinity. 605 @rtype: bool 606 @raise TypeError: If obj isn't a python float. 607 """ 608 609 # Catch None. 610 if obj == None: 611 return False 612 613 # bad result for code checking 614 result = None 615 616 # check to see if exponent is all ones (excluding sign bit) 617 # if exponent is not all ones this can't be a Inf 618 if not isExpAllOnes(obj): 619 result = False 620 else: 621 # get the mantissa as a byte array properly masked 622 manBytes = getMantissaBytes(obj) 623 624 for byte in manBytes: 625 #check if any of the unmasked mantissa bytes are zero 626 # to be a NaN the mantissa must be zero 627 if byte > 0: 628 result = False 629 break 630 result = True 631 632 return result
633 634
635 -def isPosInf(obj):
636 """Check to see if a python float is positive infinity. 637 638 @param obj: Float object to check for positive infinity. 639 @type obj: float 640 @return: True if object is a positive infinity. 641 @rtype: bool 642 @raise TypeError: If obj isn't a python float. 643 """ 644 645 return isInf(obj) and isPositive(obj)
646 647
648 -def isNegInf(obj):
649 """Check to see if a python float is negative infinity. 650 651 @param obj: Float object to check for negative infinity. 652 @type obj: float 653 @return: True if object is a negative infinity. 654 @rtype: bool 655 @raise TypeError: If obj isn't a python float. 656 """ 657 658 return isInf(obj) and not isPositive(obj)
659 660
661 -def bitpatternToFloat(string, endian='big'):
662 """Convert a 64 bit IEEE-754 ascii bit pattern into a 64 bit Python float. 663 664 @param string: The ascii bit pattern repesenting the IEEE-754 float. 665 @type string: str 666 @param endian: The endianness of the bit pattern (can be 'big' or 'little'). 667 @type endian: str 668 @return: The 64 bit float corresponding to the IEEE-754 bit pattern. 669 @returntype: float 670 @raise TypeError: If 'string' is not a string, the length of the 'string' is not 64, or if 671 'string' does not consist solely of the characters '0' and '1'. 672 """ 673 674 # Test that the bit pattern is a string. 675 if not isinstance(string, str): 676 raise TypeError("The string argument '%s' is not a string." % string) 677 678 # Test the length of the bit pattern. 679 if len(string) != 64: 680 raise TypeError("The string '%s' is not 64 characters long." % string) 681 682 # Test that the string consists solely of zeros and ones. 683 for char in string: 684 if char not in ['0', '1']: 685 raise TypeError("The string '%s' should be composed solely of the characters '0' and '1'." % string) 686 687 # Reverse the byte order as neccessary. 688 if endian == 'big' and sys.byteorder == 'little': 689 string = string[::-1] 690 elif endian == 'little' and sys.byteorder == 'big': 691 string = string[::-1] 692 693 # Convert the bit pattern into a byte array (of integers). 694 bytes = [] 695 for i in range(8): 696 bytes.append(bitpatternToInt(string[i*8:i*8+8], endian=sys.byteorder)) 697 698 # Pack the byte array into a float and return it. 699 return packBytesAsPyFloat(bytes)
700 701
702 -def bitpatternToInt(string, endian='big'):
703 """Convert a bit pattern into its integer representation. 704 705 @param string: The ascii string repesenting binary data. 706 @type string: str 707 @param endian: The endianness of the bit pattern (can be 'big' or 'little'). 708 @type endian: str 709 @return: The integer value. 710 @returntype: int 711 """ 712 713 # Test that the bit pattern is a string. 714 if not isinstance(string, str): 715 raise TypeError("The string argument '%s' is not a string." % string) 716 717 # Test that the string consists solely of zeros and ones. 718 for char in string: 719 if char not in ['0', '1']: 720 raise TypeError("The string '%s' should be composed solely of the characters '0' and '1'." % string) 721 722 # Reverse the byte order as neccessary. 723 if endian == 'big' and sys.byteorder == 'little': 724 string = string[::-1] 725 elif endian == 'little' and sys.byteorder == 'big': 726 string = string[::-1] 727 728 # Calculate the integer corresponding to the string. 729 int_val = 0 730 for i in range(len(string)): 731 if int(string[i]): 732 int_val = int_val + 2**i 733 734 # Return the integer value. 735 return int_val
736 737 738 # IEEE-754 Constants. 739 ##################### 740 741 # The following bit patterns are to be read from right to left (big-endian). 742 # Hence bit positions 0 and 63 are to the far right and far left respectively. 743 PosZero = bitpatternToFloat('0000000000000000000000000000000000000000000000000000000000000000', endian='big') 744 NegZero = bitpatternToFloat('1000000000000000000000000000000000000000000000000000000000000000', endian='big') 745 PosEpsilonDenorm = bitpatternToFloat('0000000000000000000000000000000000000000000000000000000000000001', endian='big') 746 NegEpsilonDenorm = bitpatternToFloat('1000000000000000000000000000000000000000000000000000000000000001', endian='big') 747 PosEpsilonNorm = bitpatternToFloat('0000000000010000000000000000000000000000000000000000000000000001', endian='big') 748 NegEpsilonNorm = bitpatternToFloat('1000000000010000000000000000000000000000000000000000000000000001', endian='big') 749 PosMax = bitpatternToFloat('0111111111101111111111111111111111111111111111111111111111111111', endian='big') 750 NegMin = bitpatternToFloat('1111111111101111111111111111111111111111111111111111111111111111', endian='big') 751 PosInf = bitpatternToFloat('0111111111110000000000000000000000000000000000000000000000000000', endian='big') 752 NegInf = bitpatternToFloat('1111111111110000000000000000000000000000000000000000000000000000', endian='big') 753 PosNaN_A = bitpatternToFloat('0111111111110000000000000000000000000000001000000000000000000000', endian='big') 754 NegNaN_A = bitpatternToFloat('1111111111110000000000000000000000000000001000000000000000000000', endian='big') 755 PosNaN_B = bitpatternToFloat('0111111111110000000000000000011111111111111111111110000000000000', endian='big') 756 NegNaN_B = bitpatternToFloat('1111111111110000000000000000011111111111111111111110000000000000', endian='big') 757 PosNaN_C = bitpatternToFloat('0111111111110101010101010101010101010101010101010101010101010101', endian='big') 758 NegNaN_C = bitpatternToFloat('1111111111110101010101010101010101010101010101010101010101010101', endian='big') 759 PosNaN = PosNaN_C 760 NegNaN = NegNaN_C 761 762 #print("%-30s%-20.40g" % ("Pos zero: ", PosZero)) 763 #print("%-30s%-20.40g" % ("Neg zero: ", NegZero)) 764 #print("%-30s%-20.40g" % ("Pos epsilon denorm: ", PosEpsilonDenorm)) 765 #print("%-30s%-20.40g" % ("Neg epsilon denorm: ", NegEpsilonDenorm)) 766 #print("%-30s%-20.40g" % ("Pos epsilon norm: ", PosEpsilonNorm)) 767 #print("%-30s%-20.40g" % ("Neg epsilon norm: ", NegEpsilonNorm)) 768 #print("%-30s%-20.40g" % ("Max: ", PosMax)) 769 #print("%-30s%-20.40g" % ("Min: ", NegMin) 770 #print("%-30s%-20.40g" % ("Pos inf: ", PosInf))) 771 #print("%-30s%-20.40g" % ("Neg inf: ", NegInf)) 772 #print("%-30s%-20.40g" % ("Pos NaN (A): ", PosNaN_A)) 773 #print("%-30s%-20.40g" % ("Neg NaN (A): ", NegNaN_A)) 774 #print("%-30s%-20.40g" % ("Pos NaN (B): ", PosNaN_B)) 775 #print("%-30s%-20.40g" % ("Neg NaN (B): ", NegNaN_B)) 776 #print("%-30s%-20.40g" % ("Pos NaN (C): ", PosNaN_C)) 777 #print("%-30s%-20.40g" % ("Neg NaN (C): ", NegNaN_C)) 778