(root)/
Python-3.12.0/
Modules/
clinic/
mathmodule.c.h
       1  /*[clinic input]
       2  preserve
       3  [clinic start generated code]*/
       4  
       5  #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
       6  #  include "pycore_gc.h"            // PyGC_Head
       7  #  include "pycore_runtime.h"       // _Py_ID()
       8  #endif
       9  
      10  
      11  PyDoc_STRVAR(math_ceil__doc__,
      12  "ceil($module, x, /)\n"
      13  "--\n"
      14  "\n"
      15  "Return the ceiling of x as an Integral.\n"
      16  "\n"
      17  "This is the smallest integer >= x.");
      18  
      19  #define MATH_CEIL_METHODDEF    \
      20      {"ceil", (PyCFunction)math_ceil, METH_O, math_ceil__doc__},
      21  
      22  PyDoc_STRVAR(math_floor__doc__,
      23  "floor($module, x, /)\n"
      24  "--\n"
      25  "\n"
      26  "Return the floor of x as an Integral.\n"
      27  "\n"
      28  "This is the largest integer <= x.");
      29  
      30  #define MATH_FLOOR_METHODDEF    \
      31      {"floor", (PyCFunction)math_floor, METH_O, math_floor__doc__},
      32  
      33  PyDoc_STRVAR(math_fsum__doc__,
      34  "fsum($module, seq, /)\n"
      35  "--\n"
      36  "\n"
      37  "Return an accurate floating point sum of values in the iterable seq.\n"
      38  "\n"
      39  "Assumes IEEE-754 floating point arithmetic.");
      40  
      41  #define MATH_FSUM_METHODDEF    \
      42      {"fsum", (PyCFunction)math_fsum, METH_O, math_fsum__doc__},
      43  
      44  PyDoc_STRVAR(math_isqrt__doc__,
      45  "isqrt($module, n, /)\n"
      46  "--\n"
      47  "\n"
      48  "Return the integer part of the square root of the input.");
      49  
      50  #define MATH_ISQRT_METHODDEF    \
      51      {"isqrt", (PyCFunction)math_isqrt, METH_O, math_isqrt__doc__},
      52  
      53  PyDoc_STRVAR(math_factorial__doc__,
      54  "factorial($module, n, /)\n"
      55  "--\n"
      56  "\n"
      57  "Find n!.\n"
      58  "\n"
      59  "Raise a ValueError if x is negative or non-integral.");
      60  
      61  #define MATH_FACTORIAL_METHODDEF    \
      62      {"factorial", (PyCFunction)math_factorial, METH_O, math_factorial__doc__},
      63  
      64  PyDoc_STRVAR(math_trunc__doc__,
      65  "trunc($module, x, /)\n"
      66  "--\n"
      67  "\n"
      68  "Truncates the Real x to the nearest Integral toward 0.\n"
      69  "\n"
      70  "Uses the __trunc__ magic method.");
      71  
      72  #define MATH_TRUNC_METHODDEF    \
      73      {"trunc", (PyCFunction)math_trunc, METH_O, math_trunc__doc__},
      74  
      75  PyDoc_STRVAR(math_frexp__doc__,
      76  "frexp($module, x, /)\n"
      77  "--\n"
      78  "\n"
      79  "Return the mantissa and exponent of x, as pair (m, e).\n"
      80  "\n"
      81  "m is a float and e is an int, such that x = m * 2.**e.\n"
      82  "If x is 0, m and e are both 0.  Else 0.5 <= abs(m) < 1.0.");
      83  
      84  #define MATH_FREXP_METHODDEF    \
      85      {"frexp", (PyCFunction)math_frexp, METH_O, math_frexp__doc__},
      86  
      87  static PyObject *
      88  math_frexp_impl(PyObject *module, double x);
      89  
      90  static PyObject *
      91  math_frexp(PyObject *module, PyObject *arg)
      92  {
      93      PyObject *return_value = NULL;
      94      double x;
      95  
      96      if (PyFloat_CheckExact(arg)) {
      97          x = PyFloat_AS_DOUBLE(arg);
      98      }
      99      else
     100      {
     101          x = PyFloat_AsDouble(arg);
     102          if (x == -1.0 && PyErr_Occurred()) {
     103              goto exit;
     104          }
     105      }
     106      return_value = math_frexp_impl(module, x);
     107  
     108  exit:
     109      return return_value;
     110  }
     111  
     112  PyDoc_STRVAR(math_ldexp__doc__,
     113  "ldexp($module, x, i, /)\n"
     114  "--\n"
     115  "\n"
     116  "Return x * (2**i).\n"
     117  "\n"
     118  "This is essentially the inverse of frexp().");
     119  
     120  #define MATH_LDEXP_METHODDEF    \
     121      {"ldexp", _PyCFunction_CAST(math_ldexp), METH_FASTCALL, math_ldexp__doc__},
     122  
     123  static PyObject *
     124  math_ldexp_impl(PyObject *module, double x, PyObject *i);
     125  
     126  static PyObject *
     127  math_ldexp(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
     128  {
     129      PyObject *return_value = NULL;
     130      double x;
     131      PyObject *i;
     132  
     133      if (!_PyArg_CheckPositional("ldexp", nargs, 2, 2)) {
     134          goto exit;
     135      }
     136      if (PyFloat_CheckExact(args[0])) {
     137          x = PyFloat_AS_DOUBLE(args[0]);
     138      }
     139      else
     140      {
     141          x = PyFloat_AsDouble(args[0]);
     142          if (x == -1.0 && PyErr_Occurred()) {
     143              goto exit;
     144          }
     145      }
     146      i = args[1];
     147      return_value = math_ldexp_impl(module, x, i);
     148  
     149  exit:
     150      return return_value;
     151  }
     152  
     153  PyDoc_STRVAR(math_modf__doc__,
     154  "modf($module, x, /)\n"
     155  "--\n"
     156  "\n"
     157  "Return the fractional and integer parts of x.\n"
     158  "\n"
     159  "Both results carry the sign of x and are floats.");
     160  
     161  #define MATH_MODF_METHODDEF    \
     162      {"modf", (PyCFunction)math_modf, METH_O, math_modf__doc__},
     163  
     164  static PyObject *
     165  math_modf_impl(PyObject *module, double x);
     166  
     167  static PyObject *
     168  math_modf(PyObject *module, PyObject *arg)
     169  {
     170      PyObject *return_value = NULL;
     171      double x;
     172  
     173      if (PyFloat_CheckExact(arg)) {
     174          x = PyFloat_AS_DOUBLE(arg);
     175      }
     176      else
     177      {
     178          x = PyFloat_AsDouble(arg);
     179          if (x == -1.0 && PyErr_Occurred()) {
     180              goto exit;
     181          }
     182      }
     183      return_value = math_modf_impl(module, x);
     184  
     185  exit:
     186      return return_value;
     187  }
     188  
     189  PyDoc_STRVAR(math_log2__doc__,
     190  "log2($module, x, /)\n"
     191  "--\n"
     192  "\n"
     193  "Return the base 2 logarithm of x.");
     194  
     195  #define MATH_LOG2_METHODDEF    \
     196      {"log2", (PyCFunction)math_log2, METH_O, math_log2__doc__},
     197  
     198  PyDoc_STRVAR(math_log10__doc__,
     199  "log10($module, x, /)\n"
     200  "--\n"
     201  "\n"
     202  "Return the base 10 logarithm of x.");
     203  
     204  #define MATH_LOG10_METHODDEF    \
     205      {"log10", (PyCFunction)math_log10, METH_O, math_log10__doc__},
     206  
     207  PyDoc_STRVAR(math_fmod__doc__,
     208  "fmod($module, x, y, /)\n"
     209  "--\n"
     210  "\n"
     211  "Return fmod(x, y), according to platform C.\n"
     212  "\n"
     213  "x % y may differ.");
     214  
     215  #define MATH_FMOD_METHODDEF    \
     216      {"fmod", _PyCFunction_CAST(math_fmod), METH_FASTCALL, math_fmod__doc__},
     217  
     218  static PyObject *
     219  math_fmod_impl(PyObject *module, double x, double y);
     220  
     221  static PyObject *
     222  math_fmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
     223  {
     224      PyObject *return_value = NULL;
     225      double x;
     226      double y;
     227  
     228      if (!_PyArg_CheckPositional("fmod", nargs, 2, 2)) {
     229          goto exit;
     230      }
     231      if (PyFloat_CheckExact(args[0])) {
     232          x = PyFloat_AS_DOUBLE(args[0]);
     233      }
     234      else
     235      {
     236          x = PyFloat_AsDouble(args[0]);
     237          if (x == -1.0 && PyErr_Occurred()) {
     238              goto exit;
     239          }
     240      }
     241      if (PyFloat_CheckExact(args[1])) {
     242          y = PyFloat_AS_DOUBLE(args[1]);
     243      }
     244      else
     245      {
     246          y = PyFloat_AsDouble(args[1]);
     247          if (y == -1.0 && PyErr_Occurred()) {
     248              goto exit;
     249          }
     250      }
     251      return_value = math_fmod_impl(module, x, y);
     252  
     253  exit:
     254      return return_value;
     255  }
     256  
     257  PyDoc_STRVAR(math_dist__doc__,
     258  "dist($module, p, q, /)\n"
     259  "--\n"
     260  "\n"
     261  "Return the Euclidean distance between two points p and q.\n"
     262  "\n"
     263  "The points should be specified as sequences (or iterables) of\n"
     264  "coordinates.  Both inputs must have the same dimension.\n"
     265  "\n"
     266  "Roughly equivalent to:\n"
     267  "    sqrt(sum((px - qx) ** 2.0 for px, qx in zip(p, q)))");
     268  
     269  #define MATH_DIST_METHODDEF    \
     270      {"dist", _PyCFunction_CAST(math_dist), METH_FASTCALL, math_dist__doc__},
     271  
     272  static PyObject *
     273  math_dist_impl(PyObject *module, PyObject *p, PyObject *q);
     274  
     275  static PyObject *
     276  math_dist(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
     277  {
     278      PyObject *return_value = NULL;
     279      PyObject *p;
     280      PyObject *q;
     281  
     282      if (!_PyArg_CheckPositional("dist", nargs, 2, 2)) {
     283          goto exit;
     284      }
     285      p = args[0];
     286      q = args[1];
     287      return_value = math_dist_impl(module, p, q);
     288  
     289  exit:
     290      return return_value;
     291  }
     292  
     293  PyDoc_STRVAR(math_sumprod__doc__,
     294  "sumprod($module, p, q, /)\n"
     295  "--\n"
     296  "\n"
     297  "Return the sum of products of values from two iterables p and q.\n"
     298  "\n"
     299  "Roughly equivalent to:\n"
     300  "\n"
     301  "    sum(itertools.starmap(operator.mul, zip(p, q, strict=True)))\n"
     302  "\n"
     303  "For float and mixed int/float inputs, the intermediate products\n"
     304  "and sums are computed with extended precision.");
     305  
     306  #define MATH_SUMPROD_METHODDEF    \
     307      {"sumprod", _PyCFunction_CAST(math_sumprod), METH_FASTCALL, math_sumprod__doc__},
     308  
     309  static PyObject *
     310  math_sumprod_impl(PyObject *module, PyObject *p, PyObject *q);
     311  
     312  static PyObject *
     313  math_sumprod(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
     314  {
     315      PyObject *return_value = NULL;
     316      PyObject *p;
     317      PyObject *q;
     318  
     319      if (!_PyArg_CheckPositional("sumprod", nargs, 2, 2)) {
     320          goto exit;
     321      }
     322      p = args[0];
     323      q = args[1];
     324      return_value = math_sumprod_impl(module, p, q);
     325  
     326  exit:
     327      return return_value;
     328  }
     329  
     330  PyDoc_STRVAR(math_pow__doc__,
     331  "pow($module, x, y, /)\n"
     332  "--\n"
     333  "\n"
     334  "Return x**y (x to the power of y).");
     335  
     336  #define MATH_POW_METHODDEF    \
     337      {"pow", _PyCFunction_CAST(math_pow), METH_FASTCALL, math_pow__doc__},
     338  
     339  static PyObject *
     340  math_pow_impl(PyObject *module, double x, double y);
     341  
     342  static PyObject *
     343  math_pow(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
     344  {
     345      PyObject *return_value = NULL;
     346      double x;
     347      double y;
     348  
     349      if (!_PyArg_CheckPositional("pow", nargs, 2, 2)) {
     350          goto exit;
     351      }
     352      if (PyFloat_CheckExact(args[0])) {
     353          x = PyFloat_AS_DOUBLE(args[0]);
     354      }
     355      else
     356      {
     357          x = PyFloat_AsDouble(args[0]);
     358          if (x == -1.0 && PyErr_Occurred()) {
     359              goto exit;
     360          }
     361      }
     362      if (PyFloat_CheckExact(args[1])) {
     363          y = PyFloat_AS_DOUBLE(args[1]);
     364      }
     365      else
     366      {
     367          y = PyFloat_AsDouble(args[1]);
     368          if (y == -1.0 && PyErr_Occurred()) {
     369              goto exit;
     370          }
     371      }
     372      return_value = math_pow_impl(module, x, y);
     373  
     374  exit:
     375      return return_value;
     376  }
     377  
     378  PyDoc_STRVAR(math_degrees__doc__,
     379  "degrees($module, x, /)\n"
     380  "--\n"
     381  "\n"
     382  "Convert angle x from radians to degrees.");
     383  
     384  #define MATH_DEGREES_METHODDEF    \
     385      {"degrees", (PyCFunction)math_degrees, METH_O, math_degrees__doc__},
     386  
     387  static PyObject *
     388  math_degrees_impl(PyObject *module, double x);
     389  
     390  static PyObject *
     391  math_degrees(PyObject *module, PyObject *arg)
     392  {
     393      PyObject *return_value = NULL;
     394      double x;
     395  
     396      if (PyFloat_CheckExact(arg)) {
     397          x = PyFloat_AS_DOUBLE(arg);
     398      }
     399      else
     400      {
     401          x = PyFloat_AsDouble(arg);
     402          if (x == -1.0 && PyErr_Occurred()) {
     403              goto exit;
     404          }
     405      }
     406      return_value = math_degrees_impl(module, x);
     407  
     408  exit:
     409      return return_value;
     410  }
     411  
     412  PyDoc_STRVAR(math_radians__doc__,
     413  "radians($module, x, /)\n"
     414  "--\n"
     415  "\n"
     416  "Convert angle x from degrees to radians.");
     417  
     418  #define MATH_RADIANS_METHODDEF    \
     419      {"radians", (PyCFunction)math_radians, METH_O, math_radians__doc__},
     420  
     421  static PyObject *
     422  math_radians_impl(PyObject *module, double x);
     423  
     424  static PyObject *
     425  math_radians(PyObject *module, PyObject *arg)
     426  {
     427      PyObject *return_value = NULL;
     428      double x;
     429  
     430      if (PyFloat_CheckExact(arg)) {
     431          x = PyFloat_AS_DOUBLE(arg);
     432      }
     433      else
     434      {
     435          x = PyFloat_AsDouble(arg);
     436          if (x == -1.0 && PyErr_Occurred()) {
     437              goto exit;
     438          }
     439      }
     440      return_value = math_radians_impl(module, x);
     441  
     442  exit:
     443      return return_value;
     444  }
     445  
     446  PyDoc_STRVAR(math_isfinite__doc__,
     447  "isfinite($module, x, /)\n"
     448  "--\n"
     449  "\n"
     450  "Return True if x is neither an infinity nor a NaN, and False otherwise.");
     451  
     452  #define MATH_ISFINITE_METHODDEF    \
     453      {"isfinite", (PyCFunction)math_isfinite, METH_O, math_isfinite__doc__},
     454  
     455  static PyObject *
     456  math_isfinite_impl(PyObject *module, double x);
     457  
     458  static PyObject *
     459  math_isfinite(PyObject *module, PyObject *arg)
     460  {
     461      PyObject *return_value = NULL;
     462      double x;
     463  
     464      if (PyFloat_CheckExact(arg)) {
     465          x = PyFloat_AS_DOUBLE(arg);
     466      }
     467      else
     468      {
     469          x = PyFloat_AsDouble(arg);
     470          if (x == -1.0 && PyErr_Occurred()) {
     471              goto exit;
     472          }
     473      }
     474      return_value = math_isfinite_impl(module, x);
     475  
     476  exit:
     477      return return_value;
     478  }
     479  
     480  PyDoc_STRVAR(math_isnan__doc__,
     481  "isnan($module, x, /)\n"
     482  "--\n"
     483  "\n"
     484  "Return True if x is a NaN (not a number), and False otherwise.");
     485  
     486  #define MATH_ISNAN_METHODDEF    \
     487      {"isnan", (PyCFunction)math_isnan, METH_O, math_isnan__doc__},
     488  
     489  static PyObject *
     490  math_isnan_impl(PyObject *module, double x);
     491  
     492  static PyObject *
     493  math_isnan(PyObject *module, PyObject *arg)
     494  {
     495      PyObject *return_value = NULL;
     496      double x;
     497  
     498      if (PyFloat_CheckExact(arg)) {
     499          x = PyFloat_AS_DOUBLE(arg);
     500      }
     501      else
     502      {
     503          x = PyFloat_AsDouble(arg);
     504          if (x == -1.0 && PyErr_Occurred()) {
     505              goto exit;
     506          }
     507      }
     508      return_value = math_isnan_impl(module, x);
     509  
     510  exit:
     511      return return_value;
     512  }
     513  
     514  PyDoc_STRVAR(math_isinf__doc__,
     515  "isinf($module, x, /)\n"
     516  "--\n"
     517  "\n"
     518  "Return True if x is a positive or negative infinity, and False otherwise.");
     519  
     520  #define MATH_ISINF_METHODDEF    \
     521      {"isinf", (PyCFunction)math_isinf, METH_O, math_isinf__doc__},
     522  
     523  static PyObject *
     524  math_isinf_impl(PyObject *module, double x);
     525  
     526  static PyObject *
     527  math_isinf(PyObject *module, PyObject *arg)
     528  {
     529      PyObject *return_value = NULL;
     530      double x;
     531  
     532      if (PyFloat_CheckExact(arg)) {
     533          x = PyFloat_AS_DOUBLE(arg);
     534      }
     535      else
     536      {
     537          x = PyFloat_AsDouble(arg);
     538          if (x == -1.0 && PyErr_Occurred()) {
     539              goto exit;
     540          }
     541      }
     542      return_value = math_isinf_impl(module, x);
     543  
     544  exit:
     545      return return_value;
     546  }
     547  
     548  PyDoc_STRVAR(math_isclose__doc__,
     549  "isclose($module, /, a, b, *, rel_tol=1e-09, abs_tol=0.0)\n"
     550  "--\n"
     551  "\n"
     552  "Determine whether two floating point numbers are close in value.\n"
     553  "\n"
     554  "  rel_tol\n"
     555  "    maximum difference for being considered \"close\", relative to the\n"
     556  "    magnitude of the input values\n"
     557  "  abs_tol\n"
     558  "    maximum difference for being considered \"close\", regardless of the\n"
     559  "    magnitude of the input values\n"
     560  "\n"
     561  "Return True if a is close in value to b, and False otherwise.\n"
     562  "\n"
     563  "For the values to be considered close, the difference between them\n"
     564  "must be smaller than at least one of the tolerances.\n"
     565  "\n"
     566  "-inf, inf and NaN behave similarly to the IEEE 754 Standard.  That\n"
     567  "is, NaN is not close to anything, even itself.  inf and -inf are\n"
     568  "only close to themselves.");
     569  
     570  #define MATH_ISCLOSE_METHODDEF    \
     571      {"isclose", _PyCFunction_CAST(math_isclose), METH_FASTCALL|METH_KEYWORDS, math_isclose__doc__},
     572  
     573  static int
     574  math_isclose_impl(PyObject *module, double a, double b, double rel_tol,
     575                    double abs_tol);
     576  
     577  static PyObject *
     578  math_isclose(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
     579  {
     580      PyObject *return_value = NULL;
     581      #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
     582  
     583      #define NUM_KEYWORDS 4
     584      static struct {
     585          PyGC_Head _this_is_not_used;
     586          PyObject_VAR_HEAD
     587          PyObject *ob_item[NUM_KEYWORDS];
     588      } _kwtuple = {
     589          .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
     590          .ob_item = { &_Py_ID(a), &_Py_ID(b), &_Py_ID(rel_tol), &_Py_ID(abs_tol), },
     591      };
     592      #undef NUM_KEYWORDS
     593      #define KWTUPLE (&_kwtuple.ob_base.ob_base)
     594  
     595      #else  // !Py_BUILD_CORE
     596      #  define KWTUPLE NULL
     597      #endif  // !Py_BUILD_CORE
     598  
     599      static const char * const _keywords[] = {"a", "b", "rel_tol", "abs_tol", NULL};
     600      static _PyArg_Parser _parser = {
     601          .keywords = _keywords,
     602          .fname = "isclose",
     603          .kwtuple = KWTUPLE,
     604      };
     605      #undef KWTUPLE
     606      PyObject *argsbuf[4];
     607      Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2;
     608      double a;
     609      double b;
     610      double rel_tol = 1e-09;
     611      double abs_tol = 0.0;
     612      int _return_value;
     613  
     614      args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf);
     615      if (!args) {
     616          goto exit;
     617      }
     618      if (PyFloat_CheckExact(args[0])) {
     619          a = PyFloat_AS_DOUBLE(args[0]);
     620      }
     621      else
     622      {
     623          a = PyFloat_AsDouble(args[0]);
     624          if (a == -1.0 && PyErr_Occurred()) {
     625              goto exit;
     626          }
     627      }
     628      if (PyFloat_CheckExact(args[1])) {
     629          b = PyFloat_AS_DOUBLE(args[1]);
     630      }
     631      else
     632      {
     633          b = PyFloat_AsDouble(args[1]);
     634          if (b == -1.0 && PyErr_Occurred()) {
     635              goto exit;
     636          }
     637      }
     638      if (!noptargs) {
     639          goto skip_optional_kwonly;
     640      }
     641      if (args[2]) {
     642          if (PyFloat_CheckExact(args[2])) {
     643              rel_tol = PyFloat_AS_DOUBLE(args[2]);
     644          }
     645          else
     646          {
     647              rel_tol = PyFloat_AsDouble(args[2]);
     648              if (rel_tol == -1.0 && PyErr_Occurred()) {
     649                  goto exit;
     650              }
     651          }
     652          if (!--noptargs) {
     653              goto skip_optional_kwonly;
     654          }
     655      }
     656      if (PyFloat_CheckExact(args[3])) {
     657          abs_tol = PyFloat_AS_DOUBLE(args[3]);
     658      }
     659      else
     660      {
     661          abs_tol = PyFloat_AsDouble(args[3]);
     662          if (abs_tol == -1.0 && PyErr_Occurred()) {
     663              goto exit;
     664          }
     665      }
     666  skip_optional_kwonly:
     667      _return_value = math_isclose_impl(module, a, b, rel_tol, abs_tol);
     668      if ((_return_value == -1) && PyErr_Occurred()) {
     669          goto exit;
     670      }
     671      return_value = PyBool_FromLong((long)_return_value);
     672  
     673  exit:
     674      return return_value;
     675  }
     676  
     677  PyDoc_STRVAR(math_prod__doc__,
     678  "prod($module, iterable, /, *, start=1)\n"
     679  "--\n"
     680  "\n"
     681  "Calculate the product of all the elements in the input iterable.\n"
     682  "\n"
     683  "The default start value for the product is 1.\n"
     684  "\n"
     685  "When the iterable is empty, return the start value.  This function is\n"
     686  "intended specifically for use with numeric values and may reject\n"
     687  "non-numeric types.");
     688  
     689  #define MATH_PROD_METHODDEF    \
     690      {"prod", _PyCFunction_CAST(math_prod), METH_FASTCALL|METH_KEYWORDS, math_prod__doc__},
     691  
     692  static PyObject *
     693  math_prod_impl(PyObject *module, PyObject *iterable, PyObject *start);
     694  
     695  static PyObject *
     696  math_prod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
     697  {
     698      PyObject *return_value = NULL;
     699      #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
     700  
     701      #define NUM_KEYWORDS 1
     702      static struct {
     703          PyGC_Head _this_is_not_used;
     704          PyObject_VAR_HEAD
     705          PyObject *ob_item[NUM_KEYWORDS];
     706      } _kwtuple = {
     707          .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
     708          .ob_item = { &_Py_ID(start), },
     709      };
     710      #undef NUM_KEYWORDS
     711      #define KWTUPLE (&_kwtuple.ob_base.ob_base)
     712  
     713      #else  // !Py_BUILD_CORE
     714      #  define KWTUPLE NULL
     715      #endif  // !Py_BUILD_CORE
     716  
     717      static const char * const _keywords[] = {"", "start", NULL};
     718      static _PyArg_Parser _parser = {
     719          .keywords = _keywords,
     720          .fname = "prod",
     721          .kwtuple = KWTUPLE,
     722      };
     723      #undef KWTUPLE
     724      PyObject *argsbuf[2];
     725      Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
     726      PyObject *iterable;
     727      PyObject *start = NULL;
     728  
     729      args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
     730      if (!args) {
     731          goto exit;
     732      }
     733      iterable = args[0];
     734      if (!noptargs) {
     735          goto skip_optional_kwonly;
     736      }
     737      start = args[1];
     738  skip_optional_kwonly:
     739      return_value = math_prod_impl(module, iterable, start);
     740  
     741  exit:
     742      return return_value;
     743  }
     744  
     745  PyDoc_STRVAR(math_perm__doc__,
     746  "perm($module, n, k=None, /)\n"
     747  "--\n"
     748  "\n"
     749  "Number of ways to choose k items from n items without repetition and with order.\n"
     750  "\n"
     751  "Evaluates to n! / (n - k)! when k <= n and evaluates\n"
     752  "to zero when k > n.\n"
     753  "\n"
     754  "If k is not specified or is None, then k defaults to n\n"
     755  "and the function returns n!.\n"
     756  "\n"
     757  "Raises TypeError if either of the arguments are not integers.\n"
     758  "Raises ValueError if either of the arguments are negative.");
     759  
     760  #define MATH_PERM_METHODDEF    \
     761      {"perm", _PyCFunction_CAST(math_perm), METH_FASTCALL, math_perm__doc__},
     762  
     763  static PyObject *
     764  math_perm_impl(PyObject *module, PyObject *n, PyObject *k);
     765  
     766  static PyObject *
     767  math_perm(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
     768  {
     769      PyObject *return_value = NULL;
     770      PyObject *n;
     771      PyObject *k = Py_None;
     772  
     773      if (!_PyArg_CheckPositional("perm", nargs, 1, 2)) {
     774          goto exit;
     775      }
     776      n = args[0];
     777      if (nargs < 2) {
     778          goto skip_optional;
     779      }
     780      k = args[1];
     781  skip_optional:
     782      return_value = math_perm_impl(module, n, k);
     783  
     784  exit:
     785      return return_value;
     786  }
     787  
     788  PyDoc_STRVAR(math_comb__doc__,
     789  "comb($module, n, k, /)\n"
     790  "--\n"
     791  "\n"
     792  "Number of ways to choose k items from n items without repetition and without order.\n"
     793  "\n"
     794  "Evaluates to n! / (k! * (n - k)!) when k <= n and evaluates\n"
     795  "to zero when k > n.\n"
     796  "\n"
     797  "Also called the binomial coefficient because it is equivalent\n"
     798  "to the coefficient of k-th term in polynomial expansion of the\n"
     799  "expression (1 + x)**n.\n"
     800  "\n"
     801  "Raises TypeError if either of the arguments are not integers.\n"
     802  "Raises ValueError if either of the arguments are negative.");
     803  
     804  #define MATH_COMB_METHODDEF    \
     805      {"comb", _PyCFunction_CAST(math_comb), METH_FASTCALL, math_comb__doc__},
     806  
     807  static PyObject *
     808  math_comb_impl(PyObject *module, PyObject *n, PyObject *k);
     809  
     810  static PyObject *
     811  math_comb(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
     812  {
     813      PyObject *return_value = NULL;
     814      PyObject *n;
     815      PyObject *k;
     816  
     817      if (!_PyArg_CheckPositional("comb", nargs, 2, 2)) {
     818          goto exit;
     819      }
     820      n = args[0];
     821      k = args[1];
     822      return_value = math_comb_impl(module, n, k);
     823  
     824  exit:
     825      return return_value;
     826  }
     827  
     828  PyDoc_STRVAR(math_nextafter__doc__,
     829  "nextafter($module, x, y, /, *, steps=None)\n"
     830  "--\n"
     831  "\n"
     832  "Return the floating-point value the given number of steps after x towards y.\n"
     833  "\n"
     834  "If steps is not specified or is None, it defaults to 1.\n"
     835  "\n"
     836  "Raises a TypeError, if x or y is not a double, or if steps is not an integer.\n"
     837  "Raises ValueError if steps is negative.");
     838  
     839  #define MATH_NEXTAFTER_METHODDEF    \
     840      {"nextafter", _PyCFunction_CAST(math_nextafter), METH_FASTCALL|METH_KEYWORDS, math_nextafter__doc__},
     841  
     842  static PyObject *
     843  math_nextafter_impl(PyObject *module, double x, double y, PyObject *steps);
     844  
     845  static PyObject *
     846  math_nextafter(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
     847  {
     848      PyObject *return_value = NULL;
     849      #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
     850  
     851      #define NUM_KEYWORDS 1
     852      static struct {
     853          PyGC_Head _this_is_not_used;
     854          PyObject_VAR_HEAD
     855          PyObject *ob_item[NUM_KEYWORDS];
     856      } _kwtuple = {
     857          .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
     858          .ob_item = { &_Py_ID(steps), },
     859      };
     860      #undef NUM_KEYWORDS
     861      #define KWTUPLE (&_kwtuple.ob_base.ob_base)
     862  
     863      #else  // !Py_BUILD_CORE
     864      #  define KWTUPLE NULL
     865      #endif  // !Py_BUILD_CORE
     866  
     867      static const char * const _keywords[] = {"", "", "steps", NULL};
     868      static _PyArg_Parser _parser = {
     869          .keywords = _keywords,
     870          .fname = "nextafter",
     871          .kwtuple = KWTUPLE,
     872      };
     873      #undef KWTUPLE
     874      PyObject *argsbuf[3];
     875      Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2;
     876      double x;
     877      double y;
     878      PyObject *steps = Py_None;
     879  
     880      args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf);
     881      if (!args) {
     882          goto exit;
     883      }
     884      if (PyFloat_CheckExact(args[0])) {
     885          x = PyFloat_AS_DOUBLE(args[0]);
     886      }
     887      else
     888      {
     889          x = PyFloat_AsDouble(args[0]);
     890          if (x == -1.0 && PyErr_Occurred()) {
     891              goto exit;
     892          }
     893      }
     894      if (PyFloat_CheckExact(args[1])) {
     895          y = PyFloat_AS_DOUBLE(args[1]);
     896      }
     897      else
     898      {
     899          y = PyFloat_AsDouble(args[1]);
     900          if (y == -1.0 && PyErr_Occurred()) {
     901              goto exit;
     902          }
     903      }
     904      if (!noptargs) {
     905          goto skip_optional_kwonly;
     906      }
     907      steps = args[2];
     908  skip_optional_kwonly:
     909      return_value = math_nextafter_impl(module, x, y, steps);
     910  
     911  exit:
     912      return return_value;
     913  }
     914  
     915  PyDoc_STRVAR(math_ulp__doc__,
     916  "ulp($module, x, /)\n"
     917  "--\n"
     918  "\n"
     919  "Return the value of the least significant bit of the float x.");
     920  
     921  #define MATH_ULP_METHODDEF    \
     922      {"ulp", (PyCFunction)math_ulp, METH_O, math_ulp__doc__},
     923  
     924  static double
     925  math_ulp_impl(PyObject *module, double x);
     926  
     927  static PyObject *
     928  math_ulp(PyObject *module, PyObject *arg)
     929  {
     930      PyObject *return_value = NULL;
     931      double x;
     932      double _return_value;
     933  
     934      if (PyFloat_CheckExact(arg)) {
     935          x = PyFloat_AS_DOUBLE(arg);
     936      }
     937      else
     938      {
     939          x = PyFloat_AsDouble(arg);
     940          if (x == -1.0 && PyErr_Occurred()) {
     941              goto exit;
     942          }
     943      }
     944      _return_value = math_ulp_impl(module, x);
     945      if ((_return_value == -1.0) && PyErr_Occurred()) {
     946          goto exit;
     947      }
     948      return_value = PyFloat_FromDouble(_return_value);
     949  
     950  exit:
     951      return return_value;
     952  }
     953  /*[clinic end generated code: output=91a0357265a2a553 input=a9049054013a1b77]*/