Advertisement
Guest User

Untitled

a guest
May 27th, 2019
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.57 KB | None | 0 0
  1. import struct
  2. import math
  3. import decimal
  4. from fractions import Fraction
  5.  
  6. def float_to_bits(f):
  7. bits = [(b>>i)%2 for b in struct.pack(">d", f) for i in range(7, -1, -1)]
  8. return "".join(str(b) for b in bits)
  9.  
  10. def bits_to_float(bits):
  11. result = 0
  12. for b in bits:
  13. result <<= 1
  14. result += int(b)
  15. return struct.unpack("d", struct.pack("Q", result))[0]
  16.  
  17. EXPONENT_OFFSET = 1023
  18. BASE = 2
  19. PRECISION = 53
  20.  
  21. regions = {
  22. "sign": slice(0, 1),
  23. "exponent": slice(1, 12),
  24. "mantissa": slice(12, 64)
  25. }
  26.  
  27. #normals
  28. test_cases = [math.pi, 1.0, 0.25, 123.456, -777.0]
  29. #denormals
  30. test_cases += [0.0, -0.0, 1.1125369292536007e-308]
  31. #specials
  32. test_cases += [float("nan"), float("inf"), float("-inf")]
  33.  
  34. for idx, f in enumerate(test_cases,1):
  35. print(f"Example #{idx}: {f}")
  36. bits = float_to_bits(f)
  37. print(f" Stored in memory as {bits}")
  38. for name, s in regions.items():
  39. label = f" {name} bit{'s' if s.stop-s.start>1 else ''}:"
  40. padding = " " * (20 + s.start - len(label))
  41. print(label, padding, bits[s])
  42. sign = 1 if bits[0] == "0" else -1
  43.  
  44. raw_exponent = int(bits[regions["exponent"]], 2)
  45. if raw_exponent == 0b11111111111:
  46. print(" an exponent of 0b11111111111 signals that the number is special -- either NAN or an infinity")
  47. if bits[regions["mantissa"]][0] == "1":
  48. print(" If the mantissa's leftmost bit is 1, the value is NaN.")
  49. else:
  50. print(" If the mantissa's leftmost bit is 0, the value is an infinity.")
  51. print(f" Taking the sign bit into account, the value is {'positive' if sign == 1 else 'negative'} infinity.")
  52. print("\n\n")
  53. continue
  54.  
  55. normal = raw_exponent != 0
  56. if normal:
  57. print(f" mantissa with implied `1` bit: 1{bits[regions['mantissa']]}")
  58. else:
  59. print(f" mantissa with implied `0` bit: 0{bits[regions['mantissa']]}")
  60.  
  61. print(f" raw exponent: {raw_exponent}")
  62.  
  63. if normal:
  64. exponent_bias = EXPONENT_OFFSET
  65. if not normal:
  66. exponent_bias = EXPONENT_OFFSET - 1
  67. print(f" a raw exponent of 00000000000 signals that the float is DENORMAL.")
  68. print(f" exponent bias for denormal numbers is {exponent_bias} instead of the usual {EXPONENT_OFFSET}")
  69. exponent = raw_exponent - exponent_bias
  70. print(f" actual exponent (subtracting exponent bias {exponent_bias} from raw): {exponent}")
  71. # mantissa = sum([Fraction(1, 2**i) for i, bit in enumerate(raw_mantissa,1) if bit=="1"], Fraction(1))
  72. # print(f" raw mantissa: 0b1.{raw_mantissa} \n calculated mantissa: {mantissa}")
  73. # value = mantissa * Fraction(BASE)**adjusted_exponent
  74. # print(f" final value: {value} ~= {float(value)}")
  75. raw_mantissa = int(bits[regions["mantissa"]], 2)
  76. if normal:
  77. mantissa = raw_mantissa + 2**(PRECISION-1)
  78. else:
  79. mantissa = raw_mantissa
  80. print(f" mantissa with implied bit: {mantissa}")
  81. print(f" final value formula: sign * (mantissa / b^(p-1)) * b^exponent")
  82. print(f" b (aka base) = {BASE}")
  83. print(f" p (aka precision) = {PRECISION}")
  84. print(f" final value = {sign} * ({mantissa} / {BASE}^{PRECISION-1}) * {BASE}^{exponent}")
  85. print(f" final value = {sign} * ({mantissa} / {BASE**(PRECISION-1)}) * {Fraction(BASE)**exponent}")
  86. result = sign * Fraction(mantissa, BASE**(PRECISION-1)) * Fraction(BASE)**exponent
  87. print(f" final value = {result}")
  88. if str(result) != str(decimal.Decimal(f)):
  89. print(f" final value = {decimal.Decimal(f)}")
  90. if str(float(result)) != str(decimal.Decimal(f)):
  91. print(f" final value ~= {float(result)}")
  92. print("\n\n")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement