1 # Python test set -- math module
2 # XXXX Should not do tests around zero only
4 from test
.test_support
import run_unittest
, verbose
16 # locate file with test values
17 if __name__
== '__main__':
21 test_dir
= os
.path
.dirname(file) or os
.curdir
22 test_file
= os
.path
.join(test_dir
, 'cmath_testcases.txt')
24 def parse_testfile(fname
):
25 """Parse a file with test values
27 Empty lines or lines starting with -- are ignored
28 yields id, fn, arg_real, arg_imag, exp_real, exp_imag
30 with
open(fname
) as fp
:
32 # skip comment lines and blank lines
33 if line
.startswith('--') or not line
.strip():
36 lhs
, rhs
= line
.split('->')
37 id, fn
, arg_real
, arg_imag
= lhs
.split()
38 rhs_pieces
= rhs
.split()
39 exp_real
, exp_imag
= rhs_pieces
[0], rhs_pieces
[1]
40 flags
= rhs_pieces
[2:]
43 float(arg_real
), float(arg_imag
),
44 float(exp_real
), float(exp_imag
),
48 class MathTests(unittest
.TestCase
):
50 def ftest(self
, name
, value
, expected
):
51 if abs(value
-expected
) > eps
:
52 # Use %r instead of %f so the error message
53 # displays full precision. Otherwise discrepancies
54 # in the last few bits will lead to very confusing
56 self
.fail('%s returned %r, expected %r' %
57 (name
, value
, expected
))
59 def testConstants(self
):
60 self
.ftest('pi', math
.pi
, 3.1415926)
61 self
.ftest('e', math
.e
, 2.7182818)
64 self
.assertRaises(TypeError, math
.acos
)
65 self
.ftest('acos(-1)', math
.acos(-1), math
.pi
)
66 self
.ftest('acos(0)', math
.acos(0), math
.pi
/2)
67 self
.ftest('acos(1)', math
.acos(1), 0)
68 self
.assertRaises(ValueError, math
.acos
, INF
)
69 self
.assertRaises(ValueError, math
.acos
, NINF
)
70 self
.assert_(math
.isnan(math
.acos(NAN
)))
73 self
.assertRaises(TypeError, math
.acosh
)
74 self
.ftest('acosh(1)', math
.acosh(1), 0)
75 self
.ftest('acosh(2)', math
.acosh(2), 1.3169578969248168)
76 self
.assertRaises(ValueError, math
.acosh
, 0)
77 self
.assertRaises(ValueError, math
.acosh
, -1)
78 self
.assertEquals(math
.acosh(INF
), INF
)
79 self
.assertRaises(ValueError, math
.acosh
, NINF
)
80 self
.assert_(math
.isnan(math
.acosh(NAN
)))
83 self
.assertRaises(TypeError, math
.asin
)
84 self
.ftest('asin(-1)', math
.asin(-1), -math
.pi
/2)
85 self
.ftest('asin(0)', math
.asin(0), 0)
86 self
.ftest('asin(1)', math
.asin(1), math
.pi
/2)
87 self
.assertRaises(ValueError, math
.asin
, INF
)
88 self
.assertRaises(ValueError, math
.asin
, NINF
)
89 self
.assert_(math
.isnan(math
.asin(NAN
)))
92 self
.assertRaises(TypeError, math
.asinh
)
93 self
.ftest('asinh(0)', math
.asinh(0), 0)
94 self
.ftest('asinh(1)', math
.asinh(1), 0.88137358701954305)
95 self
.ftest('asinh(-1)', math
.asinh(-1), -0.88137358701954305)
96 self
.assertEquals(math
.asinh(INF
), INF
)
97 self
.assertEquals(math
.asinh(NINF
), NINF
)
98 self
.assert_(math
.isnan(math
.asinh(NAN
)))
101 self
.assertRaises(TypeError, math
.atan
)
102 self
.ftest('atan(-1)', math
.atan(-1), -math
.pi
/4)
103 self
.ftest('atan(0)', math
.atan(0), 0)
104 self
.ftest('atan(1)', math
.atan(1), math
.pi
/4)
105 self
.ftest('atan(inf)', math
.atan(INF
), math
.pi
/2)
106 self
.ftest('atan(-inf)', math
.atan(NINF
), -math
.pi
/2)
107 self
.assert_(math
.isnan(math
.atan(NAN
)))
110 self
.assertRaises(TypeError, math
.atan
)
111 self
.ftest('atanh(0)', math
.atanh(0), 0)
112 self
.ftest('atanh(0.5)', math
.atanh(0.5), 0.54930614433405489)
113 self
.ftest('atanh(-0.5)', math
.atanh(-0.5), -0.54930614433405489)
114 self
.assertRaises(ValueError, math
.atanh
, 1)
115 self
.assertRaises(ValueError, math
.atanh
, -1)
116 self
.assertRaises(ValueError, math
.atanh
, INF
)
117 self
.assertRaises(ValueError, math
.atanh
, NINF
)
118 self
.assert_(math
.isnan(math
.atanh(NAN
)))
121 self
.assertRaises(TypeError, math
.atan2
)
122 self
.ftest('atan2(-1, 0)', math
.atan2(-1, 0), -math
.pi
/2)
123 self
.ftest('atan2(-1, 1)', math
.atan2(-1, 1), -math
.pi
/4)
124 self
.ftest('atan2(0, 1)', math
.atan2(0, 1), 0)
125 self
.ftest('atan2(1, 1)', math
.atan2(1, 1), math
.pi
/4)
126 self
.ftest('atan2(1, 0)', math
.atan2(1, 0), math
.pi
/2)
129 self
.ftest('atan2(0., -inf)', math
.atan2(0., NINF
), math
.pi
)
130 self
.ftest('atan2(0., -2.3)', math
.atan2(0., -2.3), math
.pi
)
131 self
.ftest('atan2(0., -0.)', math
.atan2(0., -0.), math
.pi
)
132 self
.assertEqual(math
.atan2(0., 0.), 0.)
133 self
.assertEqual(math
.atan2(0., 2.3), 0.)
134 self
.assertEqual(math
.atan2(0., INF
), 0.)
135 self
.assert_(math
.isnan(math
.atan2(0., NAN
)))
137 self
.ftest('atan2(-0., -inf)', math
.atan2(-0., NINF
), -math
.pi
)
138 self
.ftest('atan2(-0., -2.3)', math
.atan2(-0., -2.3), -math
.pi
)
139 self
.ftest('atan2(-0., -0.)', math
.atan2(-0., -0.), -math
.pi
)
140 self
.assertEqual(math
.atan2(-0., 0.), -0.)
141 self
.assertEqual(math
.atan2(-0., 2.3), -0.)
142 self
.assertEqual(math
.atan2(-0., INF
), -0.)
143 self
.assert_(math
.isnan(math
.atan2(-0., NAN
)))
145 self
.ftest('atan2(inf, -inf)', math
.atan2(INF
, NINF
), math
.pi
*3/4)
146 self
.ftest('atan2(inf, -2.3)', math
.atan2(INF
, -2.3), math
.pi
/2)
147 self
.ftest('atan2(inf, -0.)', math
.atan2(INF
, -0.0), math
.pi
/2)
148 self
.ftest('atan2(inf, 0.)', math
.atan2(INF
, 0.0), math
.pi
/2)
149 self
.ftest('atan2(inf, 2.3)', math
.atan2(INF
, 2.3), math
.pi
/2)
150 self
.ftest('atan2(inf, inf)', math
.atan2(INF
, INF
), math
.pi
/4)
151 self
.assert_(math
.isnan(math
.atan2(INF
, NAN
)))
152 # math.atan2(NINF, x)
153 self
.ftest('atan2(-inf, -inf)', math
.atan2(NINF
, NINF
), -math
.pi
*3/4)
154 self
.ftest('atan2(-inf, -2.3)', math
.atan2(NINF
, -2.3), -math
.pi
/2)
155 self
.ftest('atan2(-inf, -0.)', math
.atan2(NINF
, -0.0), -math
.pi
/2)
156 self
.ftest('atan2(-inf, 0.)', math
.atan2(NINF
, 0.0), -math
.pi
/2)
157 self
.ftest('atan2(-inf, 2.3)', math
.atan2(NINF
, 2.3), -math
.pi
/2)
158 self
.ftest('atan2(-inf, inf)', math
.atan2(NINF
, INF
), -math
.pi
/4)
159 self
.assert_(math
.isnan(math
.atan2(NINF
, NAN
)))
160 # math.atan2(+finite, x)
161 self
.ftest('atan2(2.3, -inf)', math
.atan2(2.3, NINF
), math
.pi
)
162 self
.ftest('atan2(2.3, -0.)', math
.atan2(2.3, -0.), math
.pi
/2)
163 self
.ftest('atan2(2.3, 0.)', math
.atan2(2.3, 0.), math
.pi
/2)
164 self
.assertEqual(math
.atan2(2.3, INF
), 0.)
165 self
.assert_(math
.isnan(math
.atan2(2.3, NAN
)))
166 # math.atan2(-finite, x)
167 self
.ftest('atan2(-2.3, -inf)', math
.atan2(-2.3, NINF
), -math
.pi
)
168 self
.ftest('atan2(-2.3, -0.)', math
.atan2(-2.3, -0.), -math
.pi
/2)
169 self
.ftest('atan2(-2.3, 0.)', math
.atan2(-2.3, 0.), -math
.pi
/2)
170 self
.assertEqual(math
.atan2(-2.3, INF
), -0.)
171 self
.assert_(math
.isnan(math
.atan2(-2.3, NAN
)))
173 self
.assert_(math
.isnan(math
.atan2(NAN
, NINF
)))
174 self
.assert_(math
.isnan(math
.atan2(NAN
, -2.3)))
175 self
.assert_(math
.isnan(math
.atan2(NAN
, -0.)))
176 self
.assert_(math
.isnan(math
.atan2(NAN
, 0.)))
177 self
.assert_(math
.isnan(math
.atan2(NAN
, 2.3)))
178 self
.assert_(math
.isnan(math
.atan2(NAN
, INF
)))
179 self
.assert_(math
.isnan(math
.atan2(NAN
, NAN
)))
182 self
.assertRaises(TypeError, math
.ceil
)
183 # These types will be int in py3k.
184 self
.assertEquals(float, type(math
.ceil(1)))
185 self
.assertEquals(float, type(math
.ceil(1L)))
186 self
.assertEquals(float, type(math
.ceil(1.0)))
187 self
.ftest('ceil(0.5)', math
.ceil(0.5), 1)
188 self
.ftest('ceil(1.0)', math
.ceil(1.0), 1)
189 self
.ftest('ceil(1.5)', math
.ceil(1.5), 2)
190 self
.ftest('ceil(-0.5)', math
.ceil(-0.5), 0)
191 self
.ftest('ceil(-1.0)', math
.ceil(-1.0), -1)
192 self
.ftest('ceil(-1.5)', math
.ceil(-1.5), -1)
193 self
.assertEquals(math
.ceil(INF
), INF
)
194 self
.assertEquals(math
.ceil(NINF
), NINF
)
195 self
.assert_(math
.isnan(math
.ceil(NAN
)))
197 class TestCeil(object):
200 class TestNoCeil(object):
202 self
.ftest('ceil(TestCeil())', math
.ceil(TestCeil()), 42)
203 self
.assertRaises(TypeError, math
.ceil
, TestNoCeil())
206 t
.__ceil
__ = lambda *args
: args
207 self
.assertRaises(TypeError, math
.ceil
, t
)
208 self
.assertRaises(TypeError, math
.ceil
, t
, 0)
210 if float.__getformat
__("double").startswith("IEEE"):
211 def testCopysign(self
):
212 self
.assertRaises(TypeError, math
.copysign
)
213 # copysign should let us distinguish signs of zeros
214 self
.assertEquals(copysign(1., 0.), 1.)
215 self
.assertEquals(copysign(1., -0.), -1.)
216 self
.assertEquals(copysign(INF
, 0.), INF
)
217 self
.assertEquals(copysign(INF
, -0.), NINF
)
218 self
.assertEquals(copysign(NINF
, 0.), INF
)
219 self
.assertEquals(copysign(NINF
, -0.), NINF
)
221 self
.assertEquals(copysign(1., INF
), 1.)
222 self
.assertEquals(copysign(1., NINF
), -1.)
223 self
.assertEquals(copysign(INF
, INF
), INF
)
224 self
.assertEquals(copysign(INF
, NINF
), NINF
)
225 self
.assertEquals(copysign(NINF
, INF
), INF
)
226 self
.assertEquals(copysign(NINF
, NINF
), NINF
)
227 self
.assert_(math
.isnan(copysign(NAN
, 1.)))
228 self
.assert_(math
.isnan(copysign(NAN
, INF
)))
229 self
.assert_(math
.isnan(copysign(NAN
, NINF
)))
230 self
.assert_(math
.isnan(copysign(NAN
, NAN
)))
231 # copysign(INF, NAN) may be INF or it may be NINF, since
232 # we don't know whether the sign bit of NAN is set on any
234 self
.assert_(math
.isinf(copysign(INF
, NAN
)))
235 # similarly, copysign(2., NAN) could be 2. or -2.
236 self
.assertEquals(abs(copysign(2., NAN
)), 2.)
239 self
.assertRaises(TypeError, math
.cos
)
240 self
.ftest('cos(-pi/2)', math
.cos(-math
.pi
/2), 0)
241 self
.ftest('cos(0)', math
.cos(0), 1)
242 self
.ftest('cos(pi/2)', math
.cos(math
.pi
/2), 0)
243 self
.ftest('cos(pi)', math
.cos(math
.pi
), -1)
245 self
.assert_(math
.isnan(math
.cos(INF
)))
246 self
.assert_(math
.isnan(math
.cos(NINF
)))
248 self
.assertRaises(ValueError, math
.cos
, INF
)
249 self
.assertRaises(ValueError, math
.cos
, NINF
)
250 self
.assert_(math
.isnan(math
.cos(NAN
)))
253 self
.assertRaises(TypeError, math
.cosh
)
254 self
.ftest('cosh(0)', math
.cosh(0), 1)
255 self
.ftest('cosh(2)-2*cosh(1)**2', math
.cosh(2)-2*math
.cosh(1)**2, -1) # Thanks to Lambert
256 self
.assertEquals(math
.cosh(INF
), INF
)
257 self
.assertEquals(math
.cosh(NINF
), INF
)
258 self
.assert_(math
.isnan(math
.cosh(NAN
)))
260 def testDegrees(self
):
261 self
.assertRaises(TypeError, math
.degrees
)
262 self
.ftest('degrees(pi)', math
.degrees(math
.pi
), 180.0)
263 self
.ftest('degrees(pi/2)', math
.degrees(math
.pi
/2), 90.0)
264 self
.ftest('degrees(-pi/4)', math
.degrees(-math
.pi
/4), -45.0)
267 self
.assertRaises(TypeError, math
.exp
)
268 self
.ftest('exp(-1)', math
.exp(-1), 1/math
.e
)
269 self
.ftest('exp(0)', math
.exp(0), 1)
270 self
.ftest('exp(1)', math
.exp(1), math
.e
)
271 self
.assertEquals(math
.exp(INF
), INF
)
272 self
.assertEquals(math
.exp(NINF
), 0.)
273 self
.assert_(math
.isnan(math
.exp(NAN
)))
276 self
.assertRaises(TypeError, math
.fabs
)
277 self
.ftest('fabs(-1)', math
.fabs(-1), 1)
278 self
.ftest('fabs(0)', math
.fabs(0), 0)
279 self
.ftest('fabs(1)', math
.fabs(1), 1)
281 def testFactorial(self
):
284 for i
in range(1, int(n
)+1):
287 values
= range(10) + [50, 100, 500]
288 random
.shuffle(values
)
290 for cast
in (int, long, float):
291 self
.assertEqual(math
.factorial(cast(x
)), fact(x
), (x
, fact(x
), math
.factorial(x
)))
292 self
.assertRaises(ValueError, math
.factorial
, -1)
293 self
.assertRaises(ValueError, math
.factorial
, math
.pi
)
296 self
.assertRaises(TypeError, math
.floor
)
297 # These types will be int in py3k.
298 self
.assertEquals(float, type(math
.floor(1)))
299 self
.assertEquals(float, type(math
.floor(1L)))
300 self
.assertEquals(float, type(math
.floor(1.0)))
301 self
.ftest('floor(0.5)', math
.floor(0.5), 0)
302 self
.ftest('floor(1.0)', math
.floor(1.0), 1)
303 self
.ftest('floor(1.5)', math
.floor(1.5), 1)
304 self
.ftest('floor(-0.5)', math
.floor(-0.5), -1)
305 self
.ftest('floor(-1.0)', math
.floor(-1.0), -1)
306 self
.ftest('floor(-1.5)', math
.floor(-1.5), -2)
307 # pow() relies on floor() to check for integers
308 # This fails on some platforms - so check it here
309 self
.ftest('floor(1.23e167)', math
.floor(1.23e167
), 1.23e167
)
310 self
.ftest('floor(-1.23e167)', math
.floor(-1.23e167
), -1.23e167
)
311 self
.assertEquals(math
.ceil(INF
), INF
)
312 self
.assertEquals(math
.ceil(NINF
), NINF
)
313 self
.assert_(math
.isnan(math
.floor(NAN
)))
315 class TestFloor(object):
318 class TestNoFloor(object):
320 self
.ftest('floor(TestFloor())', math
.floor(TestFloor()), 42)
321 self
.assertRaises(TypeError, math
.floor
, TestNoFloor())
324 t
.__floor
__ = lambda *args
: args
325 self
.assertRaises(TypeError, math
.floor
, t
)
326 self
.assertRaises(TypeError, math
.floor
, t
, 0)
329 self
.assertRaises(TypeError, math
.fmod
)
330 self
.ftest('fmod(10,1)', math
.fmod(10,1), 0)
331 self
.ftest('fmod(10,0.5)', math
.fmod(10,0.5), 0)
332 self
.ftest('fmod(10,1.5)', math
.fmod(10,1.5), 1)
333 self
.ftest('fmod(-10,1)', math
.fmod(-10,1), 0)
334 self
.ftest('fmod(-10,0.5)', math
.fmod(-10,0.5), 0)
335 self
.ftest('fmod(-10,1.5)', math
.fmod(-10,1.5), -1)
336 self
.assert_(math
.isnan(math
.fmod(NAN
, 1.)))
337 self
.assert_(math
.isnan(math
.fmod(1., NAN
)))
338 self
.assert_(math
.isnan(math
.fmod(NAN
, NAN
)))
339 self
.assertRaises(ValueError, math
.fmod
, 1., 0.)
340 self
.assertRaises(ValueError, math
.fmod
, INF
, 1.)
341 self
.assertRaises(ValueError, math
.fmod
, NINF
, 1.)
342 self
.assertRaises(ValueError, math
.fmod
, INF
, 0.)
343 self
.assertEquals(math
.fmod(3.0, INF
), 3.0)
344 self
.assertEquals(math
.fmod(-3.0, INF
), -3.0)
345 self
.assertEquals(math
.fmod(3.0, NINF
), 3.0)
346 self
.assertEquals(math
.fmod(-3.0, NINF
), -3.0)
347 self
.assertEquals(math
.fmod(0.0, 3.0), 0.0)
348 self
.assertEquals(math
.fmod(0.0, NINF
), 0.0)
351 self
.assertRaises(TypeError, math
.frexp
)
353 def testfrexp(name
, (mant
, exp
), (emant
, eexp
)):
354 if abs(mant
-emant
) > eps
or exp
!= eexp
:
355 self
.fail('%s returned %r, expected %r'%\
356 (name
, (mant
, exp
), (emant
,eexp
)))
358 testfrexp('frexp(-1)', math
.frexp(-1), (-0.5, 1))
359 testfrexp('frexp(0)', math
.frexp(0), (0, 0))
360 testfrexp('frexp(1)', math
.frexp(1), (0.5, 1))
361 testfrexp('frexp(2)', math
.frexp(2), (0.5, 2))
363 self
.assertEquals(math
.frexp(INF
)[0], INF
)
364 self
.assertEquals(math
.frexp(NINF
)[0], NINF
)
365 self
.assert_(math
.isnan(math
.frexp(NAN
)[0]))
368 self
.assertRaises(TypeError, math
.hypot
)
369 self
.ftest('hypot(0,0)', math
.hypot(0,0), 0)
370 self
.ftest('hypot(3,4)', math
.hypot(3,4), 5)
371 self
.assertEqual(math
.hypot(NAN
, INF
), INF
)
372 self
.assertEqual(math
.hypot(INF
, NAN
), INF
)
373 self
.assertEqual(math
.hypot(NAN
, NINF
), INF
)
374 self
.assertEqual(math
.hypot(NINF
, NAN
), INF
)
375 self
.assert_(math
.isnan(math
.hypot(1.0, NAN
)))
376 self
.assert_(math
.isnan(math
.hypot(NAN
, -2.0)))
379 self
.assertRaises(TypeError, math
.ldexp
)
380 self
.ftest('ldexp(0,1)', math
.ldexp(0,1), 0)
381 self
.ftest('ldexp(1,1)', math
.ldexp(1,1), 2)
382 self
.ftest('ldexp(1,-1)', math
.ldexp(1,-1), 0.5)
383 self
.ftest('ldexp(-1,1)', math
.ldexp(-1,1), -2)
384 self
.assertRaises(OverflowError, math
.ldexp
, 1., 1000000)
385 self
.assertRaises(OverflowError, math
.ldexp
, -1., 1000000)
386 self
.assertEquals(math
.ldexp(1., -1000000), 0.)
387 self
.assertEquals(math
.ldexp(-1., -1000000), -0.)
388 self
.assertEquals(math
.ldexp(INF
, 30), INF
)
389 self
.assertEquals(math
.ldexp(NINF
, -213), NINF
)
390 self
.assert_(math
.isnan(math
.ldexp(NAN
, 0)))
392 # large second argument
393 for n
in [10**5, 10L**5, 10**10, 10L**10, 10**20, 10**40]:
394 self
.assertEquals(math
.ldexp(INF
, -n
), INF
)
395 self
.assertEquals(math
.ldexp(NINF
, -n
), NINF
)
396 self
.assertEquals(math
.ldexp(1., -n
), 0.)
397 self
.assertEquals(math
.ldexp(-1., -n
), -0.)
398 self
.assertEquals(math
.ldexp(0., -n
), 0.)
399 self
.assertEquals(math
.ldexp(-0., -n
), -0.)
400 self
.assert_(math
.isnan(math
.ldexp(NAN
, -n
)))
402 self
.assertRaises(OverflowError, math
.ldexp
, 1., n
)
403 self
.assertRaises(OverflowError, math
.ldexp
, -1., n
)
404 self
.assertEquals(math
.ldexp(0., n
), 0.)
405 self
.assertEquals(math
.ldexp(-0., n
), -0.)
406 self
.assertEquals(math
.ldexp(INF
, n
), INF
)
407 self
.assertEquals(math
.ldexp(NINF
, n
), NINF
)
408 self
.assert_(math
.isnan(math
.ldexp(NAN
, n
)))
411 self
.assertRaises(TypeError, math
.log
)
412 self
.ftest('log(1/e)', math
.log(1/math
.e
), -1)
413 self
.ftest('log(1)', math
.log(1), 0)
414 self
.ftest('log(e)', math
.log(math
.e
), 1)
415 self
.ftest('log(32,2)', math
.log(32,2), 5)
416 self
.ftest('log(10**40, 10)', math
.log(10**40, 10), 40)
417 self
.ftest('log(10**40, 10**20)', math
.log(10**40, 10**20), 2)
418 self
.assertEquals(math
.log(INF
), INF
)
419 self
.assertRaises(ValueError, math
.log
, NINF
)
420 self
.assert_(math
.isnan(math
.log(NAN
)))
423 self
.assertRaises(TypeError, math
.log1p
)
424 self
.ftest('log1p(1/e -1)', math
.log1p(1/math
.e
-1), -1)
425 self
.ftest('log1p(0)', math
.log1p(0), 0)
426 self
.ftest('log1p(e-1)', math
.log1p(math
.e
-1), 1)
427 self
.ftest('log1p(1)', math
.log1p(1), math
.log(2))
428 self
.assertEquals(math
.log1p(INF
), INF
)
429 self
.assertRaises(ValueError, math
.log1p
, NINF
)
430 self
.assert_(math
.isnan(math
.log1p(NAN
)))
432 self
.assertAlmostEquals(math
.log1p(n
), 62.383246250395075)
433 self
.assertAlmostEquals(math
.log1p(n
), math
.log1p(float(n
)))
436 self
.assertRaises(TypeError, math
.log10
)
437 self
.ftest('log10(0.1)', math
.log10(0.1), -1)
438 self
.ftest('log10(1)', math
.log10(1), 0)
439 self
.ftest('log10(10)', math
.log10(10), 1)
440 self
.assertEquals(math
.log(INF
), INF
)
441 self
.assertRaises(ValueError, math
.log10
, NINF
)
442 self
.assert_(math
.isnan(math
.log10(NAN
)))
445 self
.assertRaises(TypeError, math
.modf
)
447 def testmodf(name
, (v1
, v2
), (e1
, e2
)):
448 if abs(v1
-e1
) > eps
or abs(v2
-e2
):
449 self
.fail('%s returned %r, expected %r'%\
450 (name
, (v1
,v2
), (e1
,e2
)))
452 testmodf('modf(1.5)', math
.modf(1.5), (0.5, 1.0))
453 testmodf('modf(-1.5)', math
.modf(-1.5), (-0.5, -1.0))
455 self
.assertEquals(math
.modf(INF
), (0.0, INF
))
456 self
.assertEquals(math
.modf(NINF
), (-0.0, NINF
))
458 modf_nan
= math
.modf(NAN
)
459 self
.assert_(math
.isnan(modf_nan
[0]))
460 self
.assert_(math
.isnan(modf_nan
[1]))
463 self
.assertRaises(TypeError, math
.pow)
464 self
.ftest('pow(0,1)', math
.pow(0,1), 0)
465 self
.ftest('pow(1,0)', math
.pow(1,0), 1)
466 self
.ftest('pow(2,1)', math
.pow(2,1), 2)
467 self
.ftest('pow(2,-1)', math
.pow(2,-1), 0.5)
468 self
.assertEqual(math
.pow(INF
, 1), INF
)
469 self
.assertEqual(math
.pow(NINF
, 1), NINF
)
470 self
.assertEqual((math
.pow(1, INF
)), 1.)
471 self
.assertEqual((math
.pow(1, NINF
)), 1.)
472 self
.assert_(math
.isnan(math
.pow(NAN
, 1)))
473 self
.assert_(math
.isnan(math
.pow(2, NAN
)))
474 self
.assert_(math
.isnan(math
.pow(0, NAN
)))
475 self
.assertEqual(math
.pow(1, NAN
), 1)
478 self
.assertEqual(math
.pow(0., INF
), 0.)
479 self
.assertEqual(math
.pow(0., 3.), 0.)
480 self
.assertEqual(math
.pow(0., 2.3), 0.)
481 self
.assertEqual(math
.pow(0., 2.), 0.)
482 self
.assertEqual(math
.pow(0., 0.), 1.)
483 self
.assertEqual(math
.pow(0., -0.), 1.)
484 self
.assertRaises(ValueError, math
.pow, 0., -2.)
485 self
.assertRaises(ValueError, math
.pow, 0., -2.3)
486 self
.assertRaises(ValueError, math
.pow, 0., -3.)
487 self
.assertRaises(ValueError, math
.pow, 0., NINF
)
488 self
.assert_(math
.isnan(math
.pow(0., NAN
)))
491 self
.assertEqual(math
.pow(INF
, INF
), INF
)
492 self
.assertEqual(math
.pow(INF
, 3.), INF
)
493 self
.assertEqual(math
.pow(INF
, 2.3), INF
)
494 self
.assertEqual(math
.pow(INF
, 2.), INF
)
495 self
.assertEqual(math
.pow(INF
, 0.), 1.)
496 self
.assertEqual(math
.pow(INF
, -0.), 1.)
497 self
.assertEqual(math
.pow(INF
, -2.), 0.)
498 self
.assertEqual(math
.pow(INF
, -2.3), 0.)
499 self
.assertEqual(math
.pow(INF
, -3.), 0.)
500 self
.assertEqual(math
.pow(INF
, NINF
), 0.)
501 self
.assert_(math
.isnan(math
.pow(INF
, NAN
)))
504 self
.assertEqual(math
.pow(-0., INF
), 0.)
505 self
.assertEqual(math
.pow(-0., 3.), -0.)
506 self
.assertEqual(math
.pow(-0., 2.3), 0.)
507 self
.assertEqual(math
.pow(-0., 2.), 0.)
508 self
.assertEqual(math
.pow(-0., 0.), 1.)
509 self
.assertEqual(math
.pow(-0., -0.), 1.)
510 self
.assertRaises(ValueError, math
.pow, -0., -2.)
511 self
.assertRaises(ValueError, math
.pow, -0., -2.3)
512 self
.assertRaises(ValueError, math
.pow, -0., -3.)
513 self
.assertRaises(ValueError, math
.pow, -0., NINF
)
514 self
.assert_(math
.isnan(math
.pow(-0., NAN
)))
517 self
.assertEqual(math
.pow(NINF
, INF
), INF
)
518 self
.assertEqual(math
.pow(NINF
, 3.), NINF
)
519 self
.assertEqual(math
.pow(NINF
, 2.3), INF
)
520 self
.assertEqual(math
.pow(NINF
, 2.), INF
)
521 self
.assertEqual(math
.pow(NINF
, 0.), 1.)
522 self
.assertEqual(math
.pow(NINF
, -0.), 1.)
523 self
.assertEqual(math
.pow(NINF
, -2.), 0.)
524 self
.assertEqual(math
.pow(NINF
, -2.3), 0.)
525 self
.assertEqual(math
.pow(NINF
, -3.), -0.)
526 self
.assertEqual(math
.pow(NINF
, NINF
), 0.)
527 self
.assert_(math
.isnan(math
.pow(NINF
, NAN
)))
530 self
.assertEqual(math
.pow(-1., INF
), 1.)
531 self
.assertEqual(math
.pow(-1., 3.), -1.)
532 self
.assertRaises(ValueError, math
.pow, -1., 2.3)
533 self
.assertEqual(math
.pow(-1., 2.), 1.)
534 self
.assertEqual(math
.pow(-1., 0.), 1.)
535 self
.assertEqual(math
.pow(-1., -0.), 1.)
536 self
.assertEqual(math
.pow(-1., -2.), 1.)
537 self
.assertRaises(ValueError, math
.pow, -1., -2.3)
538 self
.assertEqual(math
.pow(-1., -3.), -1.)
539 self
.assertEqual(math
.pow(-1., NINF
), 1.)
540 self
.assert_(math
.isnan(math
.pow(-1., NAN
)))
543 self
.assertEqual(math
.pow(1., INF
), 1.)
544 self
.assertEqual(math
.pow(1., 3.), 1.)
545 self
.assertEqual(math
.pow(1., 2.3), 1.)
546 self
.assertEqual(math
.pow(1., 2.), 1.)
547 self
.assertEqual(math
.pow(1., 0.), 1.)
548 self
.assertEqual(math
.pow(1., -0.), 1.)
549 self
.assertEqual(math
.pow(1., -2.), 1.)
550 self
.assertEqual(math
.pow(1., -2.3), 1.)
551 self
.assertEqual(math
.pow(1., -3.), 1.)
552 self
.assertEqual(math
.pow(1., NINF
), 1.)
553 self
.assertEqual(math
.pow(1., NAN
), 1.)
555 # pow(x, 0) should be 1 for any x
556 self
.assertEqual(math
.pow(2.3, 0.), 1.)
557 self
.assertEqual(math
.pow(-2.3, 0.), 1.)
558 self
.assertEqual(math
.pow(NAN
, 0.), 1.)
559 self
.assertEqual(math
.pow(2.3, -0.), 1.)
560 self
.assertEqual(math
.pow(-2.3, -0.), 1.)
561 self
.assertEqual(math
.pow(NAN
, -0.), 1.)
563 # pow(x, y) is invalid if x is negative and y is not integral
564 self
.assertRaises(ValueError, math
.pow, -1., 2.3)
565 self
.assertRaises(ValueError, math
.pow, -15., -3.1)
568 self
.assertEqual(math
.pow(1.9, NINF
), 0.)
569 self
.assertEqual(math
.pow(1.1, NINF
), 0.)
570 self
.assertEqual(math
.pow(0.9, NINF
), INF
)
571 self
.assertEqual(math
.pow(0.1, NINF
), INF
)
572 self
.assertEqual(math
.pow(-0.1, NINF
), INF
)
573 self
.assertEqual(math
.pow(-0.9, NINF
), INF
)
574 self
.assertEqual(math
.pow(-1.1, NINF
), 0.)
575 self
.assertEqual(math
.pow(-1.9, NINF
), 0.)
578 self
.assertEqual(math
.pow(1.9, INF
), INF
)
579 self
.assertEqual(math
.pow(1.1, INF
), INF
)
580 self
.assertEqual(math
.pow(0.9, INF
), 0.)
581 self
.assertEqual(math
.pow(0.1, INF
), 0.)
582 self
.assertEqual(math
.pow(-0.1, INF
), 0.)
583 self
.assertEqual(math
.pow(-0.9, INF
), 0.)
584 self
.assertEqual(math
.pow(-1.1, INF
), INF
)
585 self
.assertEqual(math
.pow(-1.9, INF
), INF
)
587 # pow(x, y) should work for x negative, y an integer
588 self
.ftest('(-2.)**3.', math
.pow(-2.0, 3.0), -8.0)
589 self
.ftest('(-2.)**2.', math
.pow(-2.0, 2.0), 4.0)
590 self
.ftest('(-2.)**1.', math
.pow(-2.0, 1.0), -2.0)
591 self
.ftest('(-2.)**0.', math
.pow(-2.0, 0.0), 1.0)
592 self
.ftest('(-2.)**-0.', math
.pow(-2.0, -0.0), 1.0)
593 self
.ftest('(-2.)**-1.', math
.pow(-2.0, -1.0), -0.5)
594 self
.ftest('(-2.)**-2.', math
.pow(-2.0, -2.0), 0.25)
595 self
.ftest('(-2.)**-3.', math
.pow(-2.0, -3.0), -0.125)
596 self
.assertRaises(ValueError, math
.pow, -2.0, -0.5)
597 self
.assertRaises(ValueError, math
.pow, -2.0, 0.5)
599 # the following tests have been commented out since they don't
600 # really belong here: the implementation of ** for floats is
601 # independent of the implemention of math.pow
602 #self.assertEqual(1**NAN, 1)
603 #self.assertEqual(1**INF, 1)
604 #self.assertEqual(1**NINF, 1)
605 #self.assertEqual(1**0, 1)
606 #self.assertEqual(1.**NAN, 1)
607 #self.assertEqual(1.**INF, 1)
608 #self.assertEqual(1.**NINF, 1)
609 #self.assertEqual(1.**0, 1)
611 def testRadians(self
):
612 self
.assertRaises(TypeError, math
.radians
)
613 self
.ftest('radians(180)', math
.radians(180), math
.pi
)
614 self
.ftest('radians(90)', math
.radians(90), math
.pi
/2)
615 self
.ftest('radians(-45)', math
.radians(-45), -math
.pi
/4)
618 self
.assertRaises(TypeError, math
.sin
)
619 self
.ftest('sin(0)', math
.sin(0), 0)
620 self
.ftest('sin(pi/2)', math
.sin(math
.pi
/2), 1)
621 self
.ftest('sin(-pi/2)', math
.sin(-math
.pi
/2), -1)
623 self
.assert_(math
.isnan(math
.sin(INF
)))
624 self
.assert_(math
.isnan(math
.sin(NINF
)))
626 self
.assertRaises(ValueError, math
.sin
, INF
)
627 self
.assertRaises(ValueError, math
.sin
, NINF
)
628 self
.assert_(math
.isnan(math
.sin(NAN
)))
631 self
.assertRaises(TypeError, math
.sinh
)
632 self
.ftest('sinh(0)', math
.sinh(0), 0)
633 self
.ftest('sinh(1)**2-cosh(1)**2', math
.sinh(1)**2-math
.cosh(1)**2, -1)
634 self
.ftest('sinh(1)+sinh(-1)', math
.sinh(1)+math
.sinh(-1), 0)
635 self
.assertEquals(math
.sinh(INF
), INF
)
636 self
.assertEquals(math
.sinh(NINF
), NINF
)
637 self
.assert_(math
.isnan(math
.sinh(NAN
)))
640 self
.assertRaises(TypeError, math
.sqrt
)
641 self
.ftest('sqrt(0)', math
.sqrt(0), 0)
642 self
.ftest('sqrt(1)', math
.sqrt(1), 1)
643 self
.ftest('sqrt(4)', math
.sqrt(4), 2)
644 self
.assertEquals(math
.sqrt(INF
), INF
)
645 self
.assertRaises(ValueError, math
.sqrt
, NINF
)
646 self
.assert_(math
.isnan(math
.sqrt(NAN
)))
649 # math.sum relies on exact rounding for correct operation.
650 # There's a known problem with IA32 floating-point that causes
651 # inexact rounding in some situations, and will cause the
652 # math.sum tests below to fail; see issue #2937. On non IEEE
653 # 754 platforms, and on IEEE 754 platforms that exhibit the
654 # problem described in issue #2937, we simply skip the whole
657 if not float.__getformat
__("double").startswith("IEEE"):
660 # on IEEE 754 compliant machines, both of the expressions
661 # below should round to 10000000000000002.0.
662 if 1e16
+2.999 != 1e16
+2.9999:
665 # Python version of math.sum algorithm, for comparison
667 """Full precision sum of values in iterable. Returns the value of
668 the sum, rounded to the nearest representable floating-point number
669 using the round-half-to-even rule.
672 # Stage 1: accumulate partials
685 partials
[i
:] = [x
] if x
else []
687 # Stage 2: sum partials
691 # sum from the top, stopping as soon as the sum is inexact.
692 total
= partials
.pop()
695 old_total
, total
= total
, total
+ x
696 error
= x
- (total
- old_total
)
698 # adjust for correct rounding if necessary
699 if partials
and (partials
[-1] > 0.0) == (error
> 0.0) and \
700 total
+ 2*error
- total
== 2*error
:
705 from sys
import float_info
706 maxfloat
= float_info
.max
707 twopow
= 2.**(float_info
.max_exp
- 1)
712 ([1e100
, 1.0, -1e100
, 1e-100, 1e50
, -1.0, -1e50
], 1e-100),
713 ([1e308
, 1e308
, -1e308
], OverflowError),
714 ([-1e308
, 1e308
, 1e308
], 1e308
),
715 ([1e308
, -1e308
, 1e308
], 1e308
),
716 ([2.0**1023, 2.0**1023, -2.0**1000], OverflowError),
717 ([twopow
, twopow
, twopow
, twopow
, -twopow
, -twopow
, -twopow
],
719 ([2.0**53, -0.5, -2.0**-54], 2.0**53-1.0),
720 ([2.0**53, 1.0, 2.0**-100], 2.0**53+2.0),
721 ([2.0**53+10.0, 1.0, 2.0**-100], 2.0**53+12.0),
723 ([2.0**53-4.0, 0.5, 2.0**-54], 2.0**53-3.0),
724 ([2.0**1023-2.0**970, -1.0, 2.0**1023], OverflowError),
725 ([maxfloat
, maxfloat
*2.**-54], maxfloat
),
726 ([maxfloat
, maxfloat
*2.**-53], OverflowError),
727 ([1./n
for n
in range(1, 1001)], 7.4854708605503451),
728 ([(-1.)**n
/n
for n
in range(1, 1001)], -0.69264743055982025),
729 ([1.7**(i
+1)-1.7**i
for i
in range(1000)] + [-1.7**1000], -1.0),
730 ([INF
, -INF
, NAN
], ValueError),
731 ([NAN
, INF
, -INF
], ValueError),
732 ([INF
, NAN
, INF
], ValueError),
734 ([INF
, INF
], OverflowError),
735 ([INF
, -INF
], ValueError),
736 ([-INF
, 1e308
, 1e308
, -INF
], OverflowError),
737 ([2.0**1023-2.0**970, 0.0, 2.0**1023], OverflowError),
738 ([2.0**1023-2.0**970, 1.0, 2.0**1023], OverflowError),
739 ([2.0**1023, 2.0**1023], OverflowError),
740 ([2.0**1023, 2.0**1023, -1.0], OverflowError),
741 ([twopow
, twopow
, twopow
, twopow
, -twopow
, -twopow
],
743 ([twopow
, twopow
, twopow
, twopow
, -twopow
, twopow
], OverflowError),
744 ([-twopow
, -twopow
, -twopow
, -twopow
], OverflowError),
746 ([2.**1023, 2.**1023, -2.**971], OverflowError),
747 ([2.**1023, 2.**1023, -2.**970], OverflowError),
748 ([-2.**970, 2.**1023, 2.**1023, -2.**-1074], OverflowError),
749 ([ 2.**1023, 2.**1023, -2.**970, 2.**-1074], OverflowError),
750 ([-2.**1023, 2.**971, -2.**1023], -maxfloat
),
751 ([-2.**1023, -2.**1023, 2.**970], OverflowError),
752 ([-2.**1023, -2.**1023, 2.**970, 2.**-1074], OverflowError),
753 ([-2.**-1074, -2.**1023, -2.**1023, 2.**970], OverflowError),
754 ([2.**930, -2.**980, 2.**1023, 2.**1023, twopow
, -twopow
],
756 ([2.**1023, 2.**1023, -1e307
], OverflowError),
757 ([1e16
, 1., 1e-16], 10000000000000002.0),
758 ([1e16
-2., 1.-2.**-53, -(1e16
-2.), -(1.-2.**-53)], 0.0),
761 for i
, (vals
, s
) in enumerate(test_values
):
762 if isinstance(s
, type) and issubclass(s
, Exception):
768 self
.fail("test %d failed: got %r, expected %r "
769 "for math.sum(%.100r)" %
770 (i
, m
, s
.__name
__, vals
))
773 self
.assertEqual(math
.sum(vals
), s
)
774 except OverflowError:
775 self
.fail("test %d failed: got OverflowError, expected %r "
776 "for math.sum(%.100r)" % (i
, s
, vals
))
778 self
.fail("test %d failed: got ValueError, expected %r "
779 "for math.sum(%.100r)" % (i
, s
, vals
))
781 # compare with output of msum above, but only when
782 # result isn't an IEEE special or an exception
783 if not math
.isinf(s
) and not math
.isnan(s
):
784 self
.assertEqual(msum(vals
), s
)
786 from random
import random
, gauss
, shuffle
787 for j
in xrange(1000):
788 vals
= [7, 1e100
, -7, -1e100
, -9e-20, 8e-20] * 10
790 for i
in xrange(200):
791 v
= gauss(0, random()) ** 7 - s
797 self
.assertEqual(msum(vals
), math
.sum(vals
))
801 self
.assertRaises(TypeError, math
.tan
)
802 self
.ftest('tan(0)', math
.tan(0), 0)
803 self
.ftest('tan(pi/4)', math
.tan(math
.pi
/4), 1)
804 self
.ftest('tan(-pi/4)', math
.tan(-math
.pi
/4), -1)
806 self
.assert_(math
.isnan(math
.tan(INF
)))
807 self
.assert_(math
.isnan(math
.tan(NINF
)))
809 self
.assertRaises(ValueError, math
.tan
, INF
)
810 self
.assertRaises(ValueError, math
.tan
, NINF
)
811 self
.assert_(math
.isnan(math
.tan(NAN
)))
814 self
.assertRaises(TypeError, math
.tanh
)
815 self
.ftest('tanh(0)', math
.tanh(0), 0)
816 self
.ftest('tanh(1)+tanh(-1)', math
.tanh(1)+math
.tanh(-1), 0)
817 self
.ftest('tanh(inf)', math
.tanh(INF
), 1)
818 self
.ftest('tanh(-inf)', math
.tanh(NINF
), -1)
819 self
.assert_(math
.isnan(math
.tanh(NAN
)))
820 # check that tanh(-0.) == -0. on IEEE 754 systems
821 if float.__getformat
__("double").startswith("IEEE"):
822 self
.assertEqual(math
.tanh(-0.), -0.)
823 self
.assertEqual(math
.copysign(1., math
.tanh(-0.)),
824 math
.copysign(1., -0.))
826 def test_trunc(self
):
827 self
.assertEqual(math
.trunc(1), 1)
828 self
.assertEqual(math
.trunc(-1), -1)
829 self
.assertEqual(type(math
.trunc(1)), int)
830 self
.assertEqual(type(math
.trunc(1.5)), int)
831 self
.assertEqual(math
.trunc(1.5), 1)
832 self
.assertEqual(math
.trunc(-1.5), -1)
833 self
.assertEqual(math
.trunc(1.999999), 1)
834 self
.assertEqual(math
.trunc(-1.999999), -1)
835 self
.assertEqual(math
.trunc(-0.999999), -0)
836 self
.assertEqual(math
.trunc(-100.999), -100)
838 class TestTrunc(object):
842 class TestNoTrunc(object):
845 self
.assertEqual(math
.trunc(TestTrunc()), 23)
847 self
.assertRaises(TypeError, math
.trunc
)
848 self
.assertRaises(TypeError, math
.trunc
, 1, 2)
849 # XXX: This is not ideal, but see the comment in math_trunc().
850 self
.assertRaises(AttributeError, math
.trunc
, TestNoTrunc())
853 t
.__trunc
__ = lambda *args
: args
854 self
.assertEquals((), math
.trunc(t
))
855 self
.assertRaises(TypeError, math
.trunc
, t
, 0)
857 def testCopysign(self
):
858 self
.assertEqual(math
.copysign(1, 42), 1.0)
859 self
.assertEqual(math
.copysign(0., 42), 0.0)
860 self
.assertEqual(math
.copysign(1., -42), -1.0)
861 self
.assertEqual(math
.copysign(3, 0.), 3.0)
862 self
.assertEqual(math
.copysign(4., -0.), -4.0)
865 self
.assert_(math
.isnan(float("nan")))
866 self
.assert_(math
.isnan(float("inf")* 0.))
867 self
.failIf(math
.isnan(float("inf")))
868 self
.failIf(math
.isnan(0.))
869 self
.failIf(math
.isnan(1.))
872 self
.assert_(math
.isinf(float("inf")))
873 self
.assert_(math
.isinf(float("-inf")))
874 self
.assert_(math
.isinf(1E400
))
875 self
.assert_(math
.isinf(-1E400
))
876 self
.failIf(math
.isinf(float("nan")))
877 self
.failIf(math
.isinf(0.))
878 self
.failIf(math
.isinf(1.))
880 # RED_FLAG 16-Oct-2000 Tim
881 # While 2.0 is more consistent about exceptions than previous releases, it
882 # still fails this part of the test on some platforms. For now, we only
883 # *run* test_exceptions() in verbose mode, so that this isn't normally
887 def test_exceptions(self
):
889 x
= math
.exp(-1000000000)
891 # mathmodule.c is failing to weed out underflows from libm, or
892 # we've got an fp format with huge dynamic range
893 self
.fail("underflowing exp() should not have raised "
896 self
.fail("underflowing exp() should have returned 0")
898 # If this fails, probably using a strict IEEE-754 conforming libm, and x
899 # is +Inf afterwards. But Python wants overflows detected by default.
901 x
= math
.exp(1000000000)
902 except OverflowError:
905 self
.fail("overflowing exp() didn't trigger OverflowError")
907 # If this fails, it could be a puzzle. One odd possibility is that
908 # mathmodule.c's macros are getting confused while comparing
909 # Inf (HUGE_VAL) to a NaN, and artificially setting errno to ERANGE
910 # as a result (and so raising OverflowError instead).
916 self
.fail("sqrt(-1) didn't raise ValueError")
918 def test_testfile(self
):
919 if not float.__getformat
__("double").startswith("IEEE"):
921 for id, fn
, ar
, ai
, er
, ei
, flags
in parse_testfile(test_file
):
922 # Skip if either the input or result is complex, or if
924 if ai
!= 0. or ei
!= 0. or flags
:
926 if fn
in ['rect', 'polar']:
927 # no real versions of rect, polar
929 func
= getattr(math
, fn
)
933 message
= ("Unexpected ValueError in " +
934 "test %s:%s(%r)\n" % (id, fn
, ar
))
936 except OverflowError:
937 message
= ("Unexpected OverflowError in " +
938 "test %s:%s(%r)\n" % (id, fn
, ar
))
940 self
.ftest("%s:%s(%r)" % (id, fn
, ar
), result
, er
)
943 from doctest
import DocFileSuite
944 suite
= unittest
.TestSuite()
945 suite
.addTest(unittest
.makeSuite(MathTests
))
946 suite
.addTest(DocFileSuite("ieee754.txt"))
949 if __name__
== '__main__':