Skip to content

Commit fa7a8af

Browse files
authored
Merge pull request #4150 from jopemachine/add-exp2
Add `math.exp2` implemented in cpython 3.11
2 parents f51b130 + ea4f2e7 commit fa7a8af

File tree

2 files changed

+64
-21
lines changed

2 files changed

+64
-21
lines changed

Lib/test/test_math.py

+59-21
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Python test set -- math module
22
# XXXX Should not do tests around zero only
33

4-
from test.support import run_unittest, verbose, requires_IEEE_754
4+
from test.support import verbose, requires_IEEE_754
55
from test import support
66
import unittest
77
import itertools
@@ -377,6 +377,24 @@ def testAtan2(self):
377377
self.assertTrue(math.isnan(math.atan2(NAN, INF)))
378378
self.assertTrue(math.isnan(math.atan2(NAN, NAN)))
379379

380+
# TODO: RUSTPYTHON
381+
@unittest.expectedFailure
382+
def testCbrt(self):
383+
self.assertRaises(TypeError, math.cbrt)
384+
self.ftest('cbrt(0)', math.cbrt(0), 0)
385+
self.ftest('cbrt(1)', math.cbrt(1), 1)
386+
self.ftest('cbrt(8)', math.cbrt(8), 2)
387+
self.ftest('cbrt(0.0)', math.cbrt(0.0), 0.0)
388+
self.ftest('cbrt(-0.0)', math.cbrt(-0.0), -0.0)
389+
self.ftest('cbrt(1.2)', math.cbrt(1.2), 1.062658569182611)
390+
self.ftest('cbrt(-2.6)', math.cbrt(-2.6), -1.375068867074141)
391+
self.ftest('cbrt(27)', math.cbrt(27), 3)
392+
self.ftest('cbrt(-1)', math.cbrt(-1), -1)
393+
self.ftest('cbrt(-27)', math.cbrt(-27), -3)
394+
self.assertEqual(math.cbrt(INF), INF)
395+
self.assertEqual(math.cbrt(NINF), NINF)
396+
self.assertTrue(math.isnan(math.cbrt(NAN)))
397+
380398
def testCeil(self):
381399
self.assertRaises(TypeError, math.ceil)
382400
self.assertEqual(int, type(math.ceil(0.5)))
@@ -485,6 +503,17 @@ def testExp(self):
485503
self.assertTrue(math.isnan(math.exp(NAN)))
486504
self.assertRaises(OverflowError, math.exp, 1000000)
487505

506+
def testExp2(self):
507+
self.assertRaises(TypeError, math.exp2)
508+
self.ftest('exp2(-1)', math.exp2(-1), 0.5)
509+
self.ftest('exp2(0)', math.exp2(0), 1)
510+
self.ftest('exp2(1)', math.exp2(1), 2)
511+
self.ftest('exp2(2.3)', math.exp2(2.3), 4.924577653379665)
512+
self.assertEqual(math.exp2(INF), INF)
513+
self.assertEqual(math.exp2(NINF), 0.)
514+
self.assertTrue(math.isnan(math.exp2(NAN)))
515+
self.assertRaises(OverflowError, math.exp2, 1000000)
516+
488517
def testFabs(self):
489518
self.assertRaises(TypeError, math.fabs)
490519
self.ftest('fabs(-1)', math.fabs(-1), 1)
@@ -1198,6 +1227,8 @@ def testmodf(name, result, expected):
11981227
self.assertTrue(math.isnan(modf_nan[0]))
11991228
self.assertTrue(math.isnan(modf_nan[1]))
12001229

1230+
# TODO: RUSTPYTHON
1231+
@unittest.expectedFailure
12011232
def testPow(self):
12021233
self.assertRaises(TypeError, math.pow)
12031234
self.ftest('pow(0,1)', math.pow(0,1), 0)
@@ -1223,7 +1254,7 @@ def testPow(self):
12231254
self.assertRaises(ValueError, math.pow, 0., -2.)
12241255
self.assertRaises(ValueError, math.pow, 0., -2.3)
12251256
self.assertRaises(ValueError, math.pow, 0., -3.)
1226-
self.assertRaises(ValueError, math.pow, 0., NINF)
1257+
self.assertEqual(math.pow(0., NINF), INF)
12271258
self.assertTrue(math.isnan(math.pow(0., NAN)))
12281259

12291260
# pow(INF, x)
@@ -1249,7 +1280,7 @@ def testPow(self):
12491280
self.assertRaises(ValueError, math.pow, -0., -2.)
12501281
self.assertRaises(ValueError, math.pow, -0., -2.3)
12511282
self.assertRaises(ValueError, math.pow, -0., -3.)
1252-
self.assertRaises(ValueError, math.pow, -0., NINF)
1283+
self.assertEqual(math.pow(-0., NINF), INF)
12531284
self.assertTrue(math.isnan(math.pow(-0., NAN)))
12541285

12551286
# pow(NINF, x)
@@ -1508,6 +1539,10 @@ def testSinh(self):
15081539
def testSqrt(self):
15091540
self.assertRaises(TypeError, math.sqrt)
15101541
self.ftest('sqrt(0)', math.sqrt(0), 0)
1542+
self.ftest('sqrt(0)', math.sqrt(0.0), 0.0)
1543+
self.ftest('sqrt(2.5)', math.sqrt(2.5), 1.5811388300841898)
1544+
self.ftest('sqrt(0.25)', math.sqrt(0.25), 0.5)
1545+
self.ftest('sqrt(25.25)', math.sqrt(25.25), 5.024937810560445)
15111546
self.ftest('sqrt(1)', math.sqrt(1), 1)
15121547
self.ftest('sqrt(4)', math.sqrt(4), 2)
15131548
self.assertEqual(math.sqrt(INF), INF)
@@ -1797,16 +1832,22 @@ def test_prod(self):
17971832
self.assertRaises(TypeError, prod)
17981833
self.assertRaises(TypeError, prod, 42)
17991834
self.assertRaises(TypeError, prod, ['a', 'b', 'c'])
1800-
self.assertRaises(TypeError, prod, ['a', 'b', 'c'], '')
1801-
self.assertRaises(TypeError, prod, [b'a', b'c'], b'')
1835+
self.assertRaises(TypeError, prod, ['a', 'b', 'c'], start='')
1836+
self.assertRaises(TypeError, prod, [b'a', b'c'], start=b'')
18021837
values = [bytearray(b'a'), bytearray(b'b')]
1803-
self.assertRaises(TypeError, prod, values, bytearray(b''))
1838+
self.assertRaises(TypeError, prod, values, start=bytearray(b''))
18041839
self.assertRaises(TypeError, prod, [[1], [2], [3]])
18051840
self.assertRaises(TypeError, prod, [{2:3}])
1806-
self.assertRaises(TypeError, prod, [{2:3}]*2, {2:3})
1807-
self.assertRaises(TypeError, prod, [[1], [2], [3]], [])
1841+
self.assertRaises(TypeError, prod, [{2:3}]*2, start={2:3})
1842+
self.assertRaises(TypeError, prod, [[1], [2], [3]], start=[])
1843+
1844+
# Some odd cases
1845+
self.assertEqual(prod([2, 3], start='ab'), 'abababababab')
1846+
self.assertEqual(prod([2, 3], start=[1, 2]), [1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2])
1847+
self.assertEqual(prod([], start={2: 3}), {2:3})
1848+
18081849
with self.assertRaises(TypeError):
1809-
prod([10, 20], [30, 40]) # start is a keyword-only argument
1850+
prod([10, 20], 1) # start is a keyword-only argument
18101851

18111852
self.assertEqual(prod([0, 1, 2, 3]), 0)
18121853
self.assertEqual(prod([1, 0, 2, 3]), 0)
@@ -1866,8 +1907,8 @@ def testPerm(self):
18661907
perm = math.perm
18671908
factorial = math.factorial
18681909
# Test if factorial definition is satisfied
1869-
for n in range(100):
1870-
for k in range(n + 1):
1910+
for n in range(500):
1911+
for k in (range(n + 1) if n < 100 else range(30) if n < 200 else range(10)):
18711912
self.assertEqual(perm(n, k),
18721913
factorial(n) // factorial(n - k))
18731914

@@ -1930,8 +1971,8 @@ def testComb(self):
19301971
comb = math.comb
19311972
factorial = math.factorial
19321973
# Test if factorial definition is satisfied
1933-
for n in range(100):
1934-
for k in range(n + 1):
1974+
for n in range(500):
1975+
for k in (range(n + 1) if n < 100 else range(30) if n < 200 else range(10)):
19351976
self.assertEqual(comb(n, k), factorial(n)
19361977
// (factorial(k) * factorial(n - k)))
19371978

@@ -2219,13 +2260,10 @@ def test_fractions(self):
22192260
self.assertAllNotClose(fraction_examples, rel_tol=1e-9)
22202261

22212262

2222-
def test_main():
2223-
# from doctest import DocFileSuite
2224-
suite = unittest.TestSuite()
2225-
suite.addTest(unittest.makeSuite(MathTests))
2226-
suite.addTest(unittest.makeSuite(IsCloseTests))
2227-
# suite.addTest(DocFileSuite("ieee754.txt"))
2228-
run_unittest(suite)
2263+
def load_tests(loader, tests, pattern):
2264+
from doctest import DocFileSuite
2265+
# tests.addTest(DocFileSuite("ieee754.txt"))
2266+
return tests
22292267

22302268
if __name__ == '__main__':
2231-
test_main()
2269+
unittest.main()

stdlib/src/math.rs

+5
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,11 @@ mod math {
120120
call_math_func!(exp, x, vm)
121121
}
122122

123+
#[pyfunction]
124+
fn exp2(x: ArgIntoFloat, vm: &VirtualMachine) -> PyResult<f64> {
125+
call_math_func!(exp2, x, vm)
126+
}
127+
123128
#[pyfunction]
124129
fn expm1(x: ArgIntoFloat, vm: &VirtualMachine) -> PyResult<f64> {
125130
call_math_func!(exp_m1, x, vm)

0 commit comments

Comments
 (0)