gmpy2_mpz_misc.c
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 2 * gmpy2_mpz_misc.c * 3 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 4 * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * 5 * libraries. * 6 * * 7 * Copyright 2000 - 2009 Alex Martelli * 8 * * 9 * Copyright 2008 - 2021 Case Van Horsen * 10 * * 11 * This file is part of GMPY2. * 12 * * 13 * GMPY2 is free software: you can redistribute it and/or modify it under * 14 * the terms of the GNU Lesser General Public License as published by the * 15 * Free Software Foundation, either version 3 of the License, or (at your * 16 * option) any later version. * 17 * * 18 * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * 19 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * 20 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * 21 * License for more details. * 22 * * 23 * You should have received a copy of the GNU Lesser General Public * 24 * License along with GMPY2; if not, see <http://www.gnu.org/licenses/> * 25 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 26 27 /* return number-of-digits for an mpz in requested base, default 10 */ 28 PyDoc_STRVAR(GMPy_doc_mpz_method_num_digits, 29 "x.num_digits([base]) -> int\n\n" 30 "Return length of string representing the absolute value of x in\n" 31 "the given base. Values for base can range between 2 and 62. The\n" 32 "value returned may be 1 too large."); 33 34 PyDoc_STRVAR(GMPy_doc_mpz_function_num_digits, 35 "num_digits(x[, base]) -> int\n\n" 36 "Return length of string representing the absolute value of x in\n" 37 "the given base. Values for base can range between 2 and 62. The\n" 38 "value returned may be 1 too large."); 39 40 static PyObject * 41 GMPy_MPZ_Method_NumDigits(PyObject *self, PyObject *args) 42 { 43 long base = 10; 44 PyObject *result; 45 46 if (PyTuple_GET_SIZE(args) == 1) { 47 base = PyIntOrLong_AsLong(PyTuple_GET_ITEM(args, 0)); 48 if (base == -1 && PyErr_Occurred()) { 49 return NULL; 50 } 51 } 52 53 if ((base < 2) || (base > 62)) { 54 VALUE_ERROR("base must be in the interval [2, 62]"); 55 return NULL; 56 } 57 58 result = PyIntOrLong_FromSize_t(mpz_sizeinbase(MPZ(self), (int)base)); 59 return result; 60 } 61 62 static PyObject * 63 GMPy_MPZ_Function_NumDigits(PyObject *self, PyObject *args) 64 { 65 long base = 10; 66 Py_ssize_t argc; 67 MPZ_Object *temp; 68 PyObject *result; 69 70 argc = PyTuple_GET_SIZE(args); 71 if (argc == 0 || argc > 2) { 72 TYPE_ERROR("num_digits() requires 'mpz',['int'] arguments"); 73 return NULL; 74 } 75 76 if (argc == 2) { 77 base = PyIntOrLong_AsLong(PyTuple_GET_ITEM(args, 1)); 78 if (base == -1 && PyErr_Occurred()) { 79 return NULL; 80 } 81 } 82 83 if ((base < 2) || (base > 62)) { 84 VALUE_ERROR("base must be in the interval [2, 62]"); 85 return NULL; 86 } 87 88 if (!(temp = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) { 89 return NULL; 90 } 91 92 result = PyIntOrLong_FromSize_t(mpz_sizeinbase(temp->z, (int)base)); 93 Py_DECREF((PyObject*)temp); 94 return result; 95 } 96 97 PyDoc_STRVAR(GMPy_doc_mpz_function_iroot, 98 "iroot(x,n) -> (number, boolean)\n\n" 99 "Return the integer n-th root of x and boolean value that is True\n" 100 "iff the root is exact. x >= 0. n > 0."); 101 102 static PyObject * 103 GMPy_MPZ_Function_Iroot(PyObject *self, PyObject *args) 104 { 105 unsigned long n; 106 int exact; 107 MPZ_Object *root = NULL, *tempx = NULL; 108 PyObject *result = NULL; 109 110 if ((PyTuple_GET_SIZE(args) != 2) || 111 ((!IS_INTEGER(PyTuple_GET_ITEM(args, 0))) || 112 (!IS_INTEGER(PyTuple_GET_ITEM(args, 1))))) { 113 114 TYPE_ERROR("iroot() requires 'int','int' arguments"); 115 return NULL; 116 } 117 118 n = c_ulong_From_Integer(PyTuple_GET_ITEM(args, 1)); 119 if ((n == 0) || ((n == (unsigned long)(-1)) && PyErr_Occurred())) { 120 VALUE_ERROR("n must be > 0"); 121 return NULL; 122 } 123 124 if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) { 125 /* LCOV_EXCL_START */ 126 return NULL; 127 /* LCOV_EXCL_STOP */ 128 } 129 130 if (mpz_sgn(tempx->z) < 0) { 131 VALUE_ERROR("iroot() of negative number"); 132 Py_DECREF((PyObject*)tempx); 133 return NULL; 134 } 135 136 137 138 if (!(result = PyTuple_New(2)) || 139 !(root = GMPy_MPZ_New(NULL))) { 140 141 /* LCOV_EXCL_START */ 142 Py_DECREF((PyObject*)tempx); 143 Py_XDECREF((PyObject*)root); 144 Py_XDECREF(result); 145 return NULL; 146 /* LCOV_EXCL_STOP */ 147 } 148 149 exact = mpz_root(root->z, tempx->z, n); 150 Py_DECREF((PyObject*)tempx); 151 152 PyTuple_SET_ITEM(result, 0, (PyObject*)root); 153 PyTuple_SET_ITEM(result, 1, (PyObject*)PyBool_FromLong(exact)); 154 return result; 155 } 156 157 PyDoc_STRVAR(GMPy_doc_mpz_function_iroot_rem, 158 "iroot_rem(x,n) -> (number, number)\n\n" 159 "Return a 2-element tuple (y,r), such that y is the integer n-th\n" 160 "root of x and x=y**n + r. x >= 0. n > 0."); 161 162 static PyObject * 163 GMPy_MPZ_Function_IrootRem(PyObject *self, PyObject *args) 164 { 165 unsigned long n; 166 MPZ_Object *root = NULL, *rem = NULL, *tempx = NULL; 167 PyObject *result = NULL; 168 169 if ((PyTuple_GET_SIZE(args) != 2) || 170 ((!IS_INTEGER(PyTuple_GET_ITEM(args, 0))) || 171 (!IS_INTEGER(PyTuple_GET_ITEM(args, 1))))) { 172 173 TYPE_ERROR("iroot_rem() requires 'int','int' arguments"); 174 return NULL; 175 } 176 177 n = c_ulong_From_Integer(PyTuple_GET_ITEM(args, 1)); 178 if ((n == 0) || ((n == (unsigned long)(-1)) && PyErr_Occurred())) { 179 VALUE_ERROR("n must be > 0"); 180 return NULL; 181 } 182 183 if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) { 184 /* LCOV_EXCL_START */ 185 return NULL; 186 /* LCOV_EXCL_STOP */ 187 } 188 189 if (mpz_sgn(tempx->z) < 0) { 190 VALUE_ERROR("iroot_rem() of negative number"); 191 Py_DECREF((PyObject*)tempx); 192 return NULL; 193 } 194 195 if (!(result = PyTuple_New(2)) || 196 !(root = GMPy_MPZ_New(NULL)) || 197 !(rem = GMPy_MPZ_New(NULL))) { 198 199 /* LCOV_EXCL_START */ 200 Py_DECREF((PyObject*)tempx); 201 Py_XDECREF(result); 202 Py_XDECREF((PyObject*)root); 203 Py_XDECREF((PyObject*)rem); 204 return NULL; 205 /* LCOV_EXCL_STOP */ 206 } 207 208 mpz_rootrem(root->z, rem->z, tempx->z, n); 209 Py_DECREF((PyObject*)tempx); 210 211 PyTuple_SET_ITEM(result, 0, (PyObject*)root); 212 PyTuple_SET_ITEM(result, 1, (PyObject*)rem); 213 return result; 214 } 215 216 PyDoc_STRVAR(GMPy_doc_mpz_method_ceil, "Ceiling of an mpz returns itself."); 217 218 static PyObject * 219 GMPy_MPZ_Method_Ceil(PyObject *self, PyObject *other) 220 { 221 Py_INCREF(self); 222 return self; 223 } 224 225 PyDoc_STRVAR(GMPy_doc_mpz_method_floor, "Floor of an mpz returns itself."); 226 227 static PyObject * 228 GMPy_MPZ_Method_Floor(PyObject *self, PyObject *other) 229 { 230 Py_INCREF(self); 231 return self; 232 } 233 234 PyDoc_STRVAR(GMPy_doc_mpz_method_trunc, "Truncating an mpz returns itself."); 235 236 static PyObject * 237 GMPy_MPZ_Method_Trunc(PyObject *self, PyObject *other) 238 { 239 Py_INCREF(self); 240 return self; 241 } 242 243 PyDoc_STRVAR(GMPy_doc_mpz_method_round, "Round an mpz to power of 10."); 244 245 static PyObject * 246 GMPy_MPZ_Method_Round(PyObject *self, PyObject *args) 247 { 248 Py_ssize_t round_digits; 249 MPZ_Object *result; 250 mpz_t temp, rem; 251 252 if (PyTuple_GET_SIZE(args) == 0) { 253 Py_INCREF(self); 254 return self; 255 } 256 257 round_digits = ssize_t_From_Integer(PyTuple_GET_ITEM(args, 0)); 258 if (round_digits == -1 && PyErr_Occurred()) { 259 TYPE_ERROR("__round__() requires 'int' argument"); 260 return NULL; 261 } 262 263 if (round_digits >= 0) { 264 Py_INCREF(self); 265 return self; 266 } 267 268 /* We can now assume round_digits > 0. */ 269 round_digits = -round_digits; 270 271 if ((result = GMPy_MPZ_New(NULL))) { 272 if ((unsigned)round_digits >= mpz_sizeinbase(MPZ(self), 10)) { 273 mpz_set_ui(result->z, 0); 274 } 275 else { 276 mpz_init(temp); 277 mpz_init(rem); 278 mpz_ui_pow_ui(temp, 10, round_digits); 279 mpz_fdiv_qr(result->z, rem, MPZ(self), temp); 280 mpz_mul_2exp(rem, rem, 1); 281 if (mpz_cmp(rem, temp) > 0) { 282 mpz_add_ui(result->z, result->z, 1); 283 } 284 else if (mpz_cmp(rem, temp) == 0) { 285 if (mpz_odd_p(result->z)) { 286 mpz_add_ui(result->z, result->z, 1); 287 } 288 } 289 mpz_mul(result->z, result->z, temp); 290 mpz_clear(rem); 291 mpz_clear(temp); 292 } 293 } 294 295 return (PyObject*)result; 296 } 297 298 static int 299 GMPy_MPZ_NonZero_Slot(MPZ_Object *self) 300 { 301 return mpz_sgn(self->z) != 0; 302 } 303 304 #if PY_MAJOR_VERSION < 3 305 306 /* hex/oct formatting (mpz-only) */ 307 308 static PyObject * 309 GMPy_MPZ_Oct_Slot(MPZ_Object *self) 310 { 311 return GMPy_PyStr_From_MPZ(self, 8, 0, NULL); 312 } 313 314 static PyObject * 315 GMPy_MPZ_Hex_Slot(MPZ_Object *self) 316 { 317 return GMPy_PyStr_From_MPZ(self, 16, 0, NULL); 318 } 319 #endif 320 321 /* Miscellaneous gmpy functions */ 322 323 PyDoc_STRVAR(GMPy_doc_mpz_function_gcd, 324 "gcd(a, b) -> mpz\n\n" 325 "Return the greatest common divisor of integers a and b."); 326 327 static PyObject * 328 GMPy_MPZ_Function_GCD(PyObject *self, PyObject *args) 329 { 330 PyObject *arg0, *arg1; 331 MPZ_Object *result = NULL, *tempa = NULL, *tempb = NULL; 332 333 if (PyTuple_GET_SIZE(args) != 2) { 334 TYPE_ERROR("gcd() requires 'mpz','mpz' arguments"); 335 return NULL; 336 } 337 338 if (!(result = GMPy_MPZ_New(NULL))) { 339 /* LCOV_EXCL_START */ 340 return NULL; 341 /* LCOV_EXCL_STOP */ 342 } 343 344 arg0 = PyTuple_GET_ITEM(args, 0); 345 arg1 = PyTuple_GET_ITEM(args, 1); 346 if (MPZ_Check(arg0) && MPZ_Check(arg1)) { 347 mpz_gcd(result->z, MPZ(arg0), MPZ(arg1)); 348 } 349 else { 350 if (!(tempa = GMPy_MPZ_From_Integer(arg0, NULL)) || 351 !(tempb = GMPy_MPZ_From_Integer(arg1, NULL))) { 352 353 TYPE_ERROR("gcd() requires 'mpz','mpz' arguments"); 354 Py_XDECREF((PyObject*)tempa); 355 Py_XDECREF((PyObject*)tempb); 356 Py_DECREF((PyObject*)result); 357 return NULL; 358 } 359 360 mpz_gcd(result->z, tempa->z, tempb->z); 361 Py_DECREF((PyObject*)tempa); 362 Py_DECREF((PyObject*)tempb); 363 } 364 return (PyObject*)result; 365 } 366 367 PyDoc_STRVAR(GMPy_doc_mpz_function_lcm, 368 "lcm(a, b) -> mpz\n\n" 369 "Return the lowest common multiple of integers a and b."); 370 371 static PyObject * 372 GMPy_MPZ_Function_LCM(PyObject *self, PyObject *args) 373 { 374 PyObject *arg0, *arg1; 375 MPZ_Object *result = NULL, *tempa = NULL, *tempb = NULL; 376 377 if(PyTuple_GET_SIZE(args) != 2) { 378 TYPE_ERROR("lcm() requires 'mpz','mpz' arguments"); 379 return NULL; 380 } 381 382 if (!(result = GMPy_MPZ_New(NULL))) { 383 /* LCOV_EXCL_START */ 384 return NULL; 385 /* LCOV_EXCL_STOP */ 386 } 387 388 arg0 = PyTuple_GET_ITEM(args, 0); 389 arg1 = PyTuple_GET_ITEM(args, 1); 390 391 if (MPZ_Check(arg0) && MPZ_Check(arg1)) { 392 mpz_lcm(result->z, MPZ(arg0), MPZ(arg1)); 393 } 394 else { 395 if (!(tempa = GMPy_MPZ_From_Integer(arg0, NULL)) || 396 !(tempb = GMPy_MPZ_From_Integer(arg1, NULL))) { 397 398 TYPE_ERROR("lcm() requires 'mpz','mpz' arguments"); 399 Py_XDECREF((PyObject*)tempa); 400 Py_XDECREF((PyObject*)tempb); 401 Py_DECREF((PyObject*)result); 402 return NULL; 403 } 404 mpz_lcm(result->z, tempa->z, tempb->z); 405 Py_DECREF((PyObject*)tempa); 406 Py_DECREF((PyObject*)tempb); 407 } 408 return (PyObject*)result; 409 } 410 411 PyDoc_STRVAR(GMPy_doc_mpz_function_gcdext, 412 "gcdext(a, b) - > tuple\n\n" 413 "Return a 3-element tuple (g,s,t) such that\n" 414 " g == gcd(a,b) and g == a*s + b*t"); 415 416 static PyObject * 417 GMPy_MPZ_Function_GCDext(PyObject *self, PyObject *args) 418 { 419 PyObject *arg0, *arg1, *result = NULL; 420 MPZ_Object *g = NULL, *s = NULL, *t = NULL, *tempa = NULL, *tempb = NULL; 421 422 if(PyTuple_GET_SIZE(args) != 2) { 423 TYPE_ERROR("gcdext() requires 'mpz','mpz' arguments"); 424 return NULL; 425 } 426 427 if (!(result = PyTuple_New(3)) || 428 !(g = GMPy_MPZ_New(NULL)) || 429 !(s = GMPy_MPZ_New(NULL)) || 430 !(t = GMPy_MPZ_New(NULL))) { 431 432 /* LCOV_EXCL_START */ 433 Py_XDECREF((PyObject*)g); 434 Py_XDECREF((PyObject*)s); 435 Py_XDECREF((PyObject*)t); 436 Py_XDECREF(result); 437 return NULL; 438 /* LCOV_EXCL_STOP */ 439 } 440 441 arg0 = PyTuple_GET_ITEM(args, 0); 442 arg1 = PyTuple_GET_ITEM(args, 1); 443 444 if (MPZ_Check(arg0) && MPZ_Check(arg1)) { 445 mpz_gcdext(g->z, s->z, t->z, MPZ(arg0), MPZ(arg1)); 446 } 447 else { 448 if(!(tempa = GMPy_MPZ_From_Integer(arg0, NULL)) || 449 !(tempb = GMPy_MPZ_From_Integer(arg1, NULL))) { 450 451 TYPE_ERROR("gcdext() requires 'mpz','mpz' arguments"); 452 Py_XDECREF((PyObject*)tempa); 453 Py_XDECREF((PyObject*)tempb); 454 Py_DECREF((PyObject*)g); 455 Py_DECREF((PyObject*)s); 456 Py_DECREF((PyObject*)t); 457 Py_DECREF(result); 458 return NULL; 459 } 460 mpz_gcdext(g->z, s->z, t->z, tempa->z, tempb->z); 461 Py_DECREF((PyObject*)tempa); 462 Py_DECREF((PyObject*)tempb); 463 } 464 PyTuple_SET_ITEM(result, 0, (PyObject*)g); 465 PyTuple_SET_ITEM(result, 1, (PyObject*)s); 466 PyTuple_SET_ITEM(result, 2, (PyObject*)t); 467 return result; 468 } 469 470 PyDoc_STRVAR(GMPy_doc_mpz_function_divm, 471 "divm(a, b, m) -> mpz\n\n" 472 "Return x such that b*x == a mod m. Raises a ZeroDivisionError\n" 473 "exception if no such value x exists."); 474 475 static PyObject * 476 GMPy_MPZ_Function_Divm(PyObject *self, PyObject *args) 477 { 478 MPZ_Object *result = NULL, *num = NULL, *den = NULL, *mod = NULL; 479 mpz_t numz, denz, modz, gcdz; 480 int ok = 0; 481 482 if (PyTuple_GET_SIZE(args) != 3) { 483 TYPE_ERROR("divm() requires 'mpz','mpz','mpz' arguments"); 484 return NULL; 485 } 486 487 if (!(result = GMPy_MPZ_New(NULL))) { 488 /* LCOV_EXCL_START */ 489 return NULL; 490 /* LCOV_EXCL_STOP */ 491 } 492 493 if (!(num = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL)) || 494 !(den = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL)) || 495 !(mod = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 2), NULL))) { 496 497 TYPE_ERROR("divm() requires 'mpz','mpz','mpz' arguments"); 498 Py_XDECREF((PyObject*)num); 499 Py_XDECREF((PyObject*)den); 500 Py_XDECREF((PyObject*)mod); 501 Py_DECREF((PyObject*)result); 502 return NULL; 503 } 504 505 /* Make copies so we don't destroy the input. */ 506 mpz_init(numz); 507 mpz_init(denz); 508 mpz_init(modz); 509 mpz_set(numz, num->z); 510 mpz_set(denz, den->z); 511 mpz_set(modz, mod->z); 512 Py_DECREF((PyObject*)num); 513 Py_DECREF((PyObject*)den); 514 Py_DECREF((PyObject*)mod); 515 516 if (mpz_invert(result->z, denz, modz)) { /* inverse exists */ 517 ok = 1; 518 } 519 else { 520 521 /* last-ditch attempt: do num, den AND mod have a gcd>1 ? */ 522 mpz_init(gcdz); 523 mpz_gcd(gcdz, numz, denz); 524 mpz_gcd(gcdz, gcdz, modz); 525 mpz_divexact(numz, numz, gcdz); 526 mpz_divexact(denz, denz, gcdz); 527 mpz_divexact(modz, modz, gcdz); 528 mpz_clear(gcdz); 529 ok = mpz_invert(result->z, denz, modz); 530 } 531 532 if (ok) { 533 mpz_mul(result->z, result->z, numz); 534 mpz_mod(result->z, result->z, modz); 535 mpz_clear(numz); 536 mpz_clear(denz); 537 mpz_clear(modz); 538 return (PyObject*)result; 539 } 540 else { 541 ZERO_ERROR("not invertible"); 542 mpz_clear(numz); 543 mpz_clear(denz); 544 mpz_clear(modz); 545 Py_DECREF((PyObject*)result); 546 return NULL; 547 } 548 } 549 550 PyDoc_STRVAR(GMPy_doc_mpz_function_fac, 551 "fac(n) -> mpz\n\n" 552 "Return the exact factorial of n.\n\n" 553 "See factorial(n) to get the floating-point approximation."); 554 555 static PyObject * 556 GMPy_MPZ_Function_Fac(PyObject *self, PyObject *other) 557 { 558 MPZ_Object *result = NULL; 559 unsigned long n; 560 561 n = c_ulong_From_Integer(other); 562 if (n == (unsigned long)(-1) && PyErr_Occurred()) { 563 return NULL; 564 } 565 566 if ((result = GMPy_MPZ_New(NULL))) { 567 mpz_fac_ui(result->z, n); 568 } 569 return (PyObject*)result; 570 } 571 572 PyDoc_STRVAR(GMPy_doc_mpz_function_double_fac, 573 "double_fac(n) -> mpz\n\n" 574 "Return the exact double factorial (n!!) of n. The double\n" 575 "factorial is defined as n*(n-2)*(n-4)..."); 576 577 static PyObject * 578 GMPy_MPZ_Function_DoubleFac(PyObject *self, PyObject *other) 579 { 580 MPZ_Object *result = NULL; 581 unsigned long n; 582 583 n = c_ulong_From_Integer(other); 584 if (n == (unsigned long)(-1) && PyErr_Occurred()) { 585 return NULL; 586 } 587 588 if ((result = GMPy_MPZ_New(NULL))) { 589 mpz_2fac_ui(result->z, n); 590 } 591 return (PyObject*)result; 592 } 593 594 PyDoc_STRVAR(GMPy_doc_mpz_function_primorial, 595 "primorial(n) -> mpz\n\n" 596 "Return the product of all positive prime numbers less than or" 597 "equal to n."); 598 599 static PyObject * 600 GMPy_MPZ_Function_Primorial(PyObject *self, PyObject *other) 601 { 602 MPZ_Object *result = NULL; 603 unsigned long n; 604 605 n = c_ulong_From_Integer(other); 606 if (n == (unsigned long)(-1) && PyErr_Occurred()) { 607 return NULL; 608 } 609 610 if ((result = GMPy_MPZ_New(NULL))) { 611 mpz_primorial_ui(result->z, n); 612 } 613 return (PyObject*)result; 614 } 615 616 PyDoc_STRVAR(GMPy_doc_mpz_function_multi_fac, 617 "multi_fac(n,m) -> mpz\n\n" 618 "Return the exact m-multi factorial of n. The m-multi" 619 "factorial is defined as n*(n-m)*(n-2m)..."); 620 621 static PyObject * 622 GMPy_MPZ_Function_MultiFac(PyObject *self, PyObject *args) 623 { 624 MPZ_Object *result = NULL; 625 unsigned long n, m; 626 627 if (PyTuple_GET_SIZE(args) != 2) { 628 TYPE_ERROR("multi_fac() requires 2 integer arguments"); 629 return NULL; 630 } 631 632 n = c_ulong_From_Integer(PyTuple_GET_ITEM(args, 0)); 633 if (n == (unsigned long)(-1) && PyErr_Occurred()) { 634 return NULL; 635 } 636 637 m = c_ulong_From_Integer(PyTuple_GET_ITEM(args, 1)); 638 if (m == (unsigned long)(-1) && PyErr_Occurred()) { 639 return NULL; 640 } 641 642 if ((result = GMPy_MPZ_New(NULL))) { 643 mpz_mfac_uiui(result->z, n, m); 644 } 645 return (PyObject*)result; 646 } 647 648 PyDoc_STRVAR(GMPy_doc_mpz_function_fib, 649 "fib(n) -> mpz\n\n" 650 "Return the n-th Fibonacci number."); 651 652 static PyObject * 653 GMPy_MPZ_Function_Fib(PyObject *self, PyObject *other) 654 { 655 MPZ_Object *result = NULL; 656 unsigned long n; 657 658 n = c_ulong_From_Integer(other); 659 if (n == (unsigned long)(-1) && PyErr_Occurred()) { 660 return NULL; 661 } 662 if ((result = GMPy_MPZ_New(NULL))) { 663 mpz_fib_ui(result->z, n); 664 } 665 return (PyObject*)result; 666 } 667 668 PyDoc_STRVAR(GMPy_doc_mpz_function_fib2, 669 "fib2(n) -> tuple\n\n" 670 "Return a 2-tuple with the (n-1)-th and n-th Fibonacci numbers."); 671 672 static PyObject * 673 GMPy_MPZ_Function_Fib2(PyObject *self, PyObject *other) 674 { 675 PyObject *result = NULL; 676 MPZ_Object *fib1 = NULL, *fib2 = NULL; 677 unsigned long n; 678 679 n = c_ulong_From_Integer(other); 680 if (n == (unsigned long)(-1) && PyErr_Occurred()) { 681 return NULL; 682 } 683 684 if (!(result = PyTuple_New(2)) || 685 !(fib1 = GMPy_MPZ_New(NULL)) || 686 !(fib2 = GMPy_MPZ_New(NULL))) { 687 688 /* LCOV_EXCL_START */ 689 Py_XDECREF(result); 690 Py_XDECREF((PyObject*)fib1); 691 Py_XDECREF((PyObject*)fib2); 692 result = NULL; 693 /* LCOV_EXCL_STOP */ 694 } 695 696 mpz_fib2_ui(fib1->z, fib2->z, n); 697 PyTuple_SET_ITEM(result, 0, (PyObject*)fib1); 698 PyTuple_SET_ITEM(result, 1, (PyObject*)fib2); 699 return (PyObject*)result; 700 } 701 702 PyDoc_STRVAR(GMPy_doc_mpz_function_lucas, 703 "lucas(n) -> mpz\n\n" 704 "Return the n-th Lucas number."); 705 706 static PyObject * 707 GMPy_MPZ_Function_Lucas(PyObject *self, PyObject *other) 708 { 709 MPZ_Object *result = NULL; 710 unsigned long n; 711 712 n = c_ulong_From_Integer(other); 713 if (n == (unsigned long)(-1) && PyErr_Occurred()) { 714 return NULL; 715 } 716 717 if ((result = GMPy_MPZ_New(NULL))) { 718 mpz_lucnum_ui(result->z, n); 719 } 720 return (PyObject*)result; 721 } 722 723 PyDoc_STRVAR(GMPy_doc_mpz_function_lucas2, 724 "lucas2(n) -> tuple\n\n" 725 "Return a 2-tuple with the (n-1)-th and n-th Lucas numbers."); 726 727 static PyObject * 728 GMPy_MPZ_Function_Lucas2(PyObject *self, PyObject *other) 729 { 730 PyObject *result = NULL; 731 MPZ_Object *luc1 = NULL, *luc2 = NULL; 732 unsigned long n; 733 734 n = c_ulong_From_Integer(other); 735 if (n == (unsigned long)(-1) && PyErr_Occurred()) { 736 return NULL; 737 } 738 739 if (!(result = PyTuple_New(2)) || 740 !(luc1 = GMPy_MPZ_New(NULL)) || 741 !(luc2 = GMPy_MPZ_New(NULL))) { 742 743 /* LCOV_EXCL_START */ 744 Py_XDECREF(result); 745 Py_XDECREF((PyObject*)luc1); 746 Py_XDECREF((PyObject*)luc2); 747 result = NULL; 748 /* LCOV_EXCL_STOP */ 749 } 750 751 mpz_lucnum2_ui(luc1->z, luc2->z, n); 752 PyTuple_SET_ITEM(result, 0, (PyObject*)luc1); 753 PyTuple_SET_ITEM(result, 1, (PyObject*)luc2); 754 return result; 755 } 756 757 PyDoc_STRVAR(GMPy_doc_mpz_function_bincoef, 758 "bincoef(n, k) -> mpz\n\n" 759 "Return the binomial coefficient ('n choose k'). k >= 0."); 760 761 PyDoc_STRVAR(GMPy_doc_mpz_function_comb, 762 "comb(n, k) -> mpz\n\n" 763 "Return the number of combinations of 'n things, taking k at a\n" 764 "time'. k >= 0. Same as bincoef(n, k)"); 765 766 static PyObject * 767 GMPy_MPZ_Function_Bincoef(PyObject *self, PyObject *args) 768 { 769 MPZ_Object *result = NULL, *tempx; 770 unsigned long n, k; 771 772 if (PyTuple_GET_SIZE(args) != 2) { 773 TYPE_ERROR("bincoef() requires two integer arguments"); 774 return NULL; 775 } 776 777 if (!(result = GMPy_MPZ_New(NULL))) { 778 /* LCOV_EXCL_START */ 779 return NULL; 780 /* LCOV_EXCL_STOP */ 781 } 782 783 k = c_ulong_From_Integer(PyTuple_GET_ITEM(args, 1)); 784 if (k == (unsigned long)(-1) && PyErr_Occurred()) { 785 Py_DECREF((PyObject*)result); 786 return NULL; 787 } 788 789 n = c_ulong_From_Integer(PyTuple_GET_ITEM(args, 0)); 790 if (n == (unsigned long)(-1) && PyErr_Occurred()) { 791 /* Since we plan to skip the else clause and continue, 792 * we need to clear the error since we aren't acting on it. 793 */ 794 PyErr_Clear(); 795 } 796 else { 797 /* Use mpz_bin_uiui which should be faster. */ 798 mpz_bin_uiui(result->z, n, k); 799 return (PyObject*)result; 800 } 801 802 if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) { 803 Py_DECREF((PyObject*)result); 804 return NULL; 805 } 806 807 mpz_bin_ui(result->z, tempx->z, k); 808 Py_DECREF((PyObject*)tempx); 809 return (PyObject*)result; 810 } 811 812 PyDoc_STRVAR(GMPy_doc_mpz_function_isqrt, 813 "isqrt(x) -> mpz\n\n" 814 "Return the integer square root of an integer x. x >= 0."); 815 816 static PyObject * 817 GMPy_MPZ_Function_Isqrt(PyObject *self, PyObject *other) 818 { 819 MPZ_Object *result; 820 821 if (CHECK_MPZANY(other)) { 822 if (mpz_sgn(MPZ(other)) < 0) { 823 VALUE_ERROR("isqrt() of negative number"); 824 return NULL; 825 } 826 if ((result = GMPy_MPZ_New(NULL))) { 827 mpz_sqrt(result->z, MPZ(other)); 828 } 829 } 830 else { 831 if (!(result = GMPy_MPZ_From_Integer(other, NULL))) { 832 TYPE_ERROR("isqrt() requires 'mpz' argument"); 833 return NULL; 834 } 835 if (mpz_sgn(result->z) < 0) { 836 VALUE_ERROR("isqrt() of negative number"); 837 Py_DECREF((PyObject*)result); 838 return NULL; 839 } 840 mpz_sqrt(result->z, result->z); 841 } 842 return (PyObject*)result; 843 } 844 845 PyDoc_STRVAR(GMPy_doc_mpz_function_isqrt_rem, 846 "isqrt_rem(x) -> tuple\n\n" 847 "Return a 2-element tuple (s,t) such that s=isqrt(x) and t=x-s*s.\n" 848 "x >=0."); 849 850 static PyObject * 851 GMPy_MPZ_Function_IsqrtRem(PyObject *self, PyObject *other) 852 { 853 MPZ_Object *root = NULL, *rem = NULL, *temp = NULL; 854 PyObject *result; 855 856 if (!(temp = GMPy_MPZ_From_Integer(other, NULL))) { 857 TYPE_ERROR("isqrt_rem() requires 'mpz' argument"); 858 return NULL; 859 } 860 861 if (mpz_sgn(temp->z) < 0) { 862 VALUE_ERROR("isqrt_rem() of negative number"); 863 Py_DECREF((PyObject*)temp); 864 return NULL; 865 } 866 867 868 869 870 if (!(result = PyTuple_New(2)) || 871 !(root = GMPy_MPZ_New(NULL)) || 872 !(rem = GMPy_MPZ_New(NULL))) { 873 874 /* LCOV_EXCL_START */ 875 Py_DECREF((PyObject*)temp); 876 Py_XDECREF(result); 877 Py_XDECREF((PyObject*)root); 878 Py_XDECREF((PyObject*)rem); 879 return NULL; 880 /* LCOV_EXCL_STOP */ 881 } 882 883 mpz_sqrtrem(root->z, rem->z, temp->z); 884 Py_DECREF((PyObject*)temp); 885 PyTuple_SET_ITEM(result, 0, (PyObject*)root); 886 PyTuple_SET_ITEM(result, 1, (PyObject*)rem); 887 return result; 888 } 889 890 PyDoc_STRVAR(GMPy_doc_mpz_function_remove, 891 "remove(x, f) -> tuple\n\n" 892 "Return a 2-element tuple (y,m) such that x=y*(f**m) and f does\n" 893 "not divide y. Remove the factor f from x as many times as\n" 894 "possible. m is the multiplicity f in x. f > 1."); 895 896 static PyObject * 897 GMPy_MPZ_Function_Remove(PyObject *self, PyObject *args) 898 { 899 MPZ_Object *result = NULL, *tempx = NULL, *tempf = NULL; 900 PyObject *x, *f; 901 size_t multiplicity; 902 903 if (PyTuple_GET_SIZE(args) != 2) { 904 TYPE_ERROR("remove() requires 'mpz','mpz' arguments"); 905 return NULL; 906 } 907 908 if (!(result = GMPy_MPZ_New(NULL))) { 909 /* LCOV_EXCL_START */ 910 return NULL; 911 /* LCOV_EXCL_STOP */ 912 } 913 914 x = PyTuple_GET_ITEM(args, 0); 915 f = PyTuple_GET_ITEM(args, 1); 916 917 if (MPZ_Check(x) && MPZ_Check(f)) { 918 if (mpz_cmp_si(MPZ(f), 2) < 0) { 919 VALUE_ERROR("factor must be > 1"); 920 Py_DECREF((PyObject*)result); 921 return NULL; 922 } 923 multiplicity = mpz_remove(result->z, MPZ(x), MPZ(f)); 924 return Py_BuildValue("(Nk)", result, multiplicity); 925 } 926 else { 927 928 929 if (!(tempx = GMPy_MPZ_From_Integer(x, NULL)) || 930 !(tempf = GMPy_MPZ_From_Integer(f, NULL))) { 931 932 TYPE_ERROR("remove() requires 'mpz','mpz' arguments"); 933 Py_XDECREF((PyObject*)tempx); 934 Py_XDECREF((PyObject*)tempf); 935 Py_DECREF((PyObject*)result); 936 return NULL; 937 } 938 if (mpz_cmp_si(MPZ(tempf), 2) < 0) { 939 VALUE_ERROR("factor must be > 1"); 940 Py_DECREF((PyObject*)tempx); 941 Py_DECREF((PyObject*)tempf); 942 Py_DECREF((PyObject*)result); 943 return NULL; 944 } 945 multiplicity = mpz_remove(result->z, tempx->z, tempf->z); 946 Py_DECREF((PyObject*)tempx); 947 Py_DECREF((PyObject*)tempf); 948 return Py_BuildValue("(Nk)", result, multiplicity); 949 } 950 } 951 952 PyDoc_STRVAR(GMPy_doc_mpz_function_invert, 953 "invert(x, m) -> mpz\n\n" 954 "Return y such that x*y == 1 modulo m. Raises ZeroDivisionError if no\n" 955 "inverse exists."); 956 957 static PyObject * 958 GMPy_MPZ_Function_Invert(PyObject *self, PyObject *args) 959 { 960 PyObject *x, *y; 961 MPZ_Object *result = NULL, *tempx = NULL, *tempy = NULL; 962 int success; 963 964 if (PyTuple_GET_SIZE(args) != 2) { 965 TYPE_ERROR("invert() requires 'mpz','mpz' arguments"); 966 return NULL; 967 } 968 969 if (!(result = GMPy_MPZ_New(NULL))) { 970 /* LCOV_EXCL_START */ 971 return NULL; 972 /* LCOV_EXCL_STOP */ 973 } 974 975 x = PyTuple_GET_ITEM(args, 0); 976 y = PyTuple_GET_ITEM(args, 1); 977 978 if (MPZ_Check(x) && MPZ_Check(y)) { 979 if (mpz_sgn(MPZ(y)) == 0) { 980 ZERO_ERROR("invert() division by 0"); 981 Py_DECREF((PyObject*)result); 982 return NULL; 983 } 984 success = mpz_invert(result->z, MPZ(x), MPZ(y)); 985 if (!success) { 986 ZERO_ERROR("invert() no inverse exists"); 987 Py_DECREF((PyObject*)result); 988 return NULL; 989 } 990 } 991 else { 992 993 994 if (!(tempx = GMPy_MPZ_From_Integer(x, NULL)) || 995 !(tempy = GMPy_MPZ_From_Integer(y, NULL))) { 996 997 TYPE_ERROR("invert() requires 'mpz','mpz' arguments"); 998 Py_XDECREF((PyObject*)tempx); 999 Py_XDECREF((PyObject*)tempy); 1000 Py_DECREF((PyObject*)result); 1001 return NULL; 1002 } 1003 if (mpz_sgn(tempy->z) == 0) { 1004 ZERO_ERROR("invert() division by 0"); 1005 Py_DECREF((PyObject*)tempx); 1006 Py_DECREF((PyObject*)tempy); 1007 Py_DECREF(result); 1008 return NULL; 1009 } 1010 success = mpz_invert(result->z, tempx->z, tempy->z); 1011 Py_DECREF((PyObject*)tempx); 1012 Py_DECREF((PyObject*)tempy); 1013 if (!success) { 1014 ZERO_ERROR("invert() no inverse exists"); 1015 Py_DECREF((PyObject*)result); 1016 return NULL; 1017 } 1018 } 1019 return (PyObject*)result; 1020 } 1021 1022 PyDoc_STRVAR(GMPy_doc_mpz_function_divexact, 1023 "divexact(x, y) -> mpz\n\n" 1024 "Return the quotient of x divided by y. Faster than standard\n" 1025 "division but requires the remainder is zero!"); 1026 1027 static PyObject * 1028 GMPy_MPZ_Function_Divexact(PyObject *self, PyObject *args) 1029 { 1030 PyObject *x, *y; 1031 MPZ_Object *result, *tempx= NULL, *tempy = NULL; 1032 1033 if(PyTuple_GET_SIZE(args) != 2) { 1034 TYPE_ERROR("divexact() requires 'mpz','mpz' arguments"); 1035 return NULL; 1036 } 1037 1038 if (!(result = GMPy_MPZ_New(NULL))) { 1039 /* LCOV_EXCL_START */ 1040 return NULL; 1041 /* LCOV_EXCL_STOP */ 1042 } 1043 1044 x = PyTuple_GET_ITEM(args, 0); 1045 y = PyTuple_GET_ITEM(args, 1); 1046 1047 if (MPZ_Check(x) && MPZ_Check(y)) { 1048 if (mpz_sgn(MPZ(y)) == 0) { 1049 ZERO_ERROR("divexact() division by 0"); 1050 Py_DECREF((PyObject*)result); 1051 return NULL; 1052 } 1053 mpz_divexact(result->z, MPZ(x), MPZ(y)); 1054 } 1055 else { 1056 if (!(tempx = GMPy_MPZ_From_Integer(x, NULL)) || 1057 !(tempy = GMPy_MPZ_From_Integer(y, NULL))) { 1058 1059 TYPE_ERROR("divexact() requires 'mpz','mpz' arguments"); 1060 Py_XDECREF((PyObject*)tempx); 1061 Py_XDECREF((PyObject*)tempy); 1062 Py_DECREF((PyObject*)result); 1063 return NULL; 1064 } 1065 if (mpz_sgn(MPZ(tempy)) == 0) { 1066 ZERO_ERROR("divexact() division by 0"); 1067 Py_DECREF((PyObject*)tempx); 1068 Py_DECREF((PyObject*)tempy); 1069 Py_DECREF((PyObject*)result); 1070 return NULL; 1071 } 1072 mpz_divexact(result->z, tempx->z, tempy->z); 1073 Py_DECREF((PyObject*)tempx); 1074 Py_DECREF((PyObject*)tempy); 1075 } 1076 return (PyObject*)result; 1077 } 1078 1079 PyDoc_STRVAR(GMPy_doc_mpz_function_is_square, 1080 "is_square(x) -> bool\n\n" 1081 "Returns True if x is a perfect square, else return False."); 1082 1083 static PyObject * 1084 GMPy_MPZ_Function_IsSquare(PyObject *self, PyObject *other) 1085 { 1086 int res; 1087 MPZ_Object *tempx; 1088 1089 if (MPZ_Check(other)) { 1090 res = mpz_perfect_square_p(MPZ(other)); 1091 } 1092 else { 1093 if (!(tempx = GMPy_MPZ_From_Integer(other, NULL))) { 1094 TYPE_ERROR("is_square() requires 'mpz' argument"); 1095 return NULL; 1096 } 1097 else { 1098 res = mpz_perfect_square_p(tempx->z); 1099 Py_DECREF((PyObject*)tempx); 1100 } 1101 } 1102 1103 if (res) 1104 Py_RETURN_TRUE; 1105 else 1106 Py_RETURN_FALSE; 1107 } 1108 1109 PyDoc_STRVAR(GMPy_doc_mpz_method_is_square, 1110 "x.is_square() -> bool\n\n" 1111 "Returns True if x is a perfect square, else return False."); 1112 1113 static PyObject * 1114 GMPy_MPZ_Method_IsSquare(PyObject *self, PyObject *other) 1115 { 1116 int res; 1117 1118 res = mpz_perfect_square_p(MPZ(self)); 1119 1120 if (res) 1121 Py_RETURN_TRUE; 1122 else 1123 Py_RETURN_FALSE; 1124 } 1125 1126 PyDoc_STRVAR(GMPy_doc_mpz_function_is_divisible, 1127 "is_divisible(x, d) -> bool\n\n" 1128 "Returns True if x is divisible by d, else return False."); 1129 1130 static PyObject * 1131 GMPy_MPZ_Function_IsDivisible(PyObject *self, PyObject *args) 1132 { 1133 unsigned long temp; 1134 int error, res; 1135 MPZ_Object *tempx, *tempd; 1136 1137 if (PyTuple_GET_SIZE(args) != 2) { 1138 TYPE_ERROR("is_divisible() requires 2 integer arguments"); 1139 return NULL; 1140 } 1141 1142 if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) { 1143 return NULL; 1144 } 1145 1146 temp = GMPy_Integer_AsUnsignedLongAndError(PyTuple_GET_ITEM(args, 1), &error); 1147 if (!error) { 1148 res = mpz_divisible_ui_p(tempx->z, temp); 1149 Py_DECREF((PyObject*)tempx); 1150 if (res) 1151 Py_RETURN_TRUE; 1152 else 1153 Py_RETURN_FALSE; 1154 } 1155 1156 if (!(tempd = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL))) { 1157 TYPE_ERROR("is_divisible() requires 2 integer arguments"); 1158 Py_DECREF((PyObject*)tempx); 1159 return NULL; 1160 } 1161 1162 res = mpz_divisible_p(tempx->z, tempd->z); 1163 Py_DECREF((PyObject*)tempx); 1164 Py_DECREF((PyObject*)tempd); 1165 if (res) 1166 Py_RETURN_TRUE; 1167 else 1168 Py_RETURN_FALSE; 1169 } 1170 1171 PyDoc_STRVAR(GMPy_doc_mpz_method_is_divisible, 1172 "x.is_divisible(d) -> bool\n\n" 1173 "Returns True if x is divisible by d, else return False."); 1174 1175 static PyObject * 1176 GMPy_MPZ_Method_IsDivisible(PyObject *self, PyObject *other) 1177 { 1178 unsigned long temp; 1179 int error, res; 1180 MPZ_Object *tempd; 1181 1182 temp = GMPy_Integer_AsUnsignedLongAndError(other, &error); 1183 if (!error) { 1184 res = mpz_divisible_ui_p(MPZ(self), temp); 1185 if (res) 1186 Py_RETURN_TRUE; 1187 else 1188 Py_RETURN_FALSE; 1189 } 1190 1191 if (!(tempd = GMPy_MPZ_From_Integer(other, NULL))) { 1192 TYPE_ERROR("is_divisible() requires integer argument"); 1193 return NULL; 1194 } 1195 1196 res = mpz_divisible_p(MPZ(self), tempd->z); 1197 Py_DECREF((PyObject*)tempd); 1198 if (res) 1199 Py_RETURN_TRUE; 1200 else 1201 Py_RETURN_FALSE; 1202 } 1203 1204 PyDoc_STRVAR(GMPy_doc_mpz_function_is_congruent, 1205 "is_congruent(x, y, m) -> bool\n\n" 1206 "Returns True if x is congruent to y modulo m, else return False."); 1207 1208 static PyObject * 1209 GMPy_MPZ_Function_IsCongruent(PyObject *self, PyObject *args) 1210 { 1211 int res; 1212 MPZ_Object *tempx = NULL, *tempy = NULL, *tempm = NULL; 1213 1214 if (PyTuple_GET_SIZE(args) != 3) { 1215 TYPE_ERROR("is_congruent() requires 3 integer arguments"); 1216 return NULL; 1217 } 1218 1219 if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL)) || 1220 !(tempy = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL)) || 1221 !(tempm = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 2), NULL))) { 1222 1223 Py_XDECREF((PyObject*)tempx); 1224 Py_XDECREF((PyObject*)tempy); 1225 Py_XDECREF((PyObject*)tempm); 1226 TYPE_ERROR("is_congruent() requires 3 integer arguments"); 1227 return NULL; 1228 } 1229 1230 res = mpz_congruent_p(tempx->z, tempy->z, tempm->z); 1231 Py_DECREF((PyObject*)tempx); 1232 Py_DECREF((PyObject*)tempy); 1233 Py_DECREF((PyObject*)tempm); 1234 if (res) 1235 Py_RETURN_TRUE; 1236 else 1237 Py_RETURN_FALSE; 1238 } 1239 1240 PyDoc_STRVAR(GMPy_doc_mpz_method_is_congruent, 1241 "x.is_congruent(y, m) -> bool\n\n" 1242 "Returns True if x is congruent to y modulo m, else return False."); 1243 1244 static PyObject * 1245 GMPy_MPZ_Method_IsCongruent(PyObject *self, PyObject *args) 1246 { 1247 int res; 1248 MPZ_Object *tempy = NULL, *tempm = NULL; 1249 1250 if (PyTuple_GET_SIZE(args) != 2) { 1251 TYPE_ERROR("is_congruent() requires 2 integer arguments"); 1252 return NULL; 1253 } 1254 1255 if (!(tempy = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL)) || 1256 !(tempm = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL))) { 1257 1258 Py_XDECREF((PyObject*)tempy); 1259 Py_XDECREF((PyObject*)tempm); 1260 TYPE_ERROR("is_congruent() requires 2 integer arguments"); 1261 return NULL; 1262 } 1263 1264 res = mpz_congruent_p(MPZ(self), tempy->z, tempm->z); 1265 Py_DECREF((PyObject*)tempy); 1266 Py_DECREF((PyObject*)tempm); 1267 if (res) 1268 Py_RETURN_TRUE; 1269 else 1270 Py_RETURN_FALSE; 1271 } 1272 1273 PyDoc_STRVAR(GMPy_doc_mpz_function_is_power, 1274 "is_power(x) -> bool\n\n" 1275 "Return True if x is a perfect power (there exists a y and an\n" 1276 "n > 1, such that x=y**n), else return False."); 1277 1278 static PyObject * 1279 GMPy_MPZ_Function_IsPower(PyObject *self, PyObject *other) 1280 { 1281 int res; 1282 MPZ_Object* tempx; 1283 1284 if (MPZ_Check(other)) { 1285 res = mpz_perfect_power_p(MPZ(other)); 1286 } 1287 else { 1288 if (!(tempx = GMPy_MPZ_From_Integer(other, NULL))) { 1289 TYPE_ERROR("is_power() requires 'mpz' argument"); 1290 return NULL; 1291 } 1292 else { 1293 res = mpz_perfect_power_p(tempx->z); 1294 Py_DECREF((PyObject*)tempx); 1295 } 1296 } 1297 1298 if (res) 1299 Py_RETURN_TRUE; 1300 else 1301 Py_RETURN_FALSE; 1302 } 1303 1304 PyDoc_STRVAR(GMPy_doc_mpz_method_is_power, 1305 "x.is_power() -> bool\n\n" 1306 "Return True if x is a perfect power (there exists a y and an\n" 1307 "n > 1, such that x=y**n), else return False."); 1308 1309 static PyObject * 1310 GMPy_MPZ_Method_IsPower(PyObject *self, PyObject *other) 1311 { 1312 int res; 1313 1314 res = mpz_perfect_power_p(MPZ(self)); 1315 1316 if (res) 1317 Py_RETURN_TRUE; 1318 else 1319 Py_RETURN_FALSE; 1320 } 1321 1322 PyDoc_STRVAR(GMPy_doc_mpz_function_is_prime, 1323 "is_prime(x[, n=25]) -> bool\n\n" 1324 "Return True if x is _probably_ prime, else False if x is\n" 1325 "definitely composite. x is checked for small divisors and up\n" 1326 "to n Miller-Rabin tests are performed."); 1327 1328 static PyObject * 1329 GMPy_MPZ_Function_IsPrime(PyObject *self, PyObject *args) 1330 { 1331 int i; 1332 unsigned long reps = 25; 1333 MPZ_Object* tempx; 1334 Py_ssize_t argc; 1335 1336 argc = PyTuple_GET_SIZE(args); 1337 1338 if (argc == 0 || argc > 2) { 1339 TYPE_ERROR("is_prime() requires 'mpz'[,'int'] arguments"); 1340 return NULL; 1341 } 1342 1343 if (PyTuple_GET_SIZE(args) == 2) { 1344 reps = c_ulong_From_Integer(PyTuple_GET_ITEM(args, 1)); 1345 if (reps == (unsigned long)(-1) && PyErr_Occurred()) { 1346 return NULL; 1347 } 1348 /* Silently limit n to a reasonable value. */ 1349 if (reps > 1000) { 1350 reps = 1000; 1351 } 1352 } 1353 1354 if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) { 1355 return NULL; 1356 } 1357 1358 i = mpz_probab_prime_p(tempx->z, (int)reps); 1359 Py_DECREF((PyObject*)tempx); 1360 1361 if (i) 1362 Py_RETURN_TRUE; 1363 else 1364 Py_RETURN_FALSE; 1365 } 1366 1367 PyDoc_STRVAR(GMPy_doc_mpz_method_is_prime, 1368 "x.is_prime([n=25]) -> bool\n\n" 1369 "Return True if x is _probably_ prime, else False if x is\n" 1370 "definitely composite. x is checked for small divisors and up\n" 1371 "to n Miller-Rabin tests are performed."); 1372 1373 static PyObject * 1374 GMPy_MPZ_Method_IsPrime(PyObject *self, PyObject *args) 1375 { 1376 int i; 1377 unsigned long reps = 25; 1378 Py_ssize_t argc; 1379 1380 argc = PyTuple_GET_SIZE(args); 1381 1382 if (argc > 1) { 1383 TYPE_ERROR("is_prime() takes at most 1 argument"); 1384 return NULL; 1385 } 1386 1387 if (PyTuple_GET_SIZE(args) == 1) { 1388 reps = c_ulong_From_Integer(PyTuple_GET_ITEM(args, 0)); 1389 if (reps == (unsigned long)(-1) && PyErr_Occurred()) { 1390 return NULL; 1391 } 1392 /* Silently limit n to a reasonable value. */ 1393 if (reps > 1000) { 1394 reps = 1000; 1395 } 1396 } 1397 1398 i = mpz_probab_prime_p(MPZ(self), (int)reps); 1399 1400 if (i) 1401 Py_RETURN_TRUE; 1402 else 1403 Py_RETURN_FALSE; 1404 } 1405 1406 PyDoc_STRVAR(GMPy_doc_mpz_function_next_prime, 1407 "next_prime(x) -> mpz\n\n" 1408 "Return the next _probable_ prime number > x."); 1409 1410 static PyObject * 1411 GMPy_MPZ_Function_NextPrime(PyObject *self, PyObject *other) 1412 { 1413 MPZ_Object *result; 1414 1415 if(MPZ_Check(other)) { 1416 if(!(result = GMPy_MPZ_New(NULL))) { 1417 /* LCOV_EXCL_START */ 1418 return NULL; 1419 /* LCOV_EXCL_STOP */ 1420 } 1421 mpz_nextprime(result->z, MPZ(other)); 1422 } 1423 else { 1424 if (!(result = GMPy_MPZ_From_Integer(other, NULL))) { 1425 TYPE_ERROR("next_prime() requires 'mpz' argument"); 1426 return NULL; 1427 } 1428 else { 1429 mpz_nextprime(result->z, result->z); 1430 } 1431 } 1432 return (PyObject*)result; 1433 } 1434 1435 PyDoc_STRVAR(GMPy_doc_mpz_function_jacobi, 1436 "jacobi(x, y) -> mpz\n\n" 1437 "Return the Jacobi symbol (x|y). y must be odd and >0."); 1438 1439 static PyObject * 1440 GMPy_MPZ_Function_Jacobi(PyObject *self, PyObject *args) 1441 { 1442 MPZ_Object *tempx = NULL, *tempy = NULL; 1443 long res; 1444 1445 if (PyTuple_GET_SIZE(args) != 2) { 1446 TYPE_ERROR("jacobi() requires 'mpz','mpz' arguments"); 1447 return NULL; 1448 } 1449 1450 if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL)) || 1451 !(tempy = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL))) { 1452 1453 Py_XDECREF((PyObject*)tempx); 1454 Py_XDECREF((PyObject*)tempy); 1455 return NULL; 1456 } 1457 1458 if (mpz_sgn(tempy->z) <= 0 || mpz_even_p(tempy->z)) { 1459 VALUE_ERROR("y must be odd and >0"); 1460 Py_DECREF((PyObject*)tempx); 1461 Py_DECREF((PyObject*)tempy); 1462 return NULL; 1463 } 1464 1465 res = (long)(mpz_jacobi(tempx->z, tempy->z)); 1466 Py_DECREF((PyObject*)tempx); 1467 Py_DECREF((PyObject*)tempy); 1468 return PyIntOrLong_FromLong(res); 1469 } 1470 1471 PyDoc_STRVAR(GMPy_doc_mpz_function_legendre, 1472 "legendre(x, y) -> mpz\n\n" 1473 "Return the Legendre symbol (x|y). y is assumed to be an odd prime."); 1474 1475 static PyObject * 1476 GMPy_MPZ_Function_Legendre(PyObject *self, PyObject *args) 1477 { 1478 MPZ_Object *tempx = NULL, *tempy = NULL; 1479 long res; 1480 1481 if (PyTuple_GET_SIZE(args) != 2) { 1482 TYPE_ERROR("legendre() requires 'mpz','mpz' arguments"); 1483 return NULL; 1484 } 1485 1486 if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL)) || 1487 !(tempy = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL))) { 1488 1489 Py_XDECREF((PyObject*)tempx); 1490 Py_XDECREF((PyObject*)tempy); 1491 return NULL; 1492 } 1493 1494 if (mpz_sgn(tempy->z) <= 0 || mpz_even_p(tempy->z)) { 1495 VALUE_ERROR("y must be odd, prime, and >0"); 1496 Py_DECREF((PyObject*)tempx); 1497 Py_DECREF((PyObject*)tempy); 1498 return NULL; 1499 } 1500 1501 res = (long)(mpz_legendre(tempx->z, tempy->z)); 1502 Py_DECREF((PyObject*)tempx); 1503 Py_DECREF((PyObject*)tempy); 1504 return PyIntOrLong_FromLong(res); 1505 } 1506 1507 PyDoc_STRVAR(GMPy_doc_mpz_function_kronecker, 1508 "kronecker(x, y) -> mpz\n\n" 1509 "Return the Kronecker-Jacobi symbol (x|y)."); 1510 1511 static PyObject * 1512 GMPy_MPZ_Function_Kronecker(PyObject *self, PyObject *args) 1513 { 1514 MPZ_Object *tempx = NULL, *tempy = NULL; 1515 long res; 1516 1517 if (PyTuple_GET_SIZE(args) != 2) { 1518 TYPE_ERROR("kronecker() requires 'mpz','mpz' arguments"); 1519 return NULL; 1520 } 1521 1522 if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL)) || 1523 !(tempy = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL))) { 1524 1525 Py_XDECREF((PyObject*)tempx); 1526 Py_XDECREF((PyObject*)tempy); 1527 return NULL; 1528 } 1529 1530 res = (long)(mpz_kronecker(tempx->z, tempy->z)); 1531 Py_DECREF((PyObject*)tempx); 1532 Py_DECREF((PyObject*)tempy); 1533 return PyIntOrLong_FromLong(res); 1534 } 1535 1536 PyDoc_STRVAR(GMPy_doc_mpz_function_is_even, 1537 "is_even(x) -> bool\n\n" 1538 "Return True if x is even, False otherwise."); 1539 1540 static PyObject * 1541 GMPy_MPZ_Function_IsEven(PyObject *self, PyObject *other) 1542 { 1543 int res; 1544 MPZ_Object *tempx; 1545 1546 if (MPZ_Check(other)) { 1547 res = mpz_even_p(MPZ(other)); 1548 } 1549 else { 1550 if (!(tempx = GMPy_MPZ_From_Integer(other, NULL))) { 1551 TYPE_ERROR("is_even() requires 'mpz' argument"); 1552 return NULL; 1553 } 1554 else { 1555 res = mpz_even_p(tempx->z); 1556 Py_DECREF((PyObject*)tempx); 1557 } 1558 } 1559 1560 if (res) 1561 Py_RETURN_TRUE; 1562 else 1563 Py_RETURN_FALSE; 1564 } 1565 1566 PyDoc_STRVAR(GMPy_doc_mpz_method_is_even, 1567 "x.is_even() -> bool\n\n" 1568 "Return True if x is even, False otherwise."); 1569 1570 static PyObject * 1571 GMPy_MPZ_Method_IsEven(PyObject *self, PyObject *other) 1572 { 1573 int res; 1574 1575 res = mpz_even_p(MPZ(self)); 1576 1577 if (res) 1578 Py_RETURN_TRUE; 1579 else 1580 Py_RETURN_FALSE; 1581 } 1582 1583 PyDoc_STRVAR(GMPy_doc_mpz_function_is_odd, 1584 "is_odd(x) -> bool\n\n" 1585 "Return True if x is odd, False otherwise."); 1586 1587 static PyObject * 1588 GMPy_MPZ_Function_IsOdd(PyObject *self, PyObject *other) 1589 { 1590 int res; 1591 MPZ_Object *tempx; 1592 1593 if (CHECK_MPZANY(other)) { 1594 res = mpz_odd_p(MPZ(other)); 1595 } 1596 else { 1597 if (!(tempx = GMPy_MPZ_From_Integer(other, NULL))) { 1598 TYPE_ERROR("is_odd() requires 'mpz' argument"); 1599 return NULL; 1600 } 1601 else { 1602 res = mpz_odd_p(tempx->z); 1603 Py_DECREF((PyObject*)tempx); 1604 } 1605 } 1606 1607 if (res) 1608 Py_RETURN_TRUE; 1609 else 1610 Py_RETURN_FALSE; 1611 } 1612 1613 PyDoc_STRVAR(GMPy_doc_mpz_method_is_odd, 1614 "x.is_odd() -> bool\n\n" 1615 "Return True if x is odd, False otherwise."); 1616 1617 static PyObject * 1618 GMPy_MPZ_Method_IsOdd(PyObject *self, PyObject *other) 1619 { 1620 int res; 1621 1622 res = mpz_odd_p(MPZ(self)); 1623 1624 if (res) 1625 Py_RETURN_TRUE; 1626 else 1627 Py_RETURN_FALSE; 1628 } 1629 1630 /* 1631 * Add mapping support to mpz objects. 1632 */ 1633 1634 static Py_ssize_t 1635 GMPy_MPZ_Method_Length(MPZ_Object *self) 1636 { 1637 return mpz_sizeinbase(self->z, 2); 1638 } 1639 1640 static PyObject * 1641 GMPy_MPZ_Method_SubScript(MPZ_Object *self, PyObject *item) 1642 { 1643 if (PyIndex_Check(item)) { 1644 Py_ssize_t i; 1645 1646 i = PyIntOrLong_AsSsize_t(item); 1647 if (i == -1 && PyErr_Occurred()) { 1648 INDEX_ERROR("argument too large to convert to an index"); 1649 return NULL; 1650 } 1651 if (i < 0) { 1652 i += mpz_sizeinbase(self->z, 2); 1653 } 1654 return PyIntOrLong_FromLong(mpz_tstbit(self->z, i)); 1655 } 1656 else if (PySlice_Check(item)) { 1657 Py_ssize_t start, stop, step, slicelength, cur, i; 1658 MPZ_Object *result; 1659 1660 #if PY_VERSION_HEX > 0x030200A4 1661 if (PySlice_GetIndicesEx(item, 1662 mpz_sizeinbase(self->z, 2), 1663 &start, &stop, &step, &slicelength) < 0) { 1664 return NULL; 1665 } 1666 #else 1667 if (PySlice_GetIndicesEx((PySliceObject*)item, 1668 mpz_sizeinbase(self->z, 2), 1669 &start, &stop, &step, &slicelength) < 0) { 1670 return NULL; 1671 } 1672 #endif 1673 1674 if ((step < 0 && start < stop) || (step > 0 && start > stop)) { 1675 stop = start; 1676 } 1677 1678 if (!(result = GMPy_MPZ_New(NULL))) { 1679 return NULL; 1680 } 1681 1682 mpz_set_ui(result->z, 0); 1683 if (slicelength > 0) { 1684 for (cur = start, i = 0; i < slicelength; cur += step, i++) { 1685 if(mpz_tstbit(self->z, cur)) { 1686 mpz_setbit(result->z, i); 1687 } 1688 } 1689 } 1690 return (PyObject*)result; 1691 } 1692 else { 1693 TYPE_ERROR("bit positions must be integers"); 1694 return NULL; 1695 } 1696 } 1697 1698 static PyObject * 1699 GMPy_MPZ_Attrib_GetNumer(MPZ_Object *self, void *closure) 1700 { 1701 Py_INCREF((PyObject*)self); 1702 return (PyObject*)self; 1703 } 1704 1705 static PyObject * 1706 GMPy_MPZ_Attrib_GetReal(MPZ_Object *self, void *closure) 1707 { 1708 Py_INCREF((PyObject*)self); 1709 return (PyObject*)self; 1710 } 1711 1712 static PyObject * 1713 GMPy_MPZ_Attrib_GetDenom(MPZ_Object *self, void *closure) 1714 { 1715 MPZ_Object *result; 1716 1717 if ((result = GMPy_MPZ_New(NULL))) { 1718 mpz_set_ui(result->z, 1); 1719 } 1720 return (PyObject*)result; 1721 } 1722 1723 static PyObject * 1724 GMPy_MPZ_Attrib_GetImag(MPZ_Object *self, void *closure) 1725 { 1726 MPZ_Object *result; 1727 1728 if ((result = GMPy_MPZ_New(NULL))) { 1729 mpz_set_ui(result->z, 0); 1730 } 1731 return (PyObject*)result; 1732 } 1733 1734 PyDoc_STRVAR(GMPy_doc_mpz_method_sizeof, 1735 "x.__sizeof__()\n\n" 1736 "Returns the amount of memory consumed by x. Note: deleted mpz objects\n" 1737 "are reused and may or may not be resized when a new value is assigned."); 1738 1739 static PyObject * 1740 GMPy_MPZ_Method_SizeOf(PyObject *self, PyObject *other) 1741 { 1742 return PyIntOrLong_FromSize_t(sizeof(MPZ_Object) + \ 1743 (MPZ(self)->_mp_alloc * sizeof(mp_limb_t))); 1744 } 1745 1746 /* Note: this particular function is also used for xmpz, mpq, and mpfr. Only 1747 * mpc.conjugate() does more that just return another reference to the original 1748 * object. 1749 */ 1750 1751 PyDoc_STRVAR(GMPy_doc_mp_method_conjugate, 1752 "x.conjugate() -> number\n\n" 1753 "Return the conjugate of x (which is just a new reference to x since x is\n" 1754 "not a complex number)."); 1755 1756 static PyObject * 1757 GMPy_MP_Method_Conjugate(PyObject *self, PyObject *args) 1758 { 1759 Py_INCREF((PyObject*)self); 1760 return (PyObject*)self; 1761 } 1762 1763 1764