Use skipUnless to skip math module tests on non-IEEE 754 platforms.
[python.git] / Lib / test / test_math.py
bloba9032d4784f3a1a99d5a984f4c4340640b104e68
1 # Python test set -- math module
2 # XXXX Should not do tests around zero only
4 from test.test_support import run_unittest, verbose
5 import unittest
6 import math
7 import os
8 import sys
9 import random
11 eps = 1E-05
12 NAN = float('nan')
13 INF = float('inf')
14 NINF = float('-inf')
16 # decorator for skipping tests on non-IEEE 754 platforms
17 requires_IEEE_754 = unittest.skipUnless(
18 float.__getformat__("double").startswith("IEEE"),
19 "test requires IEEE 754 doubles")
21 # detect evidence of double-rounding: fsum is not always correctly
22 # rounded on machines that suffer from double rounding.
23 x, y = 1e16, 2.9999 # use temporary values to defeat peephole optimizer
24 HAVE_DOUBLE_ROUNDING = (x + y == 1e16 + 4)
26 # locate file with test values
27 if __name__ == '__main__':
28 file = sys.argv[0]
29 else:
30 file = __file__
31 test_dir = os.path.dirname(file) or os.curdir
32 test_file = os.path.join(test_dir, 'cmath_testcases.txt')
34 def parse_testfile(fname):
35 """Parse a file with test values
37 Empty lines or lines starting with -- are ignored
38 yields id, fn, arg_real, arg_imag, exp_real, exp_imag
39 """
40 with open(fname) as fp:
41 for line in fp:
42 # skip comment lines and blank lines
43 if line.startswith('--') or not line.strip():
44 continue
46 lhs, rhs = line.split('->')
47 id, fn, arg_real, arg_imag = lhs.split()
48 rhs_pieces = rhs.split()
49 exp_real, exp_imag = rhs_pieces[0], rhs_pieces[1]
50 flags = rhs_pieces[2:]
52 yield (id, fn,
53 float(arg_real), float(arg_imag),
54 float(exp_real), float(exp_imag),
55 flags
58 class MathTests(unittest.TestCase):
60 def ftest(self, name, value, expected):
61 if abs(value-expected) > eps:
62 # Use %r instead of %f so the error message
63 # displays full precision. Otherwise discrepancies
64 # in the last few bits will lead to very confusing
65 # error messages
66 self.fail('%s returned %r, expected %r' %
67 (name, value, expected))
69 def testConstants(self):
70 self.ftest('pi', math.pi, 3.1415926)
71 self.ftest('e', math.e, 2.7182818)
73 def testAcos(self):
74 self.assertRaises(TypeError, math.acos)
75 self.ftest('acos(-1)', math.acos(-1), math.pi)
76 self.ftest('acos(0)', math.acos(0), math.pi/2)
77 self.ftest('acos(1)', math.acos(1), 0)
78 self.assertRaises(ValueError, math.acos, INF)
79 self.assertRaises(ValueError, math.acos, NINF)
80 self.assertTrue(math.isnan(math.acos(NAN)))
82 def testAcosh(self):
83 self.assertRaises(TypeError, math.acosh)
84 self.ftest('acosh(1)', math.acosh(1), 0)
85 self.ftest('acosh(2)', math.acosh(2), 1.3169578969248168)
86 self.assertRaises(ValueError, math.acosh, 0)
87 self.assertRaises(ValueError, math.acosh, -1)
88 self.assertEquals(math.acosh(INF), INF)
89 self.assertRaises(ValueError, math.acosh, NINF)
90 self.assertTrue(math.isnan(math.acosh(NAN)))
92 def testAsin(self):
93 self.assertRaises(TypeError, math.asin)
94 self.ftest('asin(-1)', math.asin(-1), -math.pi/2)
95 self.ftest('asin(0)', math.asin(0), 0)
96 self.ftest('asin(1)', math.asin(1), math.pi/2)
97 self.assertRaises(ValueError, math.asin, INF)
98 self.assertRaises(ValueError, math.asin, NINF)
99 self.assertTrue(math.isnan(math.asin(NAN)))
101 def testAsinh(self):
102 self.assertRaises(TypeError, math.asinh)
103 self.ftest('asinh(0)', math.asinh(0), 0)
104 self.ftest('asinh(1)', math.asinh(1), 0.88137358701954305)
105 self.ftest('asinh(-1)', math.asinh(-1), -0.88137358701954305)
106 self.assertEquals(math.asinh(INF), INF)
107 self.assertEquals(math.asinh(NINF), NINF)
108 self.assertTrue(math.isnan(math.asinh(NAN)))
110 def testAtan(self):
111 self.assertRaises(TypeError, math.atan)
112 self.ftest('atan(-1)', math.atan(-1), -math.pi/4)
113 self.ftest('atan(0)', math.atan(0), 0)
114 self.ftest('atan(1)', math.atan(1), math.pi/4)
115 self.ftest('atan(inf)', math.atan(INF), math.pi/2)
116 self.ftest('atan(-inf)', math.atan(NINF), -math.pi/2)
117 self.assertTrue(math.isnan(math.atan(NAN)))
119 def testAtanh(self):
120 self.assertRaises(TypeError, math.atan)
121 self.ftest('atanh(0)', math.atanh(0), 0)
122 self.ftest('atanh(0.5)', math.atanh(0.5), 0.54930614433405489)
123 self.ftest('atanh(-0.5)', math.atanh(-0.5), -0.54930614433405489)
124 self.assertRaises(ValueError, math.atanh, 1)
125 self.assertRaises(ValueError, math.atanh, -1)
126 self.assertRaises(ValueError, math.atanh, INF)
127 self.assertRaises(ValueError, math.atanh, NINF)
128 self.assertTrue(math.isnan(math.atanh(NAN)))
130 def testAtan2(self):
131 self.assertRaises(TypeError, math.atan2)
132 self.ftest('atan2(-1, 0)', math.atan2(-1, 0), -math.pi/2)
133 self.ftest('atan2(-1, 1)', math.atan2(-1, 1), -math.pi/4)
134 self.ftest('atan2(0, 1)', math.atan2(0, 1), 0)
135 self.ftest('atan2(1, 1)', math.atan2(1, 1), math.pi/4)
136 self.ftest('atan2(1, 0)', math.atan2(1, 0), math.pi/2)
138 # math.atan2(0, x)
139 self.ftest('atan2(0., -inf)', math.atan2(0., NINF), math.pi)
140 self.ftest('atan2(0., -2.3)', math.atan2(0., -2.3), math.pi)
141 self.ftest('atan2(0., -0.)', math.atan2(0., -0.), math.pi)
142 self.assertEqual(math.atan2(0., 0.), 0.)
143 self.assertEqual(math.atan2(0., 2.3), 0.)
144 self.assertEqual(math.atan2(0., INF), 0.)
145 self.assertTrue(math.isnan(math.atan2(0., NAN)))
146 # math.atan2(-0, x)
147 self.ftest('atan2(-0., -inf)', math.atan2(-0., NINF), -math.pi)
148 self.ftest('atan2(-0., -2.3)', math.atan2(-0., -2.3), -math.pi)
149 self.ftest('atan2(-0., -0.)', math.atan2(-0., -0.), -math.pi)
150 self.assertEqual(math.atan2(-0., 0.), -0.)
151 self.assertEqual(math.atan2(-0., 2.3), -0.)
152 self.assertEqual(math.atan2(-0., INF), -0.)
153 self.assertTrue(math.isnan(math.atan2(-0., NAN)))
154 # math.atan2(INF, x)
155 self.ftest('atan2(inf, -inf)', math.atan2(INF, NINF), math.pi*3/4)
156 self.ftest('atan2(inf, -2.3)', math.atan2(INF, -2.3), math.pi/2)
157 self.ftest('atan2(inf, -0.)', math.atan2(INF, -0.0), math.pi/2)
158 self.ftest('atan2(inf, 0.)', math.atan2(INF, 0.0), math.pi/2)
159 self.ftest('atan2(inf, 2.3)', math.atan2(INF, 2.3), math.pi/2)
160 self.ftest('atan2(inf, inf)', math.atan2(INF, INF), math.pi/4)
161 self.assertTrue(math.isnan(math.atan2(INF, NAN)))
162 # math.atan2(NINF, x)
163 self.ftest('atan2(-inf, -inf)', math.atan2(NINF, NINF), -math.pi*3/4)
164 self.ftest('atan2(-inf, -2.3)', math.atan2(NINF, -2.3), -math.pi/2)
165 self.ftest('atan2(-inf, -0.)', math.atan2(NINF, -0.0), -math.pi/2)
166 self.ftest('atan2(-inf, 0.)', math.atan2(NINF, 0.0), -math.pi/2)
167 self.ftest('atan2(-inf, 2.3)', math.atan2(NINF, 2.3), -math.pi/2)
168 self.ftest('atan2(-inf, inf)', math.atan2(NINF, INF), -math.pi/4)
169 self.assertTrue(math.isnan(math.atan2(NINF, NAN)))
170 # math.atan2(+finite, x)
171 self.ftest('atan2(2.3, -inf)', math.atan2(2.3, NINF), math.pi)
172 self.ftest('atan2(2.3, -0.)', math.atan2(2.3, -0.), math.pi/2)
173 self.ftest('atan2(2.3, 0.)', math.atan2(2.3, 0.), math.pi/2)
174 self.assertEqual(math.atan2(2.3, INF), 0.)
175 self.assertTrue(math.isnan(math.atan2(2.3, NAN)))
176 # math.atan2(-finite, x)
177 self.ftest('atan2(-2.3, -inf)', math.atan2(-2.3, NINF), -math.pi)
178 self.ftest('atan2(-2.3, -0.)', math.atan2(-2.3, -0.), -math.pi/2)
179 self.ftest('atan2(-2.3, 0.)', math.atan2(-2.3, 0.), -math.pi/2)
180 self.assertEqual(math.atan2(-2.3, INF), -0.)
181 self.assertTrue(math.isnan(math.atan2(-2.3, NAN)))
182 # math.atan2(NAN, x)
183 self.assertTrue(math.isnan(math.atan2(NAN, NINF)))
184 self.assertTrue(math.isnan(math.atan2(NAN, -2.3)))
185 self.assertTrue(math.isnan(math.atan2(NAN, -0.)))
186 self.assertTrue(math.isnan(math.atan2(NAN, 0.)))
187 self.assertTrue(math.isnan(math.atan2(NAN, 2.3)))
188 self.assertTrue(math.isnan(math.atan2(NAN, INF)))
189 self.assertTrue(math.isnan(math.atan2(NAN, NAN)))
191 def testCeil(self):
192 self.assertRaises(TypeError, math.ceil)
193 # These types will be int in py3k.
194 self.assertEquals(float, type(math.ceil(1)))
195 self.assertEquals(float, type(math.ceil(1L)))
196 self.assertEquals(float, type(math.ceil(1.0)))
197 self.ftest('ceil(0.5)', math.ceil(0.5), 1)
198 self.ftest('ceil(1.0)', math.ceil(1.0), 1)
199 self.ftest('ceil(1.5)', math.ceil(1.5), 2)
200 self.ftest('ceil(-0.5)', math.ceil(-0.5), 0)
201 self.ftest('ceil(-1.0)', math.ceil(-1.0), -1)
202 self.ftest('ceil(-1.5)', math.ceil(-1.5), -1)
203 self.assertEquals(math.ceil(INF), INF)
204 self.assertEquals(math.ceil(NINF), NINF)
205 self.assertTrue(math.isnan(math.ceil(NAN)))
207 class TestCeil(object):
208 def __float__(self):
209 return 41.3
210 class TestNoCeil(object):
211 pass
212 self.ftest('ceil(TestCeil())', math.ceil(TestCeil()), 42)
213 self.assertRaises(TypeError, math.ceil, TestNoCeil())
215 t = TestNoCeil()
216 t.__ceil__ = lambda *args: args
217 self.assertRaises(TypeError, math.ceil, t)
218 self.assertRaises(TypeError, math.ceil, t, 0)
220 @requires_IEEE_754
221 def testCopysign(self):
222 self.assertRaises(TypeError, math.copysign)
223 # copysign should let us distinguish signs of zeros
224 self.assertEquals(copysign(1., 0.), 1.)
225 self.assertEquals(copysign(1., -0.), -1.)
226 self.assertEquals(copysign(INF, 0.), INF)
227 self.assertEquals(copysign(INF, -0.), NINF)
228 self.assertEquals(copysign(NINF, 0.), INF)
229 self.assertEquals(copysign(NINF, -0.), NINF)
230 # and of infinities
231 self.assertEquals(copysign(1., INF), 1.)
232 self.assertEquals(copysign(1., NINF), -1.)
233 self.assertEquals(copysign(INF, INF), INF)
234 self.assertEquals(copysign(INF, NINF), NINF)
235 self.assertEquals(copysign(NINF, INF), INF)
236 self.assertEquals(copysign(NINF, NINF), NINF)
237 self.assertTrue(math.isnan(copysign(NAN, 1.)))
238 self.assertTrue(math.isnan(copysign(NAN, INF)))
239 self.assertTrue(math.isnan(copysign(NAN, NINF)))
240 self.assertTrue(math.isnan(copysign(NAN, NAN)))
241 # copysign(INF, NAN) may be INF or it may be NINF, since
242 # we don't know whether the sign bit of NAN is set on any
243 # given platform.
244 self.assertTrue(math.isinf(copysign(INF, NAN)))
245 # similarly, copysign(2., NAN) could be 2. or -2.
246 self.assertEquals(abs(copysign(2., NAN)), 2.)
248 def testCos(self):
249 self.assertRaises(TypeError, math.cos)
250 self.ftest('cos(-pi/2)', math.cos(-math.pi/2), 0)
251 self.ftest('cos(0)', math.cos(0), 1)
252 self.ftest('cos(pi/2)', math.cos(math.pi/2), 0)
253 self.ftest('cos(pi)', math.cos(math.pi), -1)
254 try:
255 self.assertTrue(math.isnan(math.cos(INF)))
256 self.assertTrue(math.isnan(math.cos(NINF)))
257 except ValueError:
258 self.assertRaises(ValueError, math.cos, INF)
259 self.assertRaises(ValueError, math.cos, NINF)
260 self.assertTrue(math.isnan(math.cos(NAN)))
262 def testCosh(self):
263 self.assertRaises(TypeError, math.cosh)
264 self.ftest('cosh(0)', math.cosh(0), 1)
265 self.ftest('cosh(2)-2*cosh(1)**2', math.cosh(2)-2*math.cosh(1)**2, -1) # Thanks to Lambert
266 self.assertEquals(math.cosh(INF), INF)
267 self.assertEquals(math.cosh(NINF), INF)
268 self.assertTrue(math.isnan(math.cosh(NAN)))
270 def testDegrees(self):
271 self.assertRaises(TypeError, math.degrees)
272 self.ftest('degrees(pi)', math.degrees(math.pi), 180.0)
273 self.ftest('degrees(pi/2)', math.degrees(math.pi/2), 90.0)
274 self.ftest('degrees(-pi/4)', math.degrees(-math.pi/4), -45.0)
276 def testExp(self):
277 self.assertRaises(TypeError, math.exp)
278 self.ftest('exp(-1)', math.exp(-1), 1/math.e)
279 self.ftest('exp(0)', math.exp(0), 1)
280 self.ftest('exp(1)', math.exp(1), math.e)
281 self.assertEquals(math.exp(INF), INF)
282 self.assertEquals(math.exp(NINF), 0.)
283 self.assertTrue(math.isnan(math.exp(NAN)))
285 def testFabs(self):
286 self.assertRaises(TypeError, math.fabs)
287 self.ftest('fabs(-1)', math.fabs(-1), 1)
288 self.ftest('fabs(0)', math.fabs(0), 0)
289 self.ftest('fabs(1)', math.fabs(1), 1)
291 def testFactorial(self):
292 def fact(n):
293 result = 1
294 for i in range(1, int(n)+1):
295 result *= i
296 return result
297 values = range(10) + [50, 100, 500]
298 random.shuffle(values)
299 for x in range(10):
300 for cast in (int, long, float):
301 self.assertEqual(math.factorial(cast(x)), fact(x), (x, fact(x), math.factorial(x)))
302 self.assertRaises(ValueError, math.factorial, -1)
303 self.assertRaises(ValueError, math.factorial, math.pi)
305 def testFloor(self):
306 self.assertRaises(TypeError, math.floor)
307 # These types will be int in py3k.
308 self.assertEquals(float, type(math.floor(1)))
309 self.assertEquals(float, type(math.floor(1L)))
310 self.assertEquals(float, type(math.floor(1.0)))
311 self.ftest('floor(0.5)', math.floor(0.5), 0)
312 self.ftest('floor(1.0)', math.floor(1.0), 1)
313 self.ftest('floor(1.5)', math.floor(1.5), 1)
314 self.ftest('floor(-0.5)', math.floor(-0.5), -1)
315 self.ftest('floor(-1.0)', math.floor(-1.0), -1)
316 self.ftest('floor(-1.5)', math.floor(-1.5), -2)
317 # pow() relies on floor() to check for integers
318 # This fails on some platforms - so check it here
319 self.ftest('floor(1.23e167)', math.floor(1.23e167), 1.23e167)
320 self.ftest('floor(-1.23e167)', math.floor(-1.23e167), -1.23e167)
321 self.assertEquals(math.ceil(INF), INF)
322 self.assertEquals(math.ceil(NINF), NINF)
323 self.assertTrue(math.isnan(math.floor(NAN)))
325 class TestFloor(object):
326 def __float__(self):
327 return 42.3
328 class TestNoFloor(object):
329 pass
330 self.ftest('floor(TestFloor())', math.floor(TestFloor()), 42)
331 self.assertRaises(TypeError, math.floor, TestNoFloor())
333 t = TestNoFloor()
334 t.__floor__ = lambda *args: args
335 self.assertRaises(TypeError, math.floor, t)
336 self.assertRaises(TypeError, math.floor, t, 0)
338 def testFmod(self):
339 self.assertRaises(TypeError, math.fmod)
340 self.ftest('fmod(10,1)', math.fmod(10,1), 0)
341 self.ftest('fmod(10,0.5)', math.fmod(10,0.5), 0)
342 self.ftest('fmod(10,1.5)', math.fmod(10,1.5), 1)
343 self.ftest('fmod(-10,1)', math.fmod(-10,1), 0)
344 self.ftest('fmod(-10,0.5)', math.fmod(-10,0.5), 0)
345 self.ftest('fmod(-10,1.5)', math.fmod(-10,1.5), -1)
346 self.assertTrue(math.isnan(math.fmod(NAN, 1.)))
347 self.assertTrue(math.isnan(math.fmod(1., NAN)))
348 self.assertTrue(math.isnan(math.fmod(NAN, NAN)))
349 self.assertRaises(ValueError, math.fmod, 1., 0.)
350 self.assertRaises(ValueError, math.fmod, INF, 1.)
351 self.assertRaises(ValueError, math.fmod, NINF, 1.)
352 self.assertRaises(ValueError, math.fmod, INF, 0.)
353 self.assertEquals(math.fmod(3.0, INF), 3.0)
354 self.assertEquals(math.fmod(-3.0, INF), -3.0)
355 self.assertEquals(math.fmod(3.0, NINF), 3.0)
356 self.assertEquals(math.fmod(-3.0, NINF), -3.0)
357 self.assertEquals(math.fmod(0.0, 3.0), 0.0)
358 self.assertEquals(math.fmod(0.0, NINF), 0.0)
360 def testFrexp(self):
361 self.assertRaises(TypeError, math.frexp)
363 def testfrexp(name, (mant, exp), (emant, eexp)):
364 if abs(mant-emant) > eps or exp != eexp:
365 self.fail('%s returned %r, expected %r'%\
366 (name, (mant, exp), (emant,eexp)))
368 testfrexp('frexp(-1)', math.frexp(-1), (-0.5, 1))
369 testfrexp('frexp(0)', math.frexp(0), (0, 0))
370 testfrexp('frexp(1)', math.frexp(1), (0.5, 1))
371 testfrexp('frexp(2)', math.frexp(2), (0.5, 2))
373 self.assertEquals(math.frexp(INF)[0], INF)
374 self.assertEquals(math.frexp(NINF)[0], NINF)
375 self.assertTrue(math.isnan(math.frexp(NAN)[0]))
377 @requires_IEEE_754
378 @unittest.skipIf(HAVE_DOUBLE_ROUNDING,
379 "fsum is not exact on machines with double rounding")
380 def testFsum(self):
381 # math.fsum relies on exact rounding for correct operation.
382 # There's a known problem with IA32 floating-point that causes
383 # inexact rounding in some situations, and will cause the
384 # math.fsum tests below to fail; see issue #2937. On non IEEE
385 # 754 platforms, and on IEEE 754 platforms that exhibit the
386 # problem described in issue #2937, we simply skip the whole
387 # test.
389 # Python version of math.fsum, for comparison. Uses a
390 # different algorithm based on frexp, ldexp and integer
391 # arithmetic.
392 from sys import float_info
393 mant_dig = float_info.mant_dig
394 etiny = float_info.min_exp - mant_dig
396 def msum(iterable):
397 """Full precision summation. Compute sum(iterable) without any
398 intermediate accumulation of error. Based on the 'lsum' function
399 at http://code.activestate.com/recipes/393090/
402 tmant, texp = 0, 0
403 for x in iterable:
404 mant, exp = math.frexp(x)
405 mant, exp = int(math.ldexp(mant, mant_dig)), exp - mant_dig
406 if texp > exp:
407 tmant <<= texp-exp
408 texp = exp
409 else:
410 mant <<= exp-texp
411 tmant += mant
412 # Round tmant * 2**texp to a float. The original recipe
413 # used float(str(tmant)) * 2.0**texp for this, but that's
414 # a little unsafe because str -> float conversion can't be
415 # relied upon to do correct rounding on all platforms.
416 tail = max(len(bin(abs(tmant)))-2 - mant_dig, etiny - texp)
417 if tail > 0:
418 h = 1 << (tail-1)
419 tmant = tmant // (2*h) + bool(tmant & h and tmant & 3*h-1)
420 texp += tail
421 return math.ldexp(tmant, texp)
423 test_values = [
424 ([], 0.0),
425 ([0.0], 0.0),
426 ([1e100, 1.0, -1e100, 1e-100, 1e50, -1.0, -1e50], 1e-100),
427 ([2.0**53, -0.5, -2.0**-54], 2.0**53-1.0),
428 ([2.0**53, 1.0, 2.0**-100], 2.0**53+2.0),
429 ([2.0**53+10.0, 1.0, 2.0**-100], 2.0**53+12.0),
430 ([2.0**53-4.0, 0.5, 2.0**-54], 2.0**53-3.0),
431 ([1./n for n in range(1, 1001)],
432 float.fromhex('0x1.df11f45f4e61ap+2')),
433 ([(-1.)**n/n for n in range(1, 1001)],
434 float.fromhex('-0x1.62a2af1bd3624p-1')),
435 ([1.7**(i+1)-1.7**i for i in range(1000)] + [-1.7**1000], -1.0),
436 ([1e16, 1., 1e-16], 10000000000000002.0),
437 ([1e16-2., 1.-2.**-53, -(1e16-2.), -(1.-2.**-53)], 0.0),
438 # exercise code for resizing partials array
439 ([2.**n - 2.**(n+50) + 2.**(n+52) for n in range(-1074, 972, 2)] +
440 [-2.**1022],
441 float.fromhex('0x1.5555555555555p+970')),
444 for i, (vals, expected) in enumerate(test_values):
445 try:
446 actual = math.fsum(vals)
447 except OverflowError:
448 self.fail("test %d failed: got OverflowError, expected %r "
449 "for math.fsum(%.100r)" % (i, expected, vals))
450 except ValueError:
451 self.fail("test %d failed: got ValueError, expected %r "
452 "for math.fsum(%.100r)" % (i, expected, vals))
453 self.assertEqual(actual, expected)
455 from random import random, gauss, shuffle
456 for j in xrange(1000):
457 vals = [7, 1e100, -7, -1e100, -9e-20, 8e-20] * 10
458 s = 0
459 for i in xrange(200):
460 v = gauss(0, random()) ** 7 - s
461 s += v
462 vals.append(v)
463 shuffle(vals)
465 s = msum(vals)
466 self.assertEqual(msum(vals), math.fsum(vals))
468 def testHypot(self):
469 self.assertRaises(TypeError, math.hypot)
470 self.ftest('hypot(0,0)', math.hypot(0,0), 0)
471 self.ftest('hypot(3,4)', math.hypot(3,4), 5)
472 self.assertEqual(math.hypot(NAN, INF), INF)
473 self.assertEqual(math.hypot(INF, NAN), INF)
474 self.assertEqual(math.hypot(NAN, NINF), INF)
475 self.assertEqual(math.hypot(NINF, NAN), INF)
476 self.assertTrue(math.isnan(math.hypot(1.0, NAN)))
477 self.assertTrue(math.isnan(math.hypot(NAN, -2.0)))
479 def testLdexp(self):
480 self.assertRaises(TypeError, math.ldexp)
481 self.ftest('ldexp(0,1)', math.ldexp(0,1), 0)
482 self.ftest('ldexp(1,1)', math.ldexp(1,1), 2)
483 self.ftest('ldexp(1,-1)', math.ldexp(1,-1), 0.5)
484 self.ftest('ldexp(-1,1)', math.ldexp(-1,1), -2)
485 self.assertRaises(OverflowError, math.ldexp, 1., 1000000)
486 self.assertRaises(OverflowError, math.ldexp, -1., 1000000)
487 self.assertEquals(math.ldexp(1., -1000000), 0.)
488 self.assertEquals(math.ldexp(-1., -1000000), -0.)
489 self.assertEquals(math.ldexp(INF, 30), INF)
490 self.assertEquals(math.ldexp(NINF, -213), NINF)
491 self.assertTrue(math.isnan(math.ldexp(NAN, 0)))
493 # large second argument
494 for n in [10**5, 10L**5, 10**10, 10L**10, 10**20, 10**40]:
495 self.assertEquals(math.ldexp(INF, -n), INF)
496 self.assertEquals(math.ldexp(NINF, -n), NINF)
497 self.assertEquals(math.ldexp(1., -n), 0.)
498 self.assertEquals(math.ldexp(-1., -n), -0.)
499 self.assertEquals(math.ldexp(0., -n), 0.)
500 self.assertEquals(math.ldexp(-0., -n), -0.)
501 self.assertTrue(math.isnan(math.ldexp(NAN, -n)))
503 self.assertRaises(OverflowError, math.ldexp, 1., n)
504 self.assertRaises(OverflowError, math.ldexp, -1., n)
505 self.assertEquals(math.ldexp(0., n), 0.)
506 self.assertEquals(math.ldexp(-0., n), -0.)
507 self.assertEquals(math.ldexp(INF, n), INF)
508 self.assertEquals(math.ldexp(NINF, n), NINF)
509 self.assertTrue(math.isnan(math.ldexp(NAN, n)))
511 def testLog(self):
512 self.assertRaises(TypeError, math.log)
513 self.ftest('log(1/e)', math.log(1/math.e), -1)
514 self.ftest('log(1)', math.log(1), 0)
515 self.ftest('log(e)', math.log(math.e), 1)
516 self.ftest('log(32,2)', math.log(32,2), 5)
517 self.ftest('log(10**40, 10)', math.log(10**40, 10), 40)
518 self.ftest('log(10**40, 10**20)', math.log(10**40, 10**20), 2)
519 self.assertEquals(math.log(INF), INF)
520 self.assertRaises(ValueError, math.log, NINF)
521 self.assertTrue(math.isnan(math.log(NAN)))
523 def testLog1p(self):
524 self.assertRaises(TypeError, math.log1p)
525 self.ftest('log1p(1/e -1)', math.log1p(1/math.e-1), -1)
526 self.ftest('log1p(0)', math.log1p(0), 0)
527 self.ftest('log1p(e-1)', math.log1p(math.e-1), 1)
528 self.ftest('log1p(1)', math.log1p(1), math.log(2))
529 self.assertEquals(math.log1p(INF), INF)
530 self.assertRaises(ValueError, math.log1p, NINF)
531 self.assertTrue(math.isnan(math.log1p(NAN)))
532 n= 2**90
533 self.assertAlmostEquals(math.log1p(n), 62.383246250395075)
534 self.assertAlmostEquals(math.log1p(n), math.log1p(float(n)))
536 def testLog10(self):
537 self.assertRaises(TypeError, math.log10)
538 self.ftest('log10(0.1)', math.log10(0.1), -1)
539 self.ftest('log10(1)', math.log10(1), 0)
540 self.ftest('log10(10)', math.log10(10), 1)
541 self.assertEquals(math.log(INF), INF)
542 self.assertRaises(ValueError, math.log10, NINF)
543 self.assertTrue(math.isnan(math.log10(NAN)))
545 def testModf(self):
546 self.assertRaises(TypeError, math.modf)
548 def testmodf(name, (v1, v2), (e1, e2)):
549 if abs(v1-e1) > eps or abs(v2-e2):
550 self.fail('%s returned %r, expected %r'%\
551 (name, (v1,v2), (e1,e2)))
553 testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0))
554 testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0))
556 self.assertEquals(math.modf(INF), (0.0, INF))
557 self.assertEquals(math.modf(NINF), (-0.0, NINF))
559 modf_nan = math.modf(NAN)
560 self.assertTrue(math.isnan(modf_nan[0]))
561 self.assertTrue(math.isnan(modf_nan[1]))
563 def testPow(self):
564 self.assertRaises(TypeError, math.pow)
565 self.ftest('pow(0,1)', math.pow(0,1), 0)
566 self.ftest('pow(1,0)', math.pow(1,0), 1)
567 self.ftest('pow(2,1)', math.pow(2,1), 2)
568 self.ftest('pow(2,-1)', math.pow(2,-1), 0.5)
569 self.assertEqual(math.pow(INF, 1), INF)
570 self.assertEqual(math.pow(NINF, 1), NINF)
571 self.assertEqual((math.pow(1, INF)), 1.)
572 self.assertEqual((math.pow(1, NINF)), 1.)
573 self.assertTrue(math.isnan(math.pow(NAN, 1)))
574 self.assertTrue(math.isnan(math.pow(2, NAN)))
575 self.assertTrue(math.isnan(math.pow(0, NAN)))
576 self.assertEqual(math.pow(1, NAN), 1)
578 # pow(0., x)
579 self.assertEqual(math.pow(0., INF), 0.)
580 self.assertEqual(math.pow(0., 3.), 0.)
581 self.assertEqual(math.pow(0., 2.3), 0.)
582 self.assertEqual(math.pow(0., 2.), 0.)
583 self.assertEqual(math.pow(0., 0.), 1.)
584 self.assertEqual(math.pow(0., -0.), 1.)
585 self.assertRaises(ValueError, math.pow, 0., -2.)
586 self.assertRaises(ValueError, math.pow, 0., -2.3)
587 self.assertRaises(ValueError, math.pow, 0., -3.)
588 self.assertRaises(ValueError, math.pow, 0., NINF)
589 self.assertTrue(math.isnan(math.pow(0., NAN)))
591 # pow(INF, x)
592 self.assertEqual(math.pow(INF, INF), INF)
593 self.assertEqual(math.pow(INF, 3.), INF)
594 self.assertEqual(math.pow(INF, 2.3), INF)
595 self.assertEqual(math.pow(INF, 2.), INF)
596 self.assertEqual(math.pow(INF, 0.), 1.)
597 self.assertEqual(math.pow(INF, -0.), 1.)
598 self.assertEqual(math.pow(INF, -2.), 0.)
599 self.assertEqual(math.pow(INF, -2.3), 0.)
600 self.assertEqual(math.pow(INF, -3.), 0.)
601 self.assertEqual(math.pow(INF, NINF), 0.)
602 self.assertTrue(math.isnan(math.pow(INF, NAN)))
604 # pow(-0., x)
605 self.assertEqual(math.pow(-0., INF), 0.)
606 self.assertEqual(math.pow(-0., 3.), -0.)
607 self.assertEqual(math.pow(-0., 2.3), 0.)
608 self.assertEqual(math.pow(-0., 2.), 0.)
609 self.assertEqual(math.pow(-0., 0.), 1.)
610 self.assertEqual(math.pow(-0., -0.), 1.)
611 self.assertRaises(ValueError, math.pow, -0., -2.)
612 self.assertRaises(ValueError, math.pow, -0., -2.3)
613 self.assertRaises(ValueError, math.pow, -0., -3.)
614 self.assertRaises(ValueError, math.pow, -0., NINF)
615 self.assertTrue(math.isnan(math.pow(-0., NAN)))
617 # pow(NINF, x)
618 self.assertEqual(math.pow(NINF, INF), INF)
619 self.assertEqual(math.pow(NINF, 3.), NINF)
620 self.assertEqual(math.pow(NINF, 2.3), INF)
621 self.assertEqual(math.pow(NINF, 2.), INF)
622 self.assertEqual(math.pow(NINF, 0.), 1.)
623 self.assertEqual(math.pow(NINF, -0.), 1.)
624 self.assertEqual(math.pow(NINF, -2.), 0.)
625 self.assertEqual(math.pow(NINF, -2.3), 0.)
626 self.assertEqual(math.pow(NINF, -3.), -0.)
627 self.assertEqual(math.pow(NINF, NINF), 0.)
628 self.assertTrue(math.isnan(math.pow(NINF, NAN)))
630 # pow(-1, x)
631 self.assertEqual(math.pow(-1., INF), 1.)
632 self.assertEqual(math.pow(-1., 3.), -1.)
633 self.assertRaises(ValueError, math.pow, -1., 2.3)
634 self.assertEqual(math.pow(-1., 2.), 1.)
635 self.assertEqual(math.pow(-1., 0.), 1.)
636 self.assertEqual(math.pow(-1., -0.), 1.)
637 self.assertEqual(math.pow(-1., -2.), 1.)
638 self.assertRaises(ValueError, math.pow, -1., -2.3)
639 self.assertEqual(math.pow(-1., -3.), -1.)
640 self.assertEqual(math.pow(-1., NINF), 1.)
641 self.assertTrue(math.isnan(math.pow(-1., NAN)))
643 # pow(1, x)
644 self.assertEqual(math.pow(1., INF), 1.)
645 self.assertEqual(math.pow(1., 3.), 1.)
646 self.assertEqual(math.pow(1., 2.3), 1.)
647 self.assertEqual(math.pow(1., 2.), 1.)
648 self.assertEqual(math.pow(1., 0.), 1.)
649 self.assertEqual(math.pow(1., -0.), 1.)
650 self.assertEqual(math.pow(1., -2.), 1.)
651 self.assertEqual(math.pow(1., -2.3), 1.)
652 self.assertEqual(math.pow(1., -3.), 1.)
653 self.assertEqual(math.pow(1., NINF), 1.)
654 self.assertEqual(math.pow(1., NAN), 1.)
656 # pow(x, 0) should be 1 for any x
657 self.assertEqual(math.pow(2.3, 0.), 1.)
658 self.assertEqual(math.pow(-2.3, 0.), 1.)
659 self.assertEqual(math.pow(NAN, 0.), 1.)
660 self.assertEqual(math.pow(2.3, -0.), 1.)
661 self.assertEqual(math.pow(-2.3, -0.), 1.)
662 self.assertEqual(math.pow(NAN, -0.), 1.)
664 # pow(x, y) is invalid if x is negative and y is not integral
665 self.assertRaises(ValueError, math.pow, -1., 2.3)
666 self.assertRaises(ValueError, math.pow, -15., -3.1)
668 # pow(x, NINF)
669 self.assertEqual(math.pow(1.9, NINF), 0.)
670 self.assertEqual(math.pow(1.1, NINF), 0.)
671 self.assertEqual(math.pow(0.9, NINF), INF)
672 self.assertEqual(math.pow(0.1, NINF), INF)
673 self.assertEqual(math.pow(-0.1, NINF), INF)
674 self.assertEqual(math.pow(-0.9, NINF), INF)
675 self.assertEqual(math.pow(-1.1, NINF), 0.)
676 self.assertEqual(math.pow(-1.9, NINF), 0.)
678 # pow(x, INF)
679 self.assertEqual(math.pow(1.9, INF), INF)
680 self.assertEqual(math.pow(1.1, INF), INF)
681 self.assertEqual(math.pow(0.9, INF), 0.)
682 self.assertEqual(math.pow(0.1, INF), 0.)
683 self.assertEqual(math.pow(-0.1, INF), 0.)
684 self.assertEqual(math.pow(-0.9, INF), 0.)
685 self.assertEqual(math.pow(-1.1, INF), INF)
686 self.assertEqual(math.pow(-1.9, INF), INF)
688 # pow(x, y) should work for x negative, y an integer
689 self.ftest('(-2.)**3.', math.pow(-2.0, 3.0), -8.0)
690 self.ftest('(-2.)**2.', math.pow(-2.0, 2.0), 4.0)
691 self.ftest('(-2.)**1.', math.pow(-2.0, 1.0), -2.0)
692 self.ftest('(-2.)**0.', math.pow(-2.0, 0.0), 1.0)
693 self.ftest('(-2.)**-0.', math.pow(-2.0, -0.0), 1.0)
694 self.ftest('(-2.)**-1.', math.pow(-2.0, -1.0), -0.5)
695 self.ftest('(-2.)**-2.', math.pow(-2.0, -2.0), 0.25)
696 self.ftest('(-2.)**-3.', math.pow(-2.0, -3.0), -0.125)
697 self.assertRaises(ValueError, math.pow, -2.0, -0.5)
698 self.assertRaises(ValueError, math.pow, -2.0, 0.5)
700 # the following tests have been commented out since they don't
701 # really belong here: the implementation of ** for floats is
702 # independent of the implemention of math.pow
703 #self.assertEqual(1**NAN, 1)
704 #self.assertEqual(1**INF, 1)
705 #self.assertEqual(1**NINF, 1)
706 #self.assertEqual(1**0, 1)
707 #self.assertEqual(1.**NAN, 1)
708 #self.assertEqual(1.**INF, 1)
709 #self.assertEqual(1.**NINF, 1)
710 #self.assertEqual(1.**0, 1)
712 def testRadians(self):
713 self.assertRaises(TypeError, math.radians)
714 self.ftest('radians(180)', math.radians(180), math.pi)
715 self.ftest('radians(90)', math.radians(90), math.pi/2)
716 self.ftest('radians(-45)', math.radians(-45), -math.pi/4)
718 def testSin(self):
719 self.assertRaises(TypeError, math.sin)
720 self.ftest('sin(0)', math.sin(0), 0)
721 self.ftest('sin(pi/2)', math.sin(math.pi/2), 1)
722 self.ftest('sin(-pi/2)', math.sin(-math.pi/2), -1)
723 try:
724 self.assertTrue(math.isnan(math.sin(INF)))
725 self.assertTrue(math.isnan(math.sin(NINF)))
726 except ValueError:
727 self.assertRaises(ValueError, math.sin, INF)
728 self.assertRaises(ValueError, math.sin, NINF)
729 self.assertTrue(math.isnan(math.sin(NAN)))
731 def testSinh(self):
732 self.assertRaises(TypeError, math.sinh)
733 self.ftest('sinh(0)', math.sinh(0), 0)
734 self.ftest('sinh(1)**2-cosh(1)**2', math.sinh(1)**2-math.cosh(1)**2, -1)
735 self.ftest('sinh(1)+sinh(-1)', math.sinh(1)+math.sinh(-1), 0)
736 self.assertEquals(math.sinh(INF), INF)
737 self.assertEquals(math.sinh(NINF), NINF)
738 self.assertTrue(math.isnan(math.sinh(NAN)))
740 def testSqrt(self):
741 self.assertRaises(TypeError, math.sqrt)
742 self.ftest('sqrt(0)', math.sqrt(0), 0)
743 self.ftest('sqrt(1)', math.sqrt(1), 1)
744 self.ftest('sqrt(4)', math.sqrt(4), 2)
745 self.assertEquals(math.sqrt(INF), INF)
746 self.assertRaises(ValueError, math.sqrt, NINF)
747 self.assertTrue(math.isnan(math.sqrt(NAN)))
749 def testTan(self):
750 self.assertRaises(TypeError, math.tan)
751 self.ftest('tan(0)', math.tan(0), 0)
752 self.ftest('tan(pi/4)', math.tan(math.pi/4), 1)
753 self.ftest('tan(-pi/4)', math.tan(-math.pi/4), -1)
754 try:
755 self.assertTrue(math.isnan(math.tan(INF)))
756 self.assertTrue(math.isnan(math.tan(NINF)))
757 except:
758 self.assertRaises(ValueError, math.tan, INF)
759 self.assertRaises(ValueError, math.tan, NINF)
760 self.assertTrue(math.isnan(math.tan(NAN)))
762 def testTanh(self):
763 self.assertRaises(TypeError, math.tanh)
764 self.ftest('tanh(0)', math.tanh(0), 0)
765 self.ftest('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0)
766 self.ftest('tanh(inf)', math.tanh(INF), 1)
767 self.ftest('tanh(-inf)', math.tanh(NINF), -1)
768 self.assertTrue(math.isnan(math.tanh(NAN)))
769 # check that tanh(-0.) == -0. on IEEE 754 systems
770 if float.__getformat__("double").startswith("IEEE"):
771 self.assertEqual(math.tanh(-0.), -0.)
772 self.assertEqual(math.copysign(1., math.tanh(-0.)),
773 math.copysign(1., -0.))
775 def test_trunc(self):
776 self.assertEqual(math.trunc(1), 1)
777 self.assertEqual(math.trunc(-1), -1)
778 self.assertEqual(type(math.trunc(1)), int)
779 self.assertEqual(type(math.trunc(1.5)), int)
780 self.assertEqual(math.trunc(1.5), 1)
781 self.assertEqual(math.trunc(-1.5), -1)
782 self.assertEqual(math.trunc(1.999999), 1)
783 self.assertEqual(math.trunc(-1.999999), -1)
784 self.assertEqual(math.trunc(-0.999999), -0)
785 self.assertEqual(math.trunc(-100.999), -100)
787 class TestTrunc(object):
788 def __trunc__(self):
789 return 23
791 class TestNoTrunc(object):
792 pass
794 self.assertEqual(math.trunc(TestTrunc()), 23)
796 self.assertRaises(TypeError, math.trunc)
797 self.assertRaises(TypeError, math.trunc, 1, 2)
798 # XXX: This is not ideal, but see the comment in math_trunc().
799 self.assertRaises(AttributeError, math.trunc, TestNoTrunc())
801 t = TestNoTrunc()
802 t.__trunc__ = lambda *args: args
803 self.assertEquals((), math.trunc(t))
804 self.assertRaises(TypeError, math.trunc, t, 0)
806 def testCopysign(self):
807 self.assertEqual(math.copysign(1, 42), 1.0)
808 self.assertEqual(math.copysign(0., 42), 0.0)
809 self.assertEqual(math.copysign(1., -42), -1.0)
810 self.assertEqual(math.copysign(3, 0.), 3.0)
811 self.assertEqual(math.copysign(4., -0.), -4.0)
813 def testIsnan(self):
814 self.assertTrue(math.isnan(float("nan")))
815 self.assertTrue(math.isnan(float("inf")* 0.))
816 self.assertFalse(math.isnan(float("inf")))
817 self.assertFalse(math.isnan(0.))
818 self.assertFalse(math.isnan(1.))
820 def testIsinf(self):
821 self.assertTrue(math.isinf(float("inf")))
822 self.assertTrue(math.isinf(float("-inf")))
823 self.assertTrue(math.isinf(1E400))
824 self.assertTrue(math.isinf(-1E400))
825 self.assertFalse(math.isinf(float("nan")))
826 self.assertFalse(math.isinf(0.))
827 self.assertFalse(math.isinf(1.))
829 # RED_FLAG 16-Oct-2000 Tim
830 # While 2.0 is more consistent about exceptions than previous releases, it
831 # still fails this part of the test on some platforms. For now, we only
832 # *run* test_exceptions() in verbose mode, so that this isn't normally
833 # tested.
835 if verbose:
836 def test_exceptions(self):
837 try:
838 x = math.exp(-1000000000)
839 except:
840 # mathmodule.c is failing to weed out underflows from libm, or
841 # we've got an fp format with huge dynamic range
842 self.fail("underflowing exp() should not have raised "
843 "an exception")
844 if x != 0:
845 self.fail("underflowing exp() should have returned 0")
847 # If this fails, probably using a strict IEEE-754 conforming libm, and x
848 # is +Inf afterwards. But Python wants overflows detected by default.
849 try:
850 x = math.exp(1000000000)
851 except OverflowError:
852 pass
853 else:
854 self.fail("overflowing exp() didn't trigger OverflowError")
856 # If this fails, it could be a puzzle. One odd possibility is that
857 # mathmodule.c's macros are getting confused while comparing
858 # Inf (HUGE_VAL) to a NaN, and artificially setting errno to ERANGE
859 # as a result (and so raising OverflowError instead).
860 try:
861 x = math.sqrt(-1.0)
862 except ValueError:
863 pass
864 else:
865 self.fail("sqrt(-1) didn't raise ValueError")
867 @requires_IEEE_754
868 def test_testfile(self):
869 for id, fn, ar, ai, er, ei, flags in parse_testfile(test_file):
870 # Skip if either the input or result is complex, or if
871 # flags is nonempty
872 if ai != 0. or ei != 0. or flags:
873 continue
874 if fn in ['rect', 'polar']:
875 # no real versions of rect, polar
876 continue
877 func = getattr(math, fn)
878 try:
879 result = func(ar)
880 except ValueError:
881 message = ("Unexpected ValueError in " +
882 "test %s:%s(%r)\n" % (id, fn, ar))
883 self.fail(message)
884 except OverflowError:
885 message = ("Unexpected OverflowError in " +
886 "test %s:%s(%r)\n" % (id, fn, ar))
887 self.fail(message)
888 self.ftest("%s:%s(%r)" % (id, fn, ar), result, er)
890 def test_main():
891 from doctest import DocFileSuite
892 suite = unittest.TestSuite()
893 suite.addTest(unittest.makeSuite(MathTests))
894 suite.addTest(DocFileSuite("ieee754.txt"))
895 run_unittest(suite)
897 if __name__ == '__main__':
898 test_main()