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