test_bitwise.py 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. """
  2. Test bit-level integer and mpf operations
  3. """
  4. from mpmath import *
  5. from mpmath.libmp import *
  6. def test_bitcount():
  7. assert bitcount(0) == 0
  8. assert bitcount(1) == 1
  9. assert bitcount(7) == 3
  10. assert bitcount(8) == 4
  11. assert bitcount(2**100) == 101
  12. assert bitcount(2**100-1) == 100
  13. def test_trailing():
  14. assert trailing(0) == 0
  15. assert trailing(1) == 0
  16. assert trailing(2) == 1
  17. assert trailing(7) == 0
  18. assert trailing(8) == 3
  19. assert trailing(2**100) == 100
  20. assert trailing(2**100-1) == 0
  21. def test_round_down():
  22. assert from_man_exp(0, -4, 4, round_down)[:3] == (0, 0, 0)
  23. assert from_man_exp(0xf0, -4, 4, round_down)[:3] == (0, 15, 0)
  24. assert from_man_exp(0xf1, -4, 4, round_down)[:3] == (0, 15, 0)
  25. assert from_man_exp(0xff, -4, 4, round_down)[:3] == (0, 15, 0)
  26. assert from_man_exp(-0xf0, -4, 4, round_down)[:3] == (1, 15, 0)
  27. assert from_man_exp(-0xf1, -4, 4, round_down)[:3] == (1, 15, 0)
  28. assert from_man_exp(-0xff, -4, 4, round_down)[:3] == (1, 15, 0)
  29. def test_round_up():
  30. assert from_man_exp(0, -4, 4, round_up)[:3] == (0, 0, 0)
  31. assert from_man_exp(0xf0, -4, 4, round_up)[:3] == (0, 15, 0)
  32. assert from_man_exp(0xf1, -4, 4, round_up)[:3] == (0, 1, 4)
  33. assert from_man_exp(0xff, -4, 4, round_up)[:3] == (0, 1, 4)
  34. assert from_man_exp(-0xf0, -4, 4, round_up)[:3] == (1, 15, 0)
  35. assert from_man_exp(-0xf1, -4, 4, round_up)[:3] == (1, 1, 4)
  36. assert from_man_exp(-0xff, -4, 4, round_up)[:3] == (1, 1, 4)
  37. def test_round_floor():
  38. assert from_man_exp(0, -4, 4, round_floor)[:3] == (0, 0, 0)
  39. assert from_man_exp(0xf0, -4, 4, round_floor)[:3] == (0, 15, 0)
  40. assert from_man_exp(0xf1, -4, 4, round_floor)[:3] == (0, 15, 0)
  41. assert from_man_exp(0xff, -4, 4, round_floor)[:3] == (0, 15, 0)
  42. assert from_man_exp(-0xf0, -4, 4, round_floor)[:3] == (1, 15, 0)
  43. assert from_man_exp(-0xf1, -4, 4, round_floor)[:3] == (1, 1, 4)
  44. assert from_man_exp(-0xff, -4, 4, round_floor)[:3] == (1, 1, 4)
  45. def test_round_ceiling():
  46. assert from_man_exp(0, -4, 4, round_ceiling)[:3] == (0, 0, 0)
  47. assert from_man_exp(0xf0, -4, 4, round_ceiling)[:3] == (0, 15, 0)
  48. assert from_man_exp(0xf1, -4, 4, round_ceiling)[:3] == (0, 1, 4)
  49. assert from_man_exp(0xff, -4, 4, round_ceiling)[:3] == (0, 1, 4)
  50. assert from_man_exp(-0xf0, -4, 4, round_ceiling)[:3] == (1, 15, 0)
  51. assert from_man_exp(-0xf1, -4, 4, round_ceiling)[:3] == (1, 15, 0)
  52. assert from_man_exp(-0xff, -4, 4, round_ceiling)[:3] == (1, 15, 0)
  53. def test_round_nearest():
  54. assert from_man_exp(0, -4, 4, round_nearest)[:3] == (0, 0, 0)
  55. assert from_man_exp(0xf0, -4, 4, round_nearest)[:3] == (0, 15, 0)
  56. assert from_man_exp(0xf7, -4, 4, round_nearest)[:3] == (0, 15, 0)
  57. assert from_man_exp(0xf8, -4, 4, round_nearest)[:3] == (0, 1, 4) # 1111.1000 -> 10000.0
  58. assert from_man_exp(0xf9, -4, 4, round_nearest)[:3] == (0, 1, 4) # 1111.1001 -> 10000.0
  59. assert from_man_exp(0xe8, -4, 4, round_nearest)[:3] == (0, 7, 1) # 1110.1000 -> 1110.0
  60. assert from_man_exp(0xe9, -4, 4, round_nearest)[:3] == (0, 15, 0) # 1110.1001 -> 1111.0
  61. assert from_man_exp(-0xf0, -4, 4, round_nearest)[:3] == (1, 15, 0)
  62. assert from_man_exp(-0xf7, -4, 4, round_nearest)[:3] == (1, 15, 0)
  63. assert from_man_exp(-0xf8, -4, 4, round_nearest)[:3] == (1, 1, 4)
  64. assert from_man_exp(-0xf9, -4, 4, round_nearest)[:3] == (1, 1, 4)
  65. assert from_man_exp(-0xe8, -4, 4, round_nearest)[:3] == (1, 7, 1)
  66. assert from_man_exp(-0xe9, -4, 4, round_nearest)[:3] == (1, 15, 0)
  67. def test_rounding_bugs():
  68. # 1 less than power-of-two cases
  69. assert from_man_exp(72057594037927935, -56, 53, round_up) == (0, 1, 0, 1)
  70. assert from_man_exp(73786976294838205979, -65, 53, round_nearest) == (0, 1, 1, 1)
  71. assert from_man_exp(31, 0, 4, round_up) == (0, 1, 5, 1)
  72. assert from_man_exp(-31, 0, 4, round_floor) == (1, 1, 5, 1)
  73. assert from_man_exp(255, 0, 7, round_up) == (0, 1, 8, 1)
  74. assert from_man_exp(-255, 0, 7, round_floor) == (1, 1, 8, 1)
  75. def test_rounding_issue_200():
  76. a = from_man_exp(9867,-100)
  77. b = from_man_exp(9867,-200)
  78. c = from_man_exp(-1,0)
  79. z = (1, 1023, -10, 10)
  80. assert mpf_add(a, c, 10, 'd') == z
  81. assert mpf_add(b, c, 10, 'd') == z
  82. assert mpf_add(c, a, 10, 'd') == z
  83. assert mpf_add(c, b, 10, 'd') == z
  84. def test_perturb():
  85. a = fone
  86. b = from_float(0.99999999999999989)
  87. c = from_float(1.0000000000000002)
  88. assert mpf_perturb(a, 0, 53, round_nearest) == a
  89. assert mpf_perturb(a, 1, 53, round_nearest) == a
  90. assert mpf_perturb(a, 0, 53, round_up) == c
  91. assert mpf_perturb(a, 0, 53, round_ceiling) == c
  92. assert mpf_perturb(a, 0, 53, round_down) == a
  93. assert mpf_perturb(a, 0, 53, round_floor) == a
  94. assert mpf_perturb(a, 1, 53, round_up) == a
  95. assert mpf_perturb(a, 1, 53, round_ceiling) == a
  96. assert mpf_perturb(a, 1, 53, round_down) == b
  97. assert mpf_perturb(a, 1, 53, round_floor) == b
  98. a = mpf_neg(a)
  99. b = mpf_neg(b)
  100. c = mpf_neg(c)
  101. assert mpf_perturb(a, 0, 53, round_nearest) == a
  102. assert mpf_perturb(a, 1, 53, round_nearest) == a
  103. assert mpf_perturb(a, 0, 53, round_up) == a
  104. assert mpf_perturb(a, 0, 53, round_floor) == a
  105. assert mpf_perturb(a, 0, 53, round_down) == b
  106. assert mpf_perturb(a, 0, 53, round_ceiling) == b
  107. assert mpf_perturb(a, 1, 53, round_up) == c
  108. assert mpf_perturb(a, 1, 53, round_floor) == c
  109. assert mpf_perturb(a, 1, 53, round_down) == a
  110. assert mpf_perturb(a, 1, 53, round_ceiling) == a
  111. def test_add_exact():
  112. ff = from_float
  113. assert mpf_add(ff(3.0), ff(2.5)) == ff(5.5)
  114. assert mpf_add(ff(3.0), ff(-2.5)) == ff(0.5)
  115. assert mpf_add(ff(-3.0), ff(2.5)) == ff(-0.5)
  116. assert mpf_add(ff(-3.0), ff(-2.5)) == ff(-5.5)
  117. assert mpf_sub(mpf_add(fone, ff(1e-100)), fone) == ff(1e-100)
  118. assert mpf_sub(mpf_add(ff(1e-100), fone), fone) == ff(1e-100)
  119. assert mpf_sub(mpf_add(fone, ff(-1e-100)), fone) == ff(-1e-100)
  120. assert mpf_sub(mpf_add(ff(-1e-100), fone), fone) == ff(-1e-100)
  121. assert mpf_add(fone, fzero) == fone
  122. assert mpf_add(fzero, fone) == fone
  123. assert mpf_add(fzero, fzero) == fzero
  124. def test_long_exponent_shifts():
  125. mp.dps = 15
  126. # Check for possible bugs due to exponent arithmetic overflow
  127. # in a C implementation
  128. x = mpf(1)
  129. for p in [32, 64]:
  130. a = ldexp(1,2**(p-1))
  131. b = ldexp(1,2**p)
  132. c = ldexp(1,2**(p+1))
  133. d = ldexp(1,-2**(p-1))
  134. e = ldexp(1,-2**p)
  135. f = ldexp(1,-2**(p+1))
  136. assert (x+a) == a
  137. assert (x+b) == b
  138. assert (x+c) == c
  139. assert (x+d) == x
  140. assert (x+e) == x
  141. assert (x+f) == x
  142. assert (a+x) == a
  143. assert (b+x) == b
  144. assert (c+x) == c
  145. assert (d+x) == x
  146. assert (e+x) == x
  147. assert (f+x) == x
  148. assert (x-a) == -a
  149. assert (x-b) == -b
  150. assert (x-c) == -c
  151. assert (x-d) == x
  152. assert (x-e) == x
  153. assert (x-f) == x
  154. assert (a-x) == a
  155. assert (b-x) == b
  156. assert (c-x) == c
  157. assert (d-x) == -x
  158. assert (e-x) == -x
  159. assert (f-x) == -x
  160. def test_float_rounding():
  161. mp.prec = 64
  162. for x in [mpf(1), mpf(1)+eps, mpf(1)-eps, -mpf(1)+eps, -mpf(1)-eps]:
  163. fa = float(x)
  164. fb = float(fadd(x,0,prec=53,rounding='n'))
  165. assert fa == fb
  166. z = mpc(x,x)
  167. ca = complex(z)
  168. cb = complex(fadd(z,0,prec=53,rounding='n'))
  169. assert ca == cb
  170. for rnd in ['n', 'd', 'u', 'f', 'c']:
  171. fa = to_float(x._mpf_, rnd=rnd)
  172. fb = to_float(fadd(x,0,prec=53,rounding=rnd)._mpf_, rnd=rnd)
  173. assert fa == fb
  174. mp.prec = 53