1import math 2import unittest 3 4class PowTest(unittest.TestCase): 5 6 def powtest(self, type): 7 if type != float: 8 for i in range(-1000, 1000): 9 self.assertEqual(pow(type(i), 0), 1) 10 self.assertEqual(pow(type(i), 1), type(i)) 11 self.assertEqual(pow(type(0), 1), type(0)) 12 self.assertEqual(pow(type(1), 1), type(1)) 13 14 for i in range(-100, 100): 15 self.assertEqual(pow(type(i), 3), i*i*i) 16 17 pow2 = 1 18 for i in range(0, 31): 19 self.assertEqual(pow(2, i), pow2) 20 if i != 30 : pow2 = pow2*2 21 22 for othertype in (int,): 23 for i in list(range(-10, 0)) + list(range(1, 10)): 24 ii = type(i) 25 for j in range(1, 11): 26 jj = -othertype(j) 27 pow(ii, jj) 28 29 for othertype in int, float: 30 for i in range(1, 100): 31 zero = type(0) 32 exp = -othertype(i/10.0) 33 if exp == 0: 34 continue 35 self.assertRaises(ZeroDivisionError, pow, zero, exp) 36 37 il, ih = -20, 20 38 jl, jh = -5, 5 39 kl, kh = -10, 10 40 asseq = self.assertEqual 41 if type == float: 42 il = 1 43 asseq = self.assertAlmostEqual 44 elif type == int: 45 jl = 0 46 elif type == int: 47 jl, jh = 0, 15 48 for i in range(il, ih+1): 49 for j in range(jl, jh+1): 50 for k in range(kl, kh+1): 51 if k != 0: 52 if type == float or j < 0: 53 self.assertRaises(TypeError, pow, type(i), j, k) 54 continue 55 asseq( 56 pow(type(i),j,k), 57 pow(type(i),j)% type(k) 58 ) 59 60 def test_powint(self): 61 self.powtest(int) 62 63 def test_powfloat(self): 64 self.powtest(float) 65 66 def test_other(self): 67 # Other tests-- not very systematic 68 self.assertEqual(pow(3,3) % 8, pow(3,3,8)) 69 self.assertEqual(pow(3,3) % -8, pow(3,3,-8)) 70 self.assertEqual(pow(3,2) % -2, pow(3,2,-2)) 71 self.assertEqual(pow(-3,3) % 8, pow(-3,3,8)) 72 self.assertEqual(pow(-3,3) % -8, pow(-3,3,-8)) 73 self.assertEqual(pow(5,2) % -8, pow(5,2,-8)) 74 75 self.assertEqual(pow(3,3) % 8, pow(3,3,8)) 76 self.assertEqual(pow(3,3) % -8, pow(3,3,-8)) 77 self.assertEqual(pow(3,2) % -2, pow(3,2,-2)) 78 self.assertEqual(pow(-3,3) % 8, pow(-3,3,8)) 79 self.assertEqual(pow(-3,3) % -8, pow(-3,3,-8)) 80 self.assertEqual(pow(5,2) % -8, pow(5,2,-8)) 81 82 for i in range(-10, 11): 83 for j in range(0, 6): 84 for k in range(-7, 11): 85 if j >= 0 and k != 0: 86 self.assertEqual( 87 pow(i,j) % k, 88 pow(i,j,k) 89 ) 90 if j >= 0 and k != 0: 91 self.assertEqual( 92 pow(int(i),j) % k, 93 pow(int(i),j,k) 94 ) 95 96 def test_bug643260(self): 97 class TestRpow: 98 def __rpow__(self, other): 99 return None 100 None ** TestRpow() # Won't fail when __rpow__ invoked. SF bug #643260. 101 102 def test_bug705231(self): 103 # -1.0 raised to an integer should never blow up. It did if the 104 # platform pow() was buggy, and Python didn't worm around it. 105 eq = self.assertEqual 106 a = -1.0 107 # The next two tests can still fail if the platform floor() 108 # function doesn't treat all large inputs as integers 109 # test_math should also fail if that is happening 110 eq(pow(a, 1.23e167), 1.0) 111 eq(pow(a, -1.23e167), 1.0) 112 for b in range(-10, 11): 113 eq(pow(a, float(b)), b & 1 and -1.0 or 1.0) 114 for n in range(0, 100): 115 fiveto = float(5 ** n) 116 # For small n, fiveto will be odd. Eventually we run out of 117 # mantissa bits, though, and thereafer fiveto will be even. 118 expected = fiveto % 2.0 and -1.0 or 1.0 119 eq(pow(a, fiveto), expected) 120 eq(pow(a, -fiveto), expected) 121 eq(expected, 1.0) # else we didn't push fiveto to evenness 122 123 def test_negative_exponent(self): 124 for a in range(-50, 50): 125 for m in range(-50, 50): 126 with self.subTest(a=a, m=m): 127 if m != 0 and math.gcd(a, m) == 1: 128 # Exponent -1 should give an inverse, with the 129 # same sign as m. 130 inv = pow(a, -1, m) 131 self.assertEqual(inv, inv % m) 132 self.assertEqual((inv * a - 1) % m, 0) 133 134 # Larger exponents 135 self.assertEqual(pow(a, -2, m), pow(inv, 2, m)) 136 self.assertEqual(pow(a, -3, m), pow(inv, 3, m)) 137 self.assertEqual(pow(a, -1001, m), pow(inv, 1001, m)) 138 139 else: 140 with self.assertRaises(ValueError): 141 pow(a, -1, m) 142 with self.assertRaises(ValueError): 143 pow(a, -2, m) 144 with self.assertRaises(ValueError): 145 pow(a, -1001, m) 146 147 148if __name__ == "__main__": 149 unittest.main() 150