Advertisement
Guest User

Untitled

a guest
May 5th, 2016
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.36 KB | None | 0 0
  1. # Examples of 32bit float's displayed as 64bit floats in CPython.
  2. 0.0005 -> 0.0005000000237487257
  3. 0.025 -> 0.02500000037252903
  4. 0.04 -> 0.03999999910593033
  5. 0.05 -> 0.05000000074505806
  6. 0.3 -> 0.30000001192092896
  7. 0.98 -> 0.9800000190734863
  8. 1.2 -> 1.2000000476837158
  9. 4096.3 -> 4096.2998046875
  10.  
  11. def as_float_32(f):
  12. from struct import pack, unpack
  13. return unpack("f", pack("f", f))[0]
  14.  
  15. print(0.025) # --> 0.025
  16. print(as_float_32(0.025)) # --> 0.02500000037252903
  17.  
  18. >>> x = "634278e13"
  19. >>> y = float(np.float32(x))
  20. >>> y
  21. 6.342780214942106e+18
  22. >>> "{:.6g}".format(y)
  23. '6.34278e+18'
  24.  
  25. >>> x = np.float32(3.14159265358979)
  26. >>> x
  27. 3.1415927
  28. >>> np.float32('{:.9g}'.format(x)) == x
  29. True
  30.  
  31. def original_string(x):
  32. for places in range(6, 10): # try 6, 7, 8, 9
  33. s = '{:.{}g}'.format(x, places)
  34. y = np.float32(s)
  35. if x == y:
  36. return s
  37. # If x was genuinely a float32, we should never get here.
  38. raise RuntimeError("We should never get here")
  39.  
  40. >>> original_string(0.02500000037252903)
  41. '0.025'
  42. >>> original_string(0.03999999910593033)
  43. '0.04'
  44. >>> original_string(0.05000000074505806)
  45. '0.05'
  46. >>> original_string(0.30000001192092896)
  47. '0.3'
  48. >>> original_string(0.9800000190734863)
  49. '0.98'
  50.  
  51. >>> x = 2.0**87
  52. >>> x
  53. 1.5474250491067253e+26
  54.  
  55. >>> s = '{:.8g}'.format(x)
  56. >>> s
  57. '1.547425e+26'
  58.  
  59. >>> np.float32(s) == x
  60. False
  61.  
  62. >>> np.float32('1.5474251e+26') == x
  63. True
  64.  
  65. >>> x = 2**-96.
  66. >>> x
  67. 1.262177448353619e-29
  68. >>> s = '{:.8g}'.format(x)
  69. >>> s
  70. '1.2621774e-29'
  71. >>> np.float32(s) == x
  72. False
  73. >>> np.float32('1.2621775e-29') == x
  74. True
  75.  
  76. def original_string(x):
  77. """
  78. Given a single-precision positive normal value x,
  79. return the shortest decimal numeric string which produces x.
  80. """
  81. # Deal with the three awkward cases.
  82. if x == 2**-96.:
  83. return '1.2621775e-29'
  84. elif x == 2**87:
  85. return '1.5474251e+26'
  86. elif x == 2**90:
  87. return '1.2379401e+27'
  88.  
  89. for places in range(6, 10): # try 6, 7, 8, 9
  90. s = '{:.{}g}'.format(x, places)
  91. y = np.float32(s)
  92. if x == y:
  93. return s
  94. # If x was genuinely a float32, we should never get here.
  95. raise RuntimeError("We should never get here")
  96.  
  97. #!/usr/bin/env python
  98. # -*- coding: utf-8 -*-
  99.  
  100. from decimal import Decimal
  101.  
  102. data = (
  103. 0.02500000037252903,
  104. 0.03999999910593033,
  105. 0.05000000074505806,
  106. 0.30000001192092896,
  107. 0.9800000190734863,
  108. )
  109.  
  110. for f in data:
  111. dec = Decimal(f).quantize(Decimal('1.0000000')).normalize()
  112. print("Original %s -> %s" % (f, dec))
  113.  
  114. Original 0.0250000003725 -> 0.025
  115. Original 0.0399999991059 -> 0.04
  116. Original 0.0500000007451 -> 0.05
  117. Original 0.300000011921 -> 0.3
  118. Original 0.980000019073 -> 0.98
  119.  
  120. def round_float_32(f):
  121. from struct import pack, unpack
  122. return unpack("f", pack("f", f))[0]
  123.  
  124.  
  125. def as_float_low_precision_repr(f, round_fn):
  126. f_round = round_fn(f)
  127. f_str = repr(f)
  128. f_str_frac = f_str.partition(".")[2]
  129. if not f_str_frac:
  130. return f_str
  131. for i in range(1, len(f_str_frac)):
  132. f_test = round(f, i)
  133. f_test_round = round_fn(f_test)
  134. if f_test_round == f_round:
  135. return "%.*f" % (i, f_test)
  136. return f_str
  137.  
  138. # ----
  139.  
  140. data = (
  141. 0.02500000037252903,
  142. 0.03999999910593033,
  143. 0.05000000074505806,
  144. 0.30000001192092896,
  145. 0.9800000190734863,
  146. 1.2000000476837158,
  147. 4096.2998046875,
  148. )
  149.  
  150. for f in data:
  151. f_as_float_32 = as_float_low_precision_repr(f, round_float_32)
  152. print("%s -> %s" % (f, f_as_float_32))
  153.  
  154. 0.02500000037252903 -> 0.025
  155. 0.03999999910593033 -> 0.04
  156. 0.05000000074505806 -> 0.05
  157. 0.30000001192092896 -> 0.3
  158. 0.9800000190734863 -> 0.98
  159. 1.2000000476837158 -> 1.2
  160. 4096.2998046875 -> 4096.3
  161.  
  162. a = 0.1
  163. a.as_integer_ratio()
  164. (3602879701896397, 36028797018963968)
  165.  
  166. # A value in python floating point precision
  167. a = 0.1
  168. # The value as ratio of integers
  169. b = a.as_integer_ratio()
  170.  
  171. import numpy as np
  172. # Force the result to have some precision:
  173. res = np.array([0], dtype=np.float16)
  174. np.true_divide(b[0], b[1], res)
  175. print(res)
  176. # Compare that two the wanted result when inputting 0.01
  177. np.true_divide(1, 10, res)
  178. print(res)
  179.  
  180. # Other precisions:
  181. res = np.array([0], dtype=np.float32)
  182. np.true_divide(b[0], b[1], res)
  183. print(res)
  184. res = np.array([0], dtype=np.float64)
  185. np.true_divide(b[0], b[1], res)
  186. print(res)
  187.  
  188. [ 0.09997559] # Float16 with integer-ratio
  189. [ 0.09997559] # Float16 reference
  190. [ 0.1] # Float32
  191. [ 0.1] # Float64
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement