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

Source Code for Module lib.float

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