@@ -1834,6 +1834,52 @@ MAKE_MPZ_UI_FUN(fac)
18341834MAKE_MPZ_UI_FUN (fac2 )
18351835MAKE_MPZ_UI_FUN (fib )
18361836
1837+ static PyObject *
1838+ gmp_comb (PyObject * self , PyObject * const * args , Py_ssize_t nargs )
1839+ {
1840+ if (nargs != 2 ) {
1841+ PyErr_SetString (PyExc_TypeError , "two arguments required" );
1842+ return NULL ;
1843+ }
1844+
1845+ MPZ_Object * x , * y , * res = MPZ_new (0 );
1846+
1847+ if (!res ) {
1848+ return NULL ; /* LCOV_EXCL_LINE */
1849+ }
1850+ CHECK_OP_INT (x , args [0 ]);
1851+ CHECK_OP_INT (y , args [1 ]);
1852+ if (zz_isneg (& x -> z ) || zz_isneg (& y -> z )) {
1853+ PyErr_SetString (PyExc_ValueError ,
1854+ "comb() not defined for negative values" );
1855+ goto err ;
1856+ }
1857+
1858+ int64_t n , k ;
1859+
1860+ if ((zz_to_i64 (& x -> z , & n ) || n > ULONG_MAX )
1861+ || (zz_to_i64 (& y -> z , & k ) || k > ULONG_MAX ))
1862+ {
1863+ PyErr_Format (PyExc_OverflowError ,
1864+ "comb() arguments should not exceed %ld" ,
1865+ ULONG_MAX );
1866+ goto err ;
1867+ }
1868+ Py_XDECREF (x );
1869+ Py_XDECREF (y );
1870+ if (zz_bin ((uint64_t )n , (uint64_t )k , & res -> z )) {
1871+ /* LCOV_EXCL_START */
1872+ PyErr_NoMemory ();
1873+ goto err ;
1874+ /* LCOV_EXCL_STOP */
1875+ }
1876+ return (PyObject * )res ;
1877+ err :
1878+ end :
1879+ Py_DECREF (res );
1880+ return NULL ;
1881+ }
1882+
18371883static zz_rnd
18381884get_round_mode (PyObject * rndstr )
18391885{
@@ -2040,6 +2086,10 @@ static PyMethodDef gmp_functions[] = {
20402086 {"fib" , gmp_fib , METH_O ,
20412087 ("fib($module, n, /)\n--\n\n"
20422088 "Return the n-th Fibonacci number." )},
2089+ {"comb" , (PyCFunction )gmp_comb , METH_FASTCALL ,
2090+ ("comb($module, n, k, /)\n--\n\nNumber of ways to choose k"
2091+ " items from n items without repetition and order.\n\n"
2092+ "Also called the binomial coefficient." )},
20432093 {"_mpmath_normalize" , (PyCFunction )gmp__mpmath_normalize , METH_FASTCALL ,
20442094 NULL },
20452095 {"_mpmath_create" , (PyCFunction )gmp__mpmath_create , METH_FASTCALL , NULL },
@@ -2131,7 +2181,8 @@ gmp_exec(PyObject *m)
21312181 const char * str = ("import numbers, importlib.metadata as imp\n"
21322182 "numbers.Integral.register(gmp.mpz)\n"
21332183 "gmp.fac = gmp.factorial\n"
2134- "gmp.__all__ = ['factorial', 'gcd', 'isqrt', 'mpz']\n"
2184+ "gmp.__all__ = ['comb', 'factorial', 'gcd', 'isqrt',\n"
2185+ " 'mpz']\n"
21352186 "gmp.__version__ = imp.version('python-gmp')\n" );
21362187
21372188 PyObject * res = PyRun_String (str , Py_file_input , ns , ns );
0 commit comments