gmpy2_mpz_bitops.c
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 2 * gmpy2_mpz_bitops.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 PyDoc_STRVAR(doc_bit_length_method, 28 "x.bit_length() -> int\n\n" 29 "Return the number of significant bits in the radix-2\n" 30 "representation of x. Note: mpz(0).bit_length() returns 0."); 31 32 static PyObject * 33 GMPy_MPZ_bit_length_method(PyObject *self, PyObject *other) 34 { 35 mp_bitcnt_t n = 0; 36 37 if (mpz_size(MPZ(self))) 38 n = mpz_sizeinbase(MPZ(self), 2); 39 40 return PyIntOrLong_FromMpBitCnt(n); 41 } 42 43 PyDoc_STRVAR(doc_bit_length_function, 44 "bit_length(x) -> int\n\n" 45 "Return the number of significant bits in the radix-2\n" 46 "representation of x. Note: bit_length(0) returns 0."); 47 48 static PyObject * 49 GMPy_MPZ_bit_length_function(PyObject *self, PyObject *other) 50 { 51 mp_bitcnt_t n = 0; 52 MPZ_Object* tempx; 53 54 if (!(tempx = GMPy_MPZ_From_Integer(other, NULL))) { 55 TYPE_ERROR("bit_length() requires 'mpz' argument"); 56 return NULL; 57 } 58 if (mpz_size(MPZ(tempx))) 59 n = mpz_sizeinbase(tempx->z, 2); 60 61 Py_DECREF((PyObject*)tempx); 62 return PyIntOrLong_FromMpBitCnt(n); 63 } 64 65 PyDoc_STRVAR(doc_bit_mask, 66 "bit_mask(n) -> mpz\n\n" 67 "Return an 'mpz' exactly n bits in length with all bits set.\n"); 68 69 static PyObject * 70 GMPy_MPZ_bit_mask(PyObject *self, PyObject *other) 71 { 72 mp_bitcnt_t n = 0; 73 MPZ_Object* result; 74 75 n = mp_bitcnt_t_From_Integer(other); 76 if (n == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { 77 return NULL; 78 } 79 80 if (!(result = GMPy_MPZ_New(NULL))) 81 return NULL; 82 83 mpz_set_ui(result->z, 1); 84 mpz_mul_2exp(result->z, result->z, n); 85 mpz_sub_ui(result->z, result->z, 1); 86 87 return (PyObject*)result; 88 } 89 90 /* return scan0/scan1 for an mpz */ 91 PyDoc_STRVAR(doc_bit_scan0_method, 92 "x.bit_scan0(n=0) -> int\n\n" 93 "Return the index of the first 0-bit of x with index >= n. n >= 0.\n" 94 "If there are no more 0-bits in x at or above index n (which can\n" 95 "only happen for x<0, assuming an infinitely long 2's complement\n" 96 "format), then None is returned."); 97 98 static PyObject * 99 GMPy_MPZ_bit_scan0_method(PyObject *self, PyObject *args) 100 { 101 mp_bitcnt_t index, starting_bit = 0; 102 103 if (PyTuple_GET_SIZE(args) == 1) { 104 starting_bit = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 0)); 105 if (starting_bit == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { 106 return NULL; 107 } 108 } 109 110 index = mpz_scan0(MPZ(self), starting_bit); 111 112 if (index == (mp_bitcnt_t)(-1)) { 113 Py_RETURN_NONE; 114 } 115 else { 116 return PyIntOrLong_FromMpBitCnt(index); 117 } 118 } 119 120 PyDoc_STRVAR(doc_bit_scan0_function, 121 "bit_scan0(x, n=0) -> int\n\n" 122 "Return the index of the first 0-bit of x with index >= n. n >= 0.\n" 123 "If there are no more 0-bits in x at or above index n (which can\n" 124 "only happen for x<0, assuming an infinitely long 2's complement\n" 125 "format), then None is returned."); 126 127 static PyObject * 128 GMPy_MPZ_bit_scan0_function(PyObject *self, PyObject *args) 129 { 130 mp_bitcnt_t index, starting_bit = 0; 131 MPZ_Object *tempx = NULL; 132 133 if (PyTuple_GET_SIZE(args) == 0 || PyTuple_GET_SIZE(args) > 2) { 134 goto err; 135 } 136 137 if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) { 138 goto err; 139 } 140 141 if (PyTuple_GET_SIZE(args) == 2) { 142 starting_bit = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1)); 143 if (starting_bit == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { 144 goto err_index; 145 } 146 } 147 148 index = mpz_scan0(tempx->z, starting_bit); 149 150 Py_DECREF((PyObject*)tempx); 151 if (index == (mp_bitcnt_t)(-1)) { 152 Py_RETURN_NONE; 153 } 154 else { 155 return PyIntOrLong_FromMpBitCnt(index); 156 } 157 158 err: 159 TYPE_ERROR("bit_scan0() requires 'mpz',['int'] arguments"); 160 err_index: 161 Py_XDECREF((PyObject*)tempx); 162 return NULL; 163 } 164 165 PyDoc_STRVAR(doc_bit_scan1_method, 166 "x.bit_scan1(n=0) -> int\n\n" 167 "Return the index of the first 1-bit of x with index >= n. n >= 0.\n" 168 "If there are no more 1-bits in x at or above index n (which can\n" 169 "only happen for x>=0, assuming an infinitely long 2's complement\n" 170 "format), then None is returned."); 171 172 static PyObject * 173 GMPy_MPZ_bit_scan1_method(PyObject *self, PyObject *args) 174 { 175 mp_bitcnt_t index, starting_bit = 0; 176 177 if (PyTuple_GET_SIZE(args) == 1) { 178 starting_bit = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 0)); 179 if (starting_bit == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { 180 return NULL; 181 } 182 } 183 184 index = mpz_scan1(MPZ(self), starting_bit); 185 186 if (index == (mp_bitcnt_t)(-1)) { 187 Py_RETURN_NONE; 188 } 189 else { 190 return PyIntOrLong_FromMpBitCnt(index); 191 } 192 } 193 194 PyDoc_STRVAR(doc_bit_scan1_function, 195 "bit_scan1(x, n=0) -> int\n\n" 196 "Return the index of the first 1-bit of x with index >= n. n >= 0.\n" 197 "If there are no more 1-bits in x at or above index n (which can\n" 198 "only happen for x>=0, assuming an infinitely long 2's complement\n" 199 "format), then None is returned."); 200 201 static PyObject * 202 GMPy_MPZ_bit_scan1_function(PyObject *self, PyObject *args) 203 { 204 mp_bitcnt_t index, starting_bit = 0; 205 MPZ_Object *tempx = NULL; 206 207 if (PyTuple_GET_SIZE(args) == 0 || PyTuple_GET_SIZE(args) > 2) { 208 goto err; 209 } 210 211 if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) { 212 goto err; 213 } 214 215 if (PyTuple_GET_SIZE(args) == 2) { 216 starting_bit = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1)); 217 if (starting_bit == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { 218 goto err_index; 219 } 220 } 221 222 index = mpz_scan1(tempx->z, starting_bit); 223 224 Py_DECREF((PyObject*)tempx); 225 if (index == (mp_bitcnt_t)(-1)) { 226 Py_RETURN_NONE; 227 } 228 else { 229 return PyIntOrLong_FromMpBitCnt(index); 230 } 231 232 err: 233 TYPE_ERROR("bit_scan1() requires 'mpz',['int'] arguments"); 234 err_index: 235 Py_XDECREF((PyObject*)tempx); 236 return NULL; 237 } 238 239 /* get & return one bit from an mpz */ 240 PyDoc_STRVAR(doc_bit_test_function, 241 "bit_test(x, n) -> bool\n\n" 242 "Return the value of the n-th bit of x."); 243 244 static PyObject * 245 GMPy_MPZ_bit_test_function(PyObject *self, PyObject *args) 246 { 247 mp_bitcnt_t bit_index; 248 int temp; 249 MPZ_Object *tempx = NULL; 250 251 if (PyTuple_GET_SIZE(args) != 2) { 252 goto err; 253 } 254 255 if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) { 256 goto err; 257 } 258 259 bit_index = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1)); 260 if (bit_index == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { 261 goto err_index; 262 } 263 264 temp = mpz_tstbit(tempx->z, bit_index); 265 Py_DECREF((PyObject*)tempx); 266 267 if (temp) 268 Py_RETURN_TRUE; 269 else 270 Py_RETURN_FALSE; 271 272 err: 273 TYPE_ERROR("bit_test() requires 'mpz','int' arguments"); 274 err_index: 275 Py_XDECREF((PyObject*)tempx); 276 return NULL; 277 } 278 279 PyDoc_STRVAR(doc_bit_test_method, 280 "x.bit_test(n) -> bool\n\n" 281 "Return the value of the n-th bit of x."); 282 283 static PyObject * 284 GMPy_MPZ_bit_test_method(PyObject *self, PyObject *other) 285 { 286 mp_bitcnt_t bit_index; 287 288 bit_index = mp_bitcnt_t_From_Integer(other); 289 if (bit_index == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { 290 return NULL; 291 } 292 293 if (mpz_tstbit(MPZ(self), bit_index)) 294 Py_RETURN_TRUE; 295 else 296 Py_RETURN_FALSE; 297 } 298 299 PyDoc_STRVAR(doc_bit_clear_function, 300 "bit_clear(x, n) -> mpz\n\n" 301 "Return a copy of x with the n-th bit cleared."); 302 303 static PyObject * 304 GMPy_MPZ_bit_clear_function(PyObject *self, PyObject *args) 305 { 306 mp_bitcnt_t bit_index; 307 MPZ_Object *result = NULL, *tempx = NULL; 308 309 if (PyTuple_GET_SIZE(args) != 2) 310 goto err; 311 312 if (!(result = GMPy_MPZ_New(NULL))) 313 return NULL; 314 315 if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) 316 goto err; 317 318 bit_index = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1)); 319 if (bit_index == (mp_bitcnt_t)(-1) && PyErr_Occurred()) 320 goto err_index; 321 322 mpz_set(result->z, tempx->z); 323 mpz_clrbit(result->z, bit_index); 324 325 Py_DECREF((PyObject*)tempx); 326 return (PyObject*)result; 327 328 err: 329 TYPE_ERROR("bit_clear() requires 'mpz','int' arguments"); 330 err_index: 331 Py_XDECREF((PyObject*)result); 332 Py_XDECREF((PyObject*)tempx); 333 return NULL; 334 } 335 336 PyDoc_STRVAR(doc_bit_clear_method, 337 "x.bit_clear(n) -> mpz\n\n" 338 "Return a copy of x with the n-th bit cleared."); 339 340 static PyObject * 341 GMPy_MPZ_bit_clear_method(PyObject *self, PyObject *other) 342 { 343 mp_bitcnt_t bit_index; 344 MPZ_Object *result = NULL; 345 346 if (!(result = GMPy_MPZ_New(NULL))) 347 return NULL; 348 349 bit_index = mp_bitcnt_t_From_Integer(other); 350 if (bit_index == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { 351 Py_DECREF(result); 352 return NULL; 353 } 354 355 mpz_set(result->z, MPZ(self)); 356 mpz_clrbit(result->z, bit_index); 357 return (PyObject*)result; 358 } 359 360 PyDoc_STRVAR(doc_bit_set_function, 361 "bit_set(x, n) -> mpz\n\n" 362 "Return a copy of x with the n-th bit set."); 363 364 static PyObject * 365 GMPy_MPZ_bit_set_function(PyObject *self, PyObject *args) 366 { 367 mp_bitcnt_t bit_index; 368 MPZ_Object *result = NULL, *tempx = NULL; 369 370 if (PyTuple_GET_SIZE(args) != 2) 371 goto err; 372 373 if (!(result = GMPy_MPZ_New(NULL))) 374 return NULL; 375 376 if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) 377 goto err; 378 379 bit_index = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1)); 380 if (bit_index == (mp_bitcnt_t)(-1) && PyErr_Occurred()) 381 goto err_index; 382 383 mpz_set(result->z, tempx->z); 384 mpz_setbit(result->z, bit_index); 385 386 Py_DECREF((PyObject*)tempx); 387 return (PyObject*)result; 388 389 err: 390 TYPE_ERROR("bit_set() requires 'mpz','int' arguments"); 391 err_index: 392 Py_XDECREF((PyObject*)result); 393 Py_XDECREF((PyObject*)tempx); 394 return NULL; 395 } 396 397 PyDoc_STRVAR(doc_bit_set_method, 398 "x.bit_set(n) -> mpz\n\n" 399 "Return a copy of x with the n-th bit set."); 400 401 static PyObject * 402 GMPy_MPZ_bit_set_method(PyObject *self, PyObject *other) 403 { 404 mp_bitcnt_t bit_index; 405 MPZ_Object *result = NULL; 406 407 if (!(result = GMPy_MPZ_New(NULL))) 408 return NULL; 409 410 bit_index = mp_bitcnt_t_From_Integer(other); 411 if (bit_index == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { 412 Py_DECREF(result); 413 return NULL; 414 } 415 416 mpz_set(result->z, MPZ(self)); 417 mpz_setbit(result->z, bit_index); 418 return (PyObject*)result; 419 } 420 421 PyDoc_STRVAR(doc_bit_flip_function, 422 "bit_flip(x, n) -> mpz\n\n" 423 "Return a copy of x with the n-th bit inverted."); 424 425 static PyObject * 426 GMPy_MPZ_bit_flip_function(PyObject *self, PyObject *args) 427 { 428 mp_bitcnt_t bit_index; 429 MPZ_Object *result = NULL, *tempx = NULL; 430 431 if (PyTuple_GET_SIZE(args) != 2) 432 goto err; 433 434 if (!(result = GMPy_MPZ_New(NULL))) 435 return NULL; 436 437 if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) 438 goto err; 439 440 bit_index = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1)); 441 if (bit_index == (mp_bitcnt_t)(-1) && PyErr_Occurred()) 442 goto err_index; 443 444 mpz_set(result->z, tempx->z); 445 mpz_combit(result->z, bit_index); 446 447 Py_DECREF((PyObject*)tempx); 448 return (PyObject*)result; 449 450 err: 451 TYPE_ERROR("bit_flip() requires 'mpz','int' arguments"); 452 err_index: 453 Py_XDECREF((PyObject*)result); 454 Py_XDECREF((PyObject*)tempx); 455 return NULL; 456 } 457 458 PyDoc_STRVAR(doc_bit_flip_method, 459 "x.bit_flip(n) -> mpz\n\n" 460 "Return a copy of x with the n-th bit inverted."); 461 462 static PyObject * 463 GMPy_MPZ_bit_flip_method(PyObject *self, PyObject *other) 464 { 465 mp_bitcnt_t bit_index; 466 MPZ_Object *result = NULL; 467 468 if (!(result = GMPy_MPZ_New(NULL))) 469 return NULL; 470 471 bit_index = mp_bitcnt_t_From_Integer(other); 472 if (bit_index == (mp_bitcnt_t)(-1) && PyErr_Occurred()) { 473 Py_DECREF(result); 474 return NULL; 475 } 476 477 mpz_set(result->z, MPZ(self)); 478 mpz_combit(result->z, bit_index); 479 return (PyObject*)result; 480 } 481 482 static PyObject * 483 GMPy_MPZ_Invert_Slot(MPZ_Object *self) 484 { 485 MPZ_Object *result; 486 487 if ((result = GMPy_MPZ_New(NULL))) 488 mpz_com(result->z, MPZ(self)); 489 490 return (PyObject*)result; 491 } 492 493 static PyObject * 494 GMPy_MPZ_And_Slot(PyObject *self, PyObject *other) 495 { 496 MPZ_Object *result; 497 498 if (CHECK_MPZANY(self)) { 499 if (CHECK_MPZANY(other)) { 500 if (!(result = GMPy_MPZ_New(NULL))) 501 return NULL; 502 mpz_and(result->z, MPZ(self), MPZ(other)); 503 } 504 else { 505 if (!(result = GMPy_MPZ_From_Integer(other, NULL))) 506 return NULL; 507 mpz_and(result->z, MPZ(self), result->z); 508 } 509 } 510 else if (CHECK_MPZANY(other)) { 511 if (!(result = GMPy_MPZ_From_Integer(self, NULL))) 512 return NULL; 513 mpz_and(result->z, result->z, MPZ(other)); 514 } 515 else { 516 Py_RETURN_NOTIMPLEMENTED; 517 } 518 return (PyObject*)result; 519 } 520 521 static PyObject * 522 GMPy_MPZ_Ior_Slot(PyObject *self, PyObject *other) 523 { 524 MPZ_Object *result; 525 526 if (CHECK_MPZANY(self)) { 527 if (CHECK_MPZANY(other)) { 528 if (!(result = GMPy_MPZ_New(NULL))) 529 return NULL; 530 mpz_ior(result->z, MPZ(self), MPZ(other)); 531 } 532 else { 533 if (!(result = GMPy_MPZ_From_Integer(other, NULL))) 534 return NULL; 535 mpz_ior(result->z, MPZ(self), result->z); 536 } 537 } 538 else if (CHECK_MPZANY(other)) { 539 if (!(result = GMPy_MPZ_From_Integer(self, NULL))) 540 return NULL; 541 mpz_ior(result->z, result->z, MPZ(other)); 542 } 543 else { 544 Py_RETURN_NOTIMPLEMENTED; 545 } 546 return (PyObject*)result; 547 } 548 549 static PyObject * 550 GMPy_MPZ_Xor_Slot(PyObject *self, PyObject *other) 551 { 552 MPZ_Object *result; 553 554 if (CHECK_MPZANY(self)) { 555 if (CHECK_MPZANY(other)) { 556 if (!(result = GMPy_MPZ_New(NULL))) 557 return NULL; 558 mpz_xor(result->z, MPZ(self), MPZ(other)); 559 } 560 else { 561 if (!(result = GMPy_MPZ_From_Integer(other, NULL))) 562 return NULL; 563 mpz_xor(result->z, MPZ(self), result->z); 564 } 565 } 566 else if (CHECK_MPZANY(other)) { 567 if (!(result = GMPy_MPZ_From_Integer(self, NULL))) 568 return NULL; 569 mpz_xor(result->z, result->z, MPZ(other)); 570 } 571 else { 572 Py_RETURN_NOTIMPLEMENTED; 573 } 574 return (PyObject*)result; 575 } 576 577 static PyObject * 578 GMPy_MPZ_Rshift_Slot(PyObject *self, PyObject *other) 579 { 580 mp_bitcnt_t count; 581 MPZ_Object *result, *tempx; 582 583 count = mp_bitcnt_t_From_Integer(other); 584 if ((count == (mp_bitcnt_t)(-1)) && PyErr_Occurred()) 585 return NULL; 586 587 if (!(result = GMPy_MPZ_New(NULL))) 588 return NULL; 589 590 if (CHECK_MPZANY(self)) { 591 mpz_fdiv_q_2exp(result->z, MPZ(self), count); 592 return (PyObject*)result; 593 } 594 else { 595 if (!(tempx = GMPy_MPZ_From_Integer(self, NULL))) { 596 Py_XDECREF((PyObject*)result); 597 Py_XDECREF((PyObject*)tempx); 598 return NULL; 599 } 600 601 mpz_fdiv_q_2exp(result->z, tempx->z, count); 602 Py_DECREF((PyObject*)tempx); 603 return (PyObject*)result; 604 } 605 } 606 607 static PyObject * 608 GMPy_MPZ_Lshift_Slot(PyObject *self, PyObject *other) 609 { 610 mp_bitcnt_t count; 611 MPZ_Object *result, *tempx; 612 613 count = mp_bitcnt_t_From_Integer(other); 614 if ((count == (mp_bitcnt_t)(-1)) && PyErr_Occurred()) 615 return NULL; 616 617 if (!(result = GMPy_MPZ_New(NULL))) 618 return NULL; 619 620 if (CHECK_MPZANY(self)) { 621 mpz_mul_2exp(result->z, MPZ(self), count); 622 return (PyObject*)result; 623 } 624 else { 625 if (!(tempx = GMPy_MPZ_From_Integer(self, NULL))) { 626 Py_XDECREF((PyObject*)result); 627 Py_XDECREF((PyObject*)tempx); 628 return NULL; 629 } 630 631 mpz_mul_2exp(result->z, tempx->z, count); 632 Py_DECREF((PyObject*)tempx); 633 return (PyObject*)result; 634 } 635 } 636 637 PyDoc_STRVAR(doc_popcount, 638 "popcount(x) -> int\n\n" 639 "Return the number of 1-bits set in x. If x<0, the number of\n" 640 "1-bits is infinite so -1 is returned in that case."); 641 642 static PyObject * 643 GMPy_MPZ_popcount(PyObject *self, PyObject *other) 644 { 645 mp_bitcnt_t n; 646 MPZ_Object *tempx; 647 648 if ((tempx = GMPy_MPZ_From_Integer(other, NULL))) { 649 n = mpz_popcount(tempx->z); 650 Py_DECREF((PyObject*)tempx); 651 if (n == (mp_bitcnt_t)(-1)) 652 return PyLong_FromLong(-1); 653 else 654 return PyIntOrLong_FromMpBitCnt(n); 655 } 656 else { 657 TYPE_ERROR("popcount() requires 'mpz' argument"); 658 return NULL; 659 } 660 } 661 662 PyDoc_STRVAR(doc_hamdist, 663 "hamdist(x, y) -> int\n\n" 664 "Return the Hamming distance (number of bit-positions where the\n" 665 "bits differ) between integers x and y."); 666 667 static PyObject * 668 GMPy_MPZ_hamdist(PyObject *self, PyObject *args) 669 { 670 PyObject *result = NULL; 671 MPZ_Object *tempx = NULL, *tempy = NULL; 672 673 if (PyTuple_GET_SIZE(args) != 2) 674 goto err; 675 676 tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL); 677 tempy = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 1), NULL); 678 if (!tempx || !tempy) 679 goto err; 680 681 result = PyIntOrLong_FromMpBitCnt(mpz_hamdist(tempx->z, tempy->z)); 682 Py_DECREF((PyObject*)tempx); 683 Py_DECREF((PyObject*)tempy); 684 return result; 685 686 err: 687 TYPE_ERROR("hamdist() requires 'mpz','mpz' arguments"); 688 Py_XDECREF((PyObject*)tempx); 689 Py_XDECREF((PyObject*)tempy); 690 return NULL; 691 } 692