test_convert.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. import random
  2. from mpmath import *
  3. from mpmath.libmp import *
  4. def test_basic_string():
  5. """
  6. Test basic string conversion
  7. """
  8. mp.dps = 15
  9. assert mpf('3') == mpf('3.0') == mpf('0003.') == mpf('0.03e2') == mpf(3.0)
  10. assert mpf('30') == mpf('30.0') == mpf('00030.') == mpf(30.0)
  11. for i in range(10):
  12. for j in range(10):
  13. assert mpf('%ie%i' % (i,j)) == i * 10**j
  14. assert str(mpf('25000.0')) == '25000.0'
  15. assert str(mpf('2500.0')) == '2500.0'
  16. assert str(mpf('250.0')) == '250.0'
  17. assert str(mpf('25.0')) == '25.0'
  18. assert str(mpf('2.5')) == '2.5'
  19. assert str(mpf('0.25')) == '0.25'
  20. assert str(mpf('0.025')) == '0.025'
  21. assert str(mpf('0.0025')) == '0.0025'
  22. assert str(mpf('0.00025')) == '0.00025'
  23. assert str(mpf('0.000025')) == '2.5e-5'
  24. assert str(mpf(0)) == '0.0'
  25. assert str(mpf('2.5e1000000000000000000000')) == '2.5e+1000000000000000000000'
  26. assert str(mpf('2.6e-1000000000000000000000')) == '2.6e-1000000000000000000000'
  27. assert str(mpf(1.23402834e-15)) == '1.23402834e-15'
  28. assert str(mpf(-1.23402834e-15)) == '-1.23402834e-15'
  29. assert str(mpf(-1.2344e-15)) == '-1.2344e-15'
  30. assert repr(mpf(-1.2344e-15)) == "mpf('-1.2343999999999999e-15')"
  31. assert str(mpf("2163048125L")) == '2163048125.0'
  32. assert str(mpf("-2163048125l")) == '-2163048125.0'
  33. assert str(mpf("-2163048125L/1088391168")) == '-1.98738118113799'
  34. assert str(mpf("2163048125/1088391168l")) == '1.98738118113799'
  35. def test_pretty():
  36. mp.pretty = True
  37. assert repr(mpf(2.5)) == '2.5'
  38. assert repr(mpc(2.5,3.5)) == '(2.5 + 3.5j)'
  39. mp.pretty = False
  40. iv.pretty = True
  41. assert repr(mpi(2.5,3.5)) == '[2.5, 3.5]'
  42. iv.pretty = False
  43. def test_str_whitespace():
  44. assert mpf('1.26 ') == 1.26
  45. def test_unicode():
  46. mp.dps = 15
  47. try:
  48. unicode = unicode
  49. except NameError:
  50. unicode = str
  51. assert mpf(unicode('2.76')) == 2.76
  52. assert mpf(unicode('inf')) == inf
  53. def test_str_format():
  54. assert to_str(from_float(0.1),15,strip_zeros=False) == '0.100000000000000'
  55. assert to_str(from_float(0.0),15,show_zero_exponent=True) == '0.0e+0'
  56. assert to_str(from_float(0.0),0,show_zero_exponent=True) == '.0e+0'
  57. assert to_str(from_float(0.0),0,show_zero_exponent=False) == '.0'
  58. assert to_str(from_float(0.0),1,show_zero_exponent=True) == '0.0e+0'
  59. assert to_str(from_float(0.0),1,show_zero_exponent=False) == '0.0'
  60. assert to_str(from_float(1.23),3,show_zero_exponent=True) == '1.23e+0'
  61. assert to_str(from_float(1.23456789000000e-2),15,strip_zeros=False,min_fixed=0,max_fixed=0) == '1.23456789000000e-2'
  62. assert to_str(from_float(1.23456789000000e+2),15,strip_zeros=False,min_fixed=0,max_fixed=0) == '1.23456789000000e+2'
  63. assert to_str(from_float(2.1287e14), 15, max_fixed=1000) == '212870000000000.0'
  64. assert to_str(from_float(2.1287e15), 15, max_fixed=1000) == '2128700000000000.0'
  65. assert to_str(from_float(2.1287e16), 15, max_fixed=1000) == '21287000000000000.0'
  66. assert to_str(from_float(2.1287e30), 15, max_fixed=1000) == '2128700000000000000000000000000.0'
  67. def test_tight_string_conversion():
  68. mp.dps = 15
  69. # In an old version, '0.5' wasn't recognized as representing
  70. # an exact binary number and was erroneously rounded up or down
  71. assert from_str('0.5', 10, round_floor) == fhalf
  72. assert from_str('0.5', 10, round_ceiling) == fhalf
  73. def test_eval_repr_invariant():
  74. """Test that eval(repr(x)) == x"""
  75. random.seed(123)
  76. for dps in [10, 15, 20, 50, 100]:
  77. mp.dps = dps
  78. for i in range(1000):
  79. a = mpf(random.random())**0.5 * 10**random.randint(-100, 100)
  80. assert eval(repr(a)) == a
  81. mp.dps = 15
  82. def test_str_bugs():
  83. mp.dps = 15
  84. # Decimal rounding used to give the wrong exponent in some cases
  85. assert str(mpf('1e600')) == '1.0e+600'
  86. assert str(mpf('1e10000')) == '1.0e+10000'
  87. def test_str_prec0():
  88. assert to_str(from_float(1.234), 0) == '.0e+0'
  89. assert to_str(from_float(1e-15), 0) == '.0e-15'
  90. assert to_str(from_float(1e+15), 0) == '.0e+15'
  91. assert to_str(from_float(-1e-15), 0) == '-.0e-15'
  92. assert to_str(from_float(-1e+15), 0) == '-.0e+15'
  93. def test_convert_rational():
  94. mp.dps = 15
  95. assert from_rational(30, 5, 53, round_nearest) == (0, 3, 1, 2)
  96. assert from_rational(-7, 4, 53, round_nearest) == (1, 7, -2, 3)
  97. assert to_rational((0, 1, -1, 1)) == (1, 2)
  98. def test_custom_class():
  99. class mympf:
  100. @property
  101. def _mpf_(self):
  102. return mpf(3.5)._mpf_
  103. class mympc:
  104. @property
  105. def _mpc_(self):
  106. return mpf(3.5)._mpf_, mpf(2.5)._mpf_
  107. assert mpf(2) + mympf() == 5.5
  108. assert mympf() + mpf(2) == 5.5
  109. assert mpf(mympf()) == 3.5
  110. assert mympc() + mpc(2) == mpc(5.5, 2.5)
  111. assert mpc(2) + mympc() == mpc(5.5, 2.5)
  112. assert mpc(mympc()) == (3.5+2.5j)
  113. def test_conversion_methods():
  114. class SomethingRandom:
  115. pass
  116. class SomethingReal:
  117. def _mpmath_(self, prec, rounding):
  118. return mp.make_mpf(from_str('1.3', prec, rounding))
  119. class SomethingComplex:
  120. def _mpmath_(self, prec, rounding):
  121. return mp.make_mpc((from_str('1.3', prec, rounding), \
  122. from_str('1.7', prec, rounding)))
  123. x = mpf(3)
  124. z = mpc(3)
  125. a = SomethingRandom()
  126. y = SomethingReal()
  127. w = SomethingComplex()
  128. for d in [15, 45]:
  129. mp.dps = d
  130. assert (x+y).ae(mpf('4.3'))
  131. assert (y+x).ae(mpf('4.3'))
  132. assert (x+w).ae(mpc('4.3', '1.7'))
  133. assert (w+x).ae(mpc('4.3', '1.7'))
  134. assert (z+y).ae(mpc('4.3'))
  135. assert (y+z).ae(mpc('4.3'))
  136. assert (z+w).ae(mpc('4.3', '1.7'))
  137. assert (w+z).ae(mpc('4.3', '1.7'))
  138. x-y; y-x; x-w; w-x; z-y; y-z; z-w; w-z
  139. x*y; y*x; x*w; w*x; z*y; y*z; z*w; w*z
  140. x/y; y/x; x/w; w/x; z/y; y/z; z/w; w/z
  141. x**y; y**x; x**w; w**x; z**y; y**z; z**w; w**z
  142. x==y; y==x; x==w; w==x; z==y; y==z; z==w; w==z
  143. mp.dps = 15
  144. assert x.__add__(a) is NotImplemented
  145. assert x.__radd__(a) is NotImplemented
  146. assert x.__lt__(a) is NotImplemented
  147. assert x.__gt__(a) is NotImplemented
  148. assert x.__le__(a) is NotImplemented
  149. assert x.__ge__(a) is NotImplemented
  150. assert x.__eq__(a) is NotImplemented
  151. assert x.__ne__(a) is NotImplemented
  152. # implementation detail
  153. if hasattr(x, "__cmp__"):
  154. assert x.__cmp__(a) is NotImplemented
  155. assert x.__sub__(a) is NotImplemented
  156. assert x.__rsub__(a) is NotImplemented
  157. assert x.__mul__(a) is NotImplemented
  158. assert x.__rmul__(a) is NotImplemented
  159. assert x.__div__(a) is NotImplemented
  160. assert x.__rdiv__(a) is NotImplemented
  161. assert x.__mod__(a) is NotImplemented
  162. assert x.__rmod__(a) is NotImplemented
  163. assert x.__pow__(a) is NotImplemented
  164. assert x.__rpow__(a) is NotImplemented
  165. assert z.__add__(a) is NotImplemented
  166. assert z.__radd__(a) is NotImplemented
  167. assert z.__eq__(a) is NotImplemented
  168. assert z.__ne__(a) is NotImplemented
  169. assert z.__sub__(a) is NotImplemented
  170. assert z.__rsub__(a) is NotImplemented
  171. assert z.__mul__(a) is NotImplemented
  172. assert z.__rmul__(a) is NotImplemented
  173. assert z.__div__(a) is NotImplemented
  174. assert z.__rdiv__(a) is NotImplemented
  175. assert z.__pow__(a) is NotImplemented
  176. assert z.__rpow__(a) is NotImplemented
  177. def test_mpmathify():
  178. assert mpmathify('1/2') == 0.5
  179. assert mpmathify('(1.0+1.0j)') == mpc(1, 1)
  180. assert mpmathify('(1.2e-10 - 3.4e5j)') == mpc('1.2e-10', '-3.4e5')
  181. assert mpmathify('1j') == mpc(1j)
  182. def test_compatibility():
  183. try:
  184. import numpy as np
  185. from fractions import Fraction
  186. from decimal import Decimal
  187. import decimal
  188. except ImportError:
  189. return
  190. # numpy types
  191. for nptype in np.core.numerictypes.typeDict.values():
  192. if issubclass(nptype, np.complexfloating):
  193. x = nptype(complex(0.5, -0.5))
  194. elif issubclass(nptype, np.floating):
  195. x = nptype(0.5)
  196. elif issubclass(nptype, np.integer):
  197. x = nptype(2)
  198. # Handle the weird types
  199. try: diff = np.abs(type(np.sqrt(x))(sqrt(x)) - np.sqrt(x))
  200. except: continue
  201. assert diff < 2.0**-53
  202. #Fraction and Decimal
  203. oldprec = mp.prec
  204. mp.prec = 1000
  205. decimal.getcontext().prec = mp.dps
  206. assert sqrt(Fraction(2, 3)).ae(sqrt(mpf('2/3')))
  207. assert sqrt(Decimal(2)/Decimal(3)).ae(sqrt(mpf('2/3')))
  208. mp.prec = oldprec