Spaces:
Running
Running
File size: 5,340 Bytes
b200bda |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
from mpmath.libmp import *
from mpmath import mpf, mp
from random import randint, choice, seed
all_modes = [round_floor, round_ceiling, round_down, round_up, round_nearest]
fb = from_bstr
fi = from_int
ff = from_float
def test_div_1_3():
a = fi(1)
b = fi(3)
c = fi(-1)
# floor rounds down, ceiling rounds up
assert mpf_div(a, b, 7, round_floor) == fb('0.01010101')
assert mpf_div(a, b, 7, round_ceiling) == fb('0.01010110')
assert mpf_div(a, b, 7, round_down) == fb('0.01010101')
assert mpf_div(a, b, 7, round_up) == fb('0.01010110')
assert mpf_div(a, b, 7, round_nearest) == fb('0.01010101')
# floor rounds up, ceiling rounds down
assert mpf_div(c, b, 7, round_floor) == fb('-0.01010110')
assert mpf_div(c, b, 7, round_ceiling) == fb('-0.01010101')
assert mpf_div(c, b, 7, round_down) == fb('-0.01010101')
assert mpf_div(c, b, 7, round_up) == fb('-0.01010110')
assert mpf_div(c, b, 7, round_nearest) == fb('-0.01010101')
def test_mpf_divi_1_3():
a = 1
b = fi(3)
c = -1
assert mpf_rdiv_int(a, b, 7, round_floor) == fb('0.01010101')
assert mpf_rdiv_int(a, b, 7, round_ceiling) == fb('0.01010110')
assert mpf_rdiv_int(a, b, 7, round_down) == fb('0.01010101')
assert mpf_rdiv_int(a, b, 7, round_up) == fb('0.01010110')
assert mpf_rdiv_int(a, b, 7, round_nearest) == fb('0.01010101')
assert mpf_rdiv_int(c, b, 7, round_floor) == fb('-0.01010110')
assert mpf_rdiv_int(c, b, 7, round_ceiling) == fb('-0.01010101')
assert mpf_rdiv_int(c, b, 7, round_down) == fb('-0.01010101')
assert mpf_rdiv_int(c, b, 7, round_up) == fb('-0.01010110')
assert mpf_rdiv_int(c, b, 7, round_nearest) == fb('-0.01010101')
def test_div_300():
q = fi(1000000)
a = fi(300499999) # a/q is a little less than a half-integer
b = fi(300500000) # b/q exactly a half-integer
c = fi(300500001) # c/q is a little more than a half-integer
# Check nearest integer rounding (prec=9 as 2**8 < 300 < 2**9)
assert mpf_div(a, q, 9, round_down) == fi(300)
assert mpf_div(b, q, 9, round_down) == fi(300)
assert mpf_div(c, q, 9, round_down) == fi(300)
assert mpf_div(a, q, 9, round_up) == fi(301)
assert mpf_div(b, q, 9, round_up) == fi(301)
assert mpf_div(c, q, 9, round_up) == fi(301)
# Nearest even integer is down
assert mpf_div(a, q, 9, round_nearest) == fi(300)
assert mpf_div(b, q, 9, round_nearest) == fi(300)
assert mpf_div(c, q, 9, round_nearest) == fi(301)
# Nearest even integer is up
a = fi(301499999)
b = fi(301500000)
c = fi(301500001)
assert mpf_div(a, q, 9, round_nearest) == fi(301)
assert mpf_div(b, q, 9, round_nearest) == fi(302)
assert mpf_div(c, q, 9, round_nearest) == fi(302)
def test_tight_integer_division():
# Test that integer division at tightest possible precision is exact
N = 100
seed(1)
for i in range(N):
a = choice([1, -1]) * randint(1, 1<<randint(10, 100))
b = choice([1, -1]) * randint(1, 1<<randint(10, 100))
p = a * b
width = bitcount(abs(b)) - trailing(b)
a = fi(a); b = fi(b); p = fi(p)
for mode in all_modes:
assert mpf_div(p, a, width, mode) == b
def test_epsilon_rounding():
# Verify that mpf_div uses infinite precision; this result will
# appear to be exactly 0.101 to a near-sighted algorithm
a = fb('0.101' + ('0'*200) + '1')
b = fb('1.10101')
c = mpf_mul(a, b, 250, round_floor) # exact
assert mpf_div(c, b, bitcount(a[1]), round_floor) == a # exact
assert mpf_div(c, b, 2, round_down) == fb('0.10')
assert mpf_div(c, b, 3, round_down) == fb('0.101')
assert mpf_div(c, b, 2, round_up) == fb('0.11')
assert mpf_div(c, b, 3, round_up) == fb('0.110')
assert mpf_div(c, b, 2, round_floor) == fb('0.10')
assert mpf_div(c, b, 3, round_floor) == fb('0.101')
assert mpf_div(c, b, 2, round_ceiling) == fb('0.11')
assert mpf_div(c, b, 3, round_ceiling) == fb('0.110')
# The same for negative numbers
a = fb('-0.101' + ('0'*200) + '1')
b = fb('1.10101')
c = mpf_mul(a, b, 250, round_floor)
assert mpf_div(c, b, bitcount(a[1]), round_floor) == a
assert mpf_div(c, b, 2, round_down) == fb('-0.10')
assert mpf_div(c, b, 3, round_up) == fb('-0.110')
# Floor goes up, ceiling goes down
assert mpf_div(c, b, 2, round_floor) == fb('-0.11')
assert mpf_div(c, b, 3, round_floor) == fb('-0.110')
assert mpf_div(c, b, 2, round_ceiling) == fb('-0.10')
assert mpf_div(c, b, 3, round_ceiling) == fb('-0.101')
def test_mod():
mp.dps = 15
assert mpf(234) % 1 == 0
assert mpf(-3) % 256 == 253
assert mpf(0.25) % 23490.5 == 0.25
assert mpf(0.25) % -23490.5 == -23490.25
assert mpf(-0.25) % 23490.5 == 23490.25
assert mpf(-0.25) % -23490.5 == -0.25
# Check that these cases are handled efficiently
assert mpf('1e10000000000') % 1 == 0
assert mpf('1.23e-1000000000') % 1 == mpf('1.23e-1000000000')
# test __rmod__
assert 3 % mpf('1.75') == 1.25
def test_div_negative_rnd_bug():
mp.dps = 15
assert (-3) / mpf('0.1531879017645047') == mpf('-19.583791966887116')
assert mpf('-2.6342475750861301') / mpf('0.35126216427941814') == mpf('-7.4993775104985909')
|