123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- from mpmath import *
- from mpmath.libmp import *
- import random
- def test_fractional_pow():
- mp.dps = 15
- assert mpf(16) ** 2.5 == 1024
- assert mpf(64) ** 0.5 == 8
- assert mpf(64) ** -0.5 == 0.125
- assert mpf(16) ** -2.5 == 0.0009765625
- assert (mpf(10) ** 0.5).ae(3.1622776601683791)
- assert (mpf(10) ** 2.5).ae(316.2277660168379)
- assert (mpf(10) ** -0.5).ae(0.31622776601683794)
- assert (mpf(10) ** -2.5).ae(0.0031622776601683794)
- assert (mpf(10) ** 0.3).ae(1.9952623149688795)
- assert (mpf(10) ** -0.3).ae(0.50118723362727224)
- def test_pow_integer_direction():
- """
- Test that inexact integer powers are rounded in the right
- direction.
- """
- random.seed(1234)
- for prec in [10, 53, 200]:
- for i in range(50):
- a = random.randint(1<<(prec-1), 1<<prec)
- b = random.randint(2, 100)
- ab = a**b
- # note: could actually be exact, but that's very unlikely!
- assert to_int(mpf_pow(from_int(a), from_int(b), prec, round_down)) < ab
- assert to_int(mpf_pow(from_int(a), from_int(b), prec, round_up)) > ab
- def test_pow_epsilon_rounding():
- """
- Stress test directed rounding for powers with integer exponents.
- Basically, we look at the following cases:
- >>> 1.0001 ** -5 # doctest: +SKIP
- 0.99950014996500702
- >>> 0.9999 ** -5 # doctest: +SKIP
- 1.000500150035007
- >>> (-1.0001) ** -5 # doctest: +SKIP
- -0.99950014996500702
- >>> (-0.9999) ** -5 # doctest: +SKIP
- -1.000500150035007
- >>> 1.0001 ** -6 # doctest: +SKIP
- 0.99940020994401269
- >>> 0.9999 ** -6 # doctest: +SKIP
- 1.0006002100560125
- >>> (-1.0001) ** -6 # doctest: +SKIP
- 0.99940020994401269
- >>> (-0.9999) ** -6 # doctest: +SKIP
- 1.0006002100560125
- etc.
- We run the tests with values a very small epsilon away from 1:
- small enough that the result is indistinguishable from 1 when
- rounded to nearest at the output precision. We check that the
- result is not erroneously rounded to 1 in cases where the
- rounding should be done strictly away from 1.
- """
- def powr(x, n, r):
- return make_mpf(mpf_pow_int(x._mpf_, n, mp.prec, r))
- for (inprec, outprec) in [(100, 20), (5000, 3000)]:
- mp.prec = inprec
- pos10001 = mpf(1) + mpf(2)**(-inprec+5)
- pos09999 = mpf(1) - mpf(2)**(-inprec+5)
- neg10001 = -pos10001
- neg09999 = -pos09999
- mp.prec = outprec
- r = round_up
- assert powr(pos10001, 5, r) > 1
- assert powr(pos09999, 5, r) == 1
- assert powr(neg10001, 5, r) < -1
- assert powr(neg09999, 5, r) == -1
- assert powr(pos10001, 6, r) > 1
- assert powr(pos09999, 6, r) == 1
- assert powr(neg10001, 6, r) > 1
- assert powr(neg09999, 6, r) == 1
- assert powr(pos10001, -5, r) == 1
- assert powr(pos09999, -5, r) > 1
- assert powr(neg10001, -5, r) == -1
- assert powr(neg09999, -5, r) < -1
- assert powr(pos10001, -6, r) == 1
- assert powr(pos09999, -6, r) > 1
- assert powr(neg10001, -6, r) == 1
- assert powr(neg09999, -6, r) > 1
- r = round_down
- assert powr(pos10001, 5, r) == 1
- assert powr(pos09999, 5, r) < 1
- assert powr(neg10001, 5, r) == -1
- assert powr(neg09999, 5, r) > -1
- assert powr(pos10001, 6, r) == 1
- assert powr(pos09999, 6, r) < 1
- assert powr(neg10001, 6, r) == 1
- assert powr(neg09999, 6, r) < 1
- assert powr(pos10001, -5, r) < 1
- assert powr(pos09999, -5, r) == 1
- assert powr(neg10001, -5, r) > -1
- assert powr(neg09999, -5, r) == -1
- assert powr(pos10001, -6, r) < 1
- assert powr(pos09999, -6, r) == 1
- assert powr(neg10001, -6, r) < 1
- assert powr(neg09999, -6, r) == 1
- r = round_ceiling
- assert powr(pos10001, 5, r) > 1
- assert powr(pos09999, 5, r) == 1
- assert powr(neg10001, 5, r) == -1
- assert powr(neg09999, 5, r) > -1
- assert powr(pos10001, 6, r) > 1
- assert powr(pos09999, 6, r) == 1
- assert powr(neg10001, 6, r) > 1
- assert powr(neg09999, 6, r) == 1
- assert powr(pos10001, -5, r) == 1
- assert powr(pos09999, -5, r) > 1
- assert powr(neg10001, -5, r) > -1
- assert powr(neg09999, -5, r) == -1
- assert powr(pos10001, -6, r) == 1
- assert powr(pos09999, -6, r) > 1
- assert powr(neg10001, -6, r) == 1
- assert powr(neg09999, -6, r) > 1
- r = round_floor
- assert powr(pos10001, 5, r) == 1
- assert powr(pos09999, 5, r) < 1
- assert powr(neg10001, 5, r) < -1
- assert powr(neg09999, 5, r) == -1
- assert powr(pos10001, 6, r) == 1
- assert powr(pos09999, 6, r) < 1
- assert powr(neg10001, 6, r) == 1
- assert powr(neg09999, 6, r) < 1
- assert powr(pos10001, -5, r) < 1
- assert powr(pos09999, -5, r) == 1
- assert powr(neg10001, -5, r) == -1
- assert powr(neg09999, -5, r) < -1
- assert powr(pos10001, -6, r) < 1
- assert powr(pos09999, -6, r) == 1
- assert powr(neg10001, -6, r) < 1
- assert powr(neg09999, -6, r) == 1
- mp.dps = 15
|