mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
bpo-39479:Add math.lcm() function: Least Common Multiple (#18547)
* Update math.rst * Update math.rst * updated whats new * Update test_math.py * Update mathmodule.c * Update mathmodule.c.h * Update ACKS * 📜🤖 Added by blurb_it. * Update 3.9.rst * Update 2020-02-18-12-37-16.bpo-39479.j3UcCq.rst * Update math.rst * Update 2020-02-18-12-37-16.bpo-39479.j3UcCq.rst * Update test_math.py * Update ACKS * Update mathmodule.c.h * Update mathmodule.c * Update mathmodule.c.h * Update mathmodule.c.h Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
This commit is contained in:
parent
4dee92b0ad
commit
f2ee21d858
7 changed files with 134 additions and 1 deletions
|
@ -136,6 +136,15 @@ Number-theoretic and representation functions
|
||||||
.. versionadded:: 3.5
|
.. versionadded:: 3.5
|
||||||
|
|
||||||
|
|
||||||
|
.. function:: lcm(a, b)
|
||||||
|
|
||||||
|
Return the least common multiple of integers *a* and *b*. The value of
|
||||||
|
``lcm(a, b)`` is the smallest nonnegative integer that is a multiple of
|
||||||
|
both *a* and *b*. If either *a* or *b* is zero then ``lcm(a, b)`` is zero.
|
||||||
|
|
||||||
|
.. versionadded:: 3.9
|
||||||
|
|
||||||
|
|
||||||
.. function:: isclose(a, b, *, rel_tol=1e-09, abs_tol=0.0)
|
.. function:: isclose(a, b, *, rel_tol=1e-09, abs_tol=0.0)
|
||||||
|
|
||||||
Return ``True`` if the values *a* and *b* are close to each other and
|
Return ``True`` if the values *a* and *b* are close to each other and
|
||||||
|
|
|
@ -216,6 +216,9 @@ import attempts.
|
||||||
math
|
math
|
||||||
----
|
----
|
||||||
|
|
||||||
|
Add :func:`math.lcm`: return the least common multiple of *a* and *b*.
|
||||||
|
(Contributed by Ananthakrishnan in :issue:`39479`.)
|
||||||
|
|
||||||
Add :func:`math.nextafter`: return the next floating-point value after *x*
|
Add :func:`math.nextafter`: return the next floating-point value after *x*
|
||||||
towards *y*.
|
towards *y*.
|
||||||
(Contributed by Victor Stinner in :issue:`39288`.)
|
(Contributed by Victor Stinner in :issue:`39288`.)
|
||||||
|
|
|
@ -974,6 +974,41 @@ class MathTests(unittest.TestCase):
|
||||||
with self.assertRaises(TypeError):
|
with self.assertRaises(TypeError):
|
||||||
math.isqrt(value)
|
math.isqrt(value)
|
||||||
|
|
||||||
|
def test_lcm(self):
|
||||||
|
lcm = math.lcm
|
||||||
|
self.assertEqual(lcm(0, 0), 0)
|
||||||
|
self.assertEqual(lcm(1, 0), 0)
|
||||||
|
self.assertEqual(lcm(-1, 0), 0)
|
||||||
|
self.assertEqual(lcm(0, 1), 0)
|
||||||
|
self.assertEqual(lcm(0, -1), 0)
|
||||||
|
self.assertEqual(lcm(7, 1), 7)
|
||||||
|
self.assertEqual(lcm(7, -1), 7)
|
||||||
|
self.assertEqual(lcm(-23, 15), 345)
|
||||||
|
self.assertEqual(lcm(120, 84), 840)
|
||||||
|
self.assertEqual(lcm(84, -120), 840)
|
||||||
|
self.assertEqual(lcm(1216342683557601535506311712,
|
||||||
|
436522681849110124616458784),
|
||||||
|
16592536571065866494401400422922201534178938447014944)
|
||||||
|
x = 43461045657039990237
|
||||||
|
y = 10645022458251153277
|
||||||
|
|
||||||
|
for c in (652560,
|
||||||
|
57655923087165495981):
|
||||||
|
a = x * c
|
||||||
|
b = y * c
|
||||||
|
d = x * y * c
|
||||||
|
self.assertEqual(lcm(a, b), d)
|
||||||
|
self.assertEqual(lcm(b, a), d)
|
||||||
|
self.assertEqual(lcm(-a, b), d)
|
||||||
|
self.assertEqual(lcm(b, -a), d)
|
||||||
|
self.assertEqual(lcm(a, -b), d)
|
||||||
|
self.assertEqual(lcm(-b, a), d)
|
||||||
|
self.assertEqual(lcm(-a, -b), d)
|
||||||
|
self.assertEqual(lcm(-b, -a), d)
|
||||||
|
self.assertEqual(lcm(MyIndexable(120), MyIndexable(84)), 840)
|
||||||
|
self.assertRaises(TypeError, lcm, 120.0, 84)
|
||||||
|
self.assertRaises(TypeError, lcm, 120, 84.0)
|
||||||
|
|
||||||
def testLdexp(self):
|
def testLdexp(self):
|
||||||
self.assertRaises(TypeError, math.ldexp)
|
self.assertRaises(TypeError, math.ldexp)
|
||||||
self.ftest('ldexp(0,1)', math.ldexp(0,1), 0)
|
self.ftest('ldexp(0,1)', math.ldexp(0,1), 0)
|
||||||
|
|
|
@ -45,6 +45,7 @@ Rose Ames
|
||||||
A. Amoroso
|
A. Amoroso
|
||||||
Mark Anacker
|
Mark Anacker
|
||||||
Shashwat Anand
|
Shashwat Anand
|
||||||
|
Ananthakrishnan
|
||||||
Anders Andersen
|
Anders Andersen
|
||||||
Tycho Andersen
|
Tycho Andersen
|
||||||
John Anderson
|
John Anderson
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Add :func:`math.lcm` function: least common multiple.
|
32
Modules/clinic/mathmodule.c.h
generated
32
Modules/clinic/mathmodule.c.h
generated
|
@ -85,6 +85,36 @@ PyDoc_STRVAR(math_factorial__doc__,
|
||||||
#define MATH_FACTORIAL_METHODDEF \
|
#define MATH_FACTORIAL_METHODDEF \
|
||||||
{"factorial", (PyCFunction)math_factorial, METH_O, math_factorial__doc__},
|
{"factorial", (PyCFunction)math_factorial, METH_O, math_factorial__doc__},
|
||||||
|
|
||||||
|
PyDoc_STRVAR(math_lcm__doc__,
|
||||||
|
"lcm($module, x, y, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"least common multiple of x and y");
|
||||||
|
|
||||||
|
#define MATH_LCM_METHODDEF \
|
||||||
|
{"lcm", (PyCFunction)(void(*)(void))math_lcm, METH_FASTCALL, math_lcm__doc__},
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
math_lcm_impl(PyObject *module, PyObject *a, PyObject *b);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
math_lcm(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
|
||||||
|
{
|
||||||
|
PyObject *return_value = NULL;
|
||||||
|
PyObject *a;
|
||||||
|
PyObject *b;
|
||||||
|
|
||||||
|
if (!_PyArg_CheckPositional("lcm", nargs, 2, 2)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
a = args[0];
|
||||||
|
b = args[1];
|
||||||
|
return_value = math_lcm_impl(module, a, b);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(math_trunc__doc__,
|
PyDoc_STRVAR(math_trunc__doc__,
|
||||||
"trunc($module, x, /)\n"
|
"trunc($module, x, /)\n"
|
||||||
"--\n"
|
"--\n"
|
||||||
|
@ -895,4 +925,4 @@ math_ulp(PyObject *module, PyObject *arg)
|
||||||
exit:
|
exit:
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
/*[clinic end generated code: output=9b51d215dbcac060 input=a9049054013a1b77]*/
|
/*[clinic end generated code: output=f8daa185c043a7b7 input=a9049054013a1b77]*/
|
||||||
|
|
|
@ -2017,6 +2017,59 @@ math_factorial(PyObject *module, PyObject *arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
math.lcm
|
||||||
|
x as a: object
|
||||||
|
y as b: object
|
||||||
|
/
|
||||||
|
least common multiple of x and y
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
math_lcm_impl(PyObject *module, PyObject *a, PyObject *b)
|
||||||
|
/*[clinic end generated code: output=6f83fb6d671074ba input=efb3d7b7334b7118]*/
|
||||||
|
{
|
||||||
|
PyObject *g, *m, *f, *ab;
|
||||||
|
|
||||||
|
a = PyNumber_Index(a);
|
||||||
|
if (a == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
b = PyNumber_Index(b);
|
||||||
|
if (b == NULL) {
|
||||||
|
Py_DECREF(a);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (_PyLong_Sign(a) == 0 || _PyLong_Sign(b) == 0) {
|
||||||
|
Py_DECREF(a);
|
||||||
|
Py_DECREF(b);
|
||||||
|
return PyLong_FromLong(0);
|
||||||
|
}
|
||||||
|
g = _PyLong_GCD(a, b);
|
||||||
|
if (g == NULL) {
|
||||||
|
Py_DECREF(a);
|
||||||
|
Py_DECREF(b);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
f = PyNumber_FloorDivide(a, g);
|
||||||
|
Py_DECREF(g);
|
||||||
|
Py_DECREF(a);
|
||||||
|
if (f == NULL) {
|
||||||
|
Py_DECREF(b);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
m = PyNumber_Multiply(f, b);
|
||||||
|
Py_DECREF(f);
|
||||||
|
Py_DECREF(b);
|
||||||
|
if (m == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ab = PyNumber_Absolute(m);
|
||||||
|
Py_DECREF(m);
|
||||||
|
return ab;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
math.trunc
|
math.trunc
|
||||||
|
|
||||||
|
@ -3362,6 +3415,7 @@ static PyMethodDef math_methods[] = {
|
||||||
MATH_ISINF_METHODDEF
|
MATH_ISINF_METHODDEF
|
||||||
MATH_ISNAN_METHODDEF
|
MATH_ISNAN_METHODDEF
|
||||||
MATH_ISQRT_METHODDEF
|
MATH_ISQRT_METHODDEF
|
||||||
|
MATH_LCM_METHODDEF
|
||||||
MATH_LDEXP_METHODDEF
|
MATH_LDEXP_METHODDEF
|
||||||
{"lgamma", math_lgamma, METH_O, math_lgamma_doc},
|
{"lgamma", math_lgamma, METH_O, math_lgamma_doc},
|
||||||
MATH_LOG_METHODDEF
|
MATH_LOG_METHODDEF
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue