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