/src/gmpy_mpc.c
C | 1524 lines | 1257 code | 214 blank | 53 comment | 266 complexity | 2bde16ee68b87b3c0c9412e47ea69797 MD5 | raw file
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 2 * gmpy_mpc.c * 3 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 4 * Python interface to the GMP or MPIR, MPFR, and MPC multiple precision * 5 * libraries. * 6 * * 7 * Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, * 8 * 2008, 2009 Alex Martelli * 9 * * 10 * Copyright 2008, 2009, 2010, 2011, 2012, 2013 Case Van Horsen * 11 * * 12 * This file is part of GMPY2. * 13 * * 14 * GMPY2 is free software: you can redistribute it and/or modify it under * 15 * the terms of the GNU Lesser General Public License as published by the * 16 * Free Software Foundation, either version 3 of the License, or (at your * 17 * option) any later version. * 18 * * 19 * GMPY2 is distributed in the hope that it will be useful, but WITHOUT * 20 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * 21 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * 22 * License for more details. * 23 * * 24 * You should have received a copy of the GNU Lesser General Public * 25 * License along with GMPY2; if not, see <http://www.gnu.org/licenses/> * 26 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 27 28PyDoc_STRVAR(doc_mpc_digits, 29"c.digits(base=10, prec=0) -> ((mant, exp, prec), (mant, exp, prec))\n\n" 30"Returns up to 'prec' digits in the given base. If 'prec' is 0, as many\n" 31"digits that are available given c's precision are returned. 'base' must\n" 32"be between 2 and 62. The result consists of 2 three-element tuples that\n" 33"contain the mantissa, exponent, and number of bits of precision of the\n" 34"real and imaginary components."); 35 36/* TODO: support keyword arguments. */ 37 38static PyObject * 39Pympc_digits(PyObject *self, PyObject *args) 40{ 41 int base = 10; 42 int prec = 0; 43 PyObject *result; 44 45 if (self && Pympc_Check(self)) { 46 if (!PyArg_ParseTuple(args, "|ii", &base, &prec)) 47 return NULL; 48 Py_INCREF(self); 49 } 50 else { 51 if(!PyArg_ParseTuple(args, "O&|ii", Pympc_convert_arg, &self, 52 &base, &prec)) 53 return NULL; 54 } 55 result = Pympc_To_PyStr((PympcObject*)self, base, prec); 56 Py_DECREF(self); 57 return result; 58} 59 60PyDoc_STRVAR(doc_g_mpc, 61"mpc() -> mpc(0.0+0.0j)\n\n" 62" If no argument is given, return mpc(0.0+0.0j).\n\n" 63"mpc(c[, precision=0]) -> mpc\n\n" 64" Return a new 'mpc' object from an existing complex number\n" 65" (either a Python complex object or another 'mpc' object). If\n" 66" the precision is not specified, then the precision is taken\n" 67" from the current context. The rounding mode is always taken\n" 68" from the current context.\n\n" 69"mpc(r[, i=0[, precision=0]]) -> mpc\n\n" 70" Return a new 'mpc' object by converting two non-complex numbers\n" 71" into the real and imaginary components of an 'mpc' object. If\n" 72" the precision is not specified, then the precision is taken from\n" 73" the current context. The rounding mode is always taken from the\n" 74" current context.\n\n" 75"mpc(s[, [precision=0[, base=10]]) -> mpc\n\n" 76" Return a new 'mpc' object by converting a string s into a complex\n" 77" number. If base is omitted, then a base-10 representation is\n" 78" assumed otherwise a base between 2 and 36 can be specified. If\n" 79" the precision is not specified, then the precision is taken from\n" 80" the current context. The rounding mode is always taken from the\n" 81" current context.\n\n" 82"Note: The precision can be specified either a single number that\n" 83" is used for both the real and imaginary components, or as a\n" 84" tuple that can specify different precisions for the real\n" 85" and imaginary components."); 86 87static PyObject * 88Pygmpy_mpc(PyObject *self, PyObject *args, PyObject *kwargs) 89{ 90 PympcObject *result = NULL; 91 PympfrObject *tempreal = NULL, *tempimag = NULL; 92 PyObject *arg0 = NULL, *arg1 = NULL, *prec = NULL; 93 int base = 10; 94 /* Assumes mpfr_prec_t is the same as a long. */ 95 mpfr_prec_t rbits = 0, ibits = 0; 96 Py_ssize_t argc; 97 static char *kwlist_c[] = {"c", "precision", NULL}; 98 static char *kwlist_r[] = {"r", "i", "precision", NULL}; 99 static char *kwlist_s[] = {"s", "precision", "base", NULL}; 100 101 argc = PyTuple_Size(args); 102 103 if (argc == 0) { 104 if ((result = (PympcObject*)Pympc_new(0,0))) { 105 mpc_set_ui(result->c, 0, GET_MPC_ROUND(context)); 106 } 107 return (PyObject*)result; 108 } 109 110 arg0 = PyTuple_GetItem(args, 0); 111 if (PyStrOrUnicode_Check(arg0)) { 112 /* First argument is a string */ 113 114 if (!(PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi", kwlist_s, 115 &arg0, &prec, &base))) 116 return NULL; 117 118 if (prec) { 119 if (PyIntOrLong_Check(prec)) { 120 rbits = (mpfr_prec_t)PyIntOrLong_AsLong(prec); 121 ibits = rbits; 122 } 123 else if (PyTuple_Check(prec) && PyTuple_Size(prec) == 2) { 124 rbits = (mpfr_prec_t)PyIntOrLong_AsLong(PyTuple_GetItem(prec, 0)); 125 ibits = (mpfr_prec_t)PyIntOrLong_AsLong(PyTuple_GetItem(prec, 1)); 126 } 127 if (PyErr_Occurred()) { 128 VALUE_ERROR("invalid value for precision in gmpy2.mpc()."); 129 return NULL; 130 } 131 } 132 133 if (base < 2 || base > 36) { 134 VALUE_ERROR("base for mpc() must be in the interval 2 ... 36."); 135 return NULL; 136 } 137 138 result = Pympc_From_PyStr(arg0, base, rbits, ibits); 139 } 140 else if (PyComplex_Check(arg0) || Pympc_Check(arg0)) { 141 /* First argument is a complex number */ 142 143 if (!(PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", kwlist_c, 144 &arg0, &prec))) 145 return NULL; 146 147 if (prec) { 148 if (PyIntOrLong_Check(prec)) { 149 rbits = (mpfr_prec_t)PyIntOrLong_AsLong(prec); 150 ibits = rbits; 151 } 152 else if (PyTuple_Check(prec) && PyTuple_Size(prec) == 2) { 153 rbits = (mpfr_prec_t)PyIntOrLong_AsLong(PyTuple_GetItem(prec, 0)); 154 ibits = (mpfr_prec_t)PyIntOrLong_AsLong(PyTuple_GetItem(prec, 1)); 155 } 156 if (PyErr_Occurred()) { 157 VALUE_ERROR("invalid value for precision in mpc()."); 158 return NULL; 159 } 160 } 161 162 if (PyComplex_Check(arg0)) { 163 result = Pympc_From_PyComplex(arg0, rbits, ibits); 164 } 165 else { 166 result = Pympc_From_Pympc(arg0, rbits, ibits); 167 } 168 } 169 else if (isReal(arg0)) { 170 /* First argument is a real number */ 171 172 if (!(PyArg_ParseTupleAndKeywords(args, kwargs, "O|OO", kwlist_r, 173 &arg0, &arg1, &prec))) 174 return NULL; 175 176 if (prec) { 177 if (PyIntOrLong_Check(prec)) { 178 rbits = (mpfr_prec_t)PyIntOrLong_AsLong(prec); 179 ibits = rbits; 180 } 181 else if (PyTuple_Check(prec) && PyTuple_Size(prec) == 2) { 182 rbits = (mpfr_prec_t)PyIntOrLong_AsLong(PyTuple_GetItem(prec, 0)); 183 ibits = (mpfr_prec_t)PyIntOrLong_AsLong(PyTuple_GetItem(prec, 1)); 184 } 185 if (PyErr_Occurred()) { 186 VALUE_ERROR("invalid value for precision in mpc()."); 187 return NULL; 188 } 189 } 190 191 if (arg1 && !isReal(arg1)) { 192 TYPE_ERROR("invalid type for imaginary component in mpc()"); 193 return NULL; 194 } 195 196 if (arg0) { 197 tempreal = Pympfr_From_Real(arg0, rbits); 198 } 199 else { 200 if ((tempreal = (PympfrObject*)Pympfr_new(rbits))) { 201 mpfr_set_ui(Pympfr_AS_MPFR(tempreal), 0, context->ctx.mpfr_round); 202 } 203 } 204 205 if (arg1) { 206 tempimag = Pympfr_From_Real(arg1, ibits); 207 } 208 else { 209 if ((tempimag = (PympfrObject*)Pympfr_new(ibits))) { 210 mpfr_set_ui(Pympfr_AS_MPFR(tempimag), 0, context->ctx.mpfr_round); 211 } 212 } 213 214 result = (PympcObject*)Pympc_new(rbits, ibits); 215 if (!tempreal || !tempimag || !result) { 216 Py_XDECREF(tempreal); 217 Py_XDECREF(tempimag); 218 Py_XDECREF(result); 219 TYPE_ERROR("mpc() requires string or numeric argument."); 220 return NULL; 221 } 222 223 mpc_set_fr_fr(Pympc_AS_MPC(result), Pympfr_AS_MPFR(tempreal), 224 Pympfr_AS_MPFR(tempimag), GET_MPC_ROUND(context)); 225 Py_DECREF(tempreal); 226 Py_DECREF(tempimag); 227 } 228 else { 229 TYPE_ERROR("mpc() requires numeric or string argument"); 230 } 231 232 return (PyObject*)result; 233} 234 235PyDoc_STRVAR(doc_mpc_format, 236"x.__format__(fmt) -> string\n\n" 237"Return a Python string by formatting 'x' using the format string\n" 238"'fmt'. A valid format string consists of:\n" 239" optional alignment code:\n" 240" '<' -> left shifted in field\n" 241" '>' -> right shifted in field\n" 242" '^' -> centered in field\n" 243" optional leading sign code\n" 244" '+' -> always display leading sign\n" 245" '-' -> only display minus for negative values\n" 246" ' ' -> minus for negative values, space for positive values\n" 247" optional width.real_precision.imag_precision\n" 248" optional rounding mode:\n" 249" 'U' -> round toward plus infinity\n" 250" 'D' -> round toward minus infinity\n" 251" 'Z' -> round toward zero\n" 252" 'N' -> round to nearest\n" 253" optional output style:\n" 254" 'P' -> Python style, 1+2j, (default)\n" 255" 'M' -> MPC style, (1 2)\n" 256" optional conversion code:\n" 257" 'a','A' -> hex format\n" 258" 'b' -> binary format\n" 259" 'e','E' -> scientific format\n" 260" 'f','F' -> fixed point format\n" 261" 'g','G' -> fixed or scientific format\n\n" 262"The default format is 'f'."); 263 264static PyObject * 265Pympc_format(PyObject *self, PyObject *args) 266{ 267 PyObject *result = 0, *tempstr = 0; 268 char *realbuf = 0, *imagbuf = 0, *tempbuf = 0, *fmtcode = 0; 269 char *p, *rfmtptr, *ifmtptr, *fmtptr; 270 char rfmt[100], ifmt[100], fmt[30]; 271 int rbuflen, ibuflen; 272 int seensign = 0, seenalign = 0, seendecimal = 0, seendigits = 0; 273 int seenround = 0, seenconv = 0, seenstyle = 0, mpcstyle = 0; 274 275 if (!Pympc_Check(self)) { 276 TYPE_ERROR("requires 'mpc' object"); 277 return NULL; 278 } 279 280 if (!PyArg_ParseTuple(args, "s", &fmtcode)) 281 return NULL; 282 283 rfmtptr = rfmt; 284 ifmtptr = ifmt; 285 fmtptr = fmt; 286 *(rfmtptr++) = '%'; 287 *(ifmtptr++) = '%'; 288 289 for (p = fmtcode; *p != '\00'; p++) { 290 if (*p == '<' || *p == '>' || *p == '^') { 291 if (seenalign || seensign || seendecimal || seendigits || 292 seenround || seenstyle) { 293 VALUE_ERROR("Invalid conversion specification"); 294 return NULL; 295 } 296 else { 297 *(fmtptr++) = *p; 298 seenalign = 1; 299 continue; 300 } 301 } 302 if (*p == '+' || *p == ' ' || *p == '-') { 303 if (seensign || seendecimal || seendigits || seenround || 304 seenstyle) { 305 VALUE_ERROR("Invalid conversion specification"); 306 return NULL; 307 } 308 else { 309 *(rfmtptr++) = *p; 310 *(ifmtptr++) = *p; 311 seensign = 1; 312 continue; 313 } 314 } 315 if (!seensign) { 316 *(rfmtptr++) = '-'; 317 *(ifmtptr++) = '-'; 318 seensign = 1; 319 } 320 if (*p == '.') { 321 if (seendecimal == 2 || seendigits || seenround || seenstyle) { 322 VALUE_ERROR("Invalid conversion specification"); 323 return NULL; 324 } 325 else { 326 if (!seendecimal) { 327 *(rfmtptr++) = *p; 328 *(ifmtptr++) = *p; 329 } 330 seendecimal++; 331 if (seendecimal == 2) { 332 while (isdigit(*(ifmtptr-1))) 333 ifmtptr--; 334 } 335 continue; 336 } 337 } 338 if (isdigit(*p)) { 339 if (seendigits || seenround || seenstyle) { 340 VALUE_ERROR("Invalid conversion specification"); 341 return NULL; 342 } 343 else if (seendecimal == 1) { 344 *(rfmtptr++) = *p; 345 *(ifmtptr++) = *p; 346 continue; 347 } 348 else if (seendecimal == 2) { 349 *(ifmtptr++) = *p; 350 continue; 351 } 352 else { 353 if (fmtptr == fmt) { 354 *(fmtptr++) = '>'; 355 seenalign = 1; 356 } 357 *(fmtptr++) = *p; 358 continue; 359 } 360 } 361 if (!seendigits) { 362 seendigits = 1; 363 *(rfmtptr++) = 'R'; 364 *(ifmtptr++) = 'R'; 365 } 366 if (*p == 'U' || *p == 'D' || *p == 'Y' || *p == 'Z' || 367 *p == 'N' ) { 368 if (seenround || seenstyle) { 369 VALUE_ERROR("Invalid conversion specification"); 370 return NULL; 371 } 372 else { 373 *(rfmtptr++) = *p; 374 *(ifmtptr++) = *p; 375 seenround = 1; 376 continue; 377 } 378 } 379 if (*p == 'P' || *p == 'M') { 380 if (seenstyle) { 381 VALUE_ERROR("Invalid conversion specification"); 382 return NULL; 383 } 384 else { 385 if (*p == 'M') 386 mpcstyle = 1; 387 seenstyle = 1; 388 continue; 389 } 390 } 391 if (*p == 'a' || *p == 'A' || *p == 'b' || *p == 'e' || 392 *p == 'E' || *p == 'f' || *p == 'F' || *p == 'g' || 393 *p == 'G' ) { 394 *(rfmtptr++) = *p; 395 *(ifmtptr++) = *p; 396 seenconv = 1; 397 break; 398 } 399 VALUE_ERROR("Invalid conversion specification"); 400 return NULL; 401 } 402 403 if (!seensign) { 404 *(rfmtptr++) = '-'; 405 *(ifmtptr++) = '-'; 406 } 407 if (!seendigits) { 408 *(rfmtptr++) = 'R'; 409 *(ifmtptr++) = 'R'; 410 } 411 if (!seenconv) { 412 *(rfmtptr++) = 'f'; 413 *(ifmtptr++) = 'f'; 414 } 415 416 *(rfmtptr) = '\00'; 417 *(ifmtptr) = '\00'; 418 *(fmtptr) = '\00'; 419 420 /* Format the real part.... */ 421 422 rbuflen = mpfr_asprintf(&realbuf, rfmt, 423 mpc_realref(Pympc_AS_MPC(self))); 424 425 if (rbuflen < 0) { 426 mpfr_free_str(realbuf); 427 SYSTEM_ERROR("Internal error in mpfr_asprintf"); 428 return NULL; 429 } 430 431 /* Format the imaginary part. If Python style is wanted, convert the '-' 432 * or ' ' sign indicator to '+'. */ 433 434 if (!mpcstyle) { 435 if (ifmt[1] == ' ' || ifmt[1] == '-' || ifmt[1] == '+') { 436 ifmt[1] = '+'; 437 } 438 else { 439 mpfr_free_str(realbuf); 440 VALUE_ERROR("Invalid conversion specification for imag"); 441 return NULL; 442 } 443 } 444 445 ibuflen = mpfr_asprintf(&imagbuf, ifmt, 446 mpc_imagref(Pympc_AS_MPC(self))); 447 448 if (ibuflen < 0) { 449 mpfr_free_str(realbuf); 450 mpfr_free_str(imagbuf); 451 SYSTEM_ERROR("Internal error in mpfr_asprintf"); 452 return NULL; 453 } 454 455 /* Combine the real and imaginary components into a single buffer. 456 * Include space for '(', ' ', and 'j)' and possibly appending '.0' twice. 457 */ 458 459 tempbuf = GMPY_MALLOC(rbuflen + ibuflen + 10); 460 if (!tempbuf) { 461 mpfr_free_str(realbuf); 462 mpfr_free_str(imagbuf); 463 return PyErr_NoMemory(); 464 } 465 tempbuf[0] = '\00'; 466 if (mpcstyle) 467 strcat(tempbuf, "("); 468 strcat(tempbuf, realbuf); 469 470 /* If there isn't a decimal point in the output and the output 471 * is short and only consists of digits, then append .0 */ 472 if (strlen(realbuf) < 50 && 473 strlen(realbuf) == strspn(realbuf, "+- 0123456789")) { 474 strcat(tempbuf, ".0"); 475 } 476 477 if (mpcstyle) 478 strcat(tempbuf, " "); 479 else { 480 /* Need to insert + if imag is nan or +inf. */ 481 if (mpfr_nan_p(mpc_imagref(Pympc_AS_MPC(self))) || 482 (mpfr_inf_p(mpc_imagref(Pympc_AS_MPC(self))) && 483 mpfr_sgn(mpc_imagref(Pympc_AS_MPC(self))) > 0)) { 484 strcat(tempbuf, "+"); 485 } 486 } 487 strcat(tempbuf, imagbuf); 488 if (strlen(imagbuf) < 50 && 489 strlen(imagbuf) == strspn(imagbuf, "+- 0123456789")) { 490 strcat(tempbuf, ".0"); 491 } 492 493 if (mpcstyle) 494 strcat(tempbuf, ")"); 495 else 496 strcat(tempbuf, "j"); 497 498 mpfr_free_str(realbuf); 499 mpfr_free_str(imagbuf); 500 501 tempstr = Py_BuildValue("s", tempbuf); 502 if (!tempstr) { 503 GMPY_FREE(tempbuf); 504 return NULL; 505 } 506 507 result = PyObject_CallMethod(tempstr, "__format__", "(s)", fmt); 508 509 Py_DECREF(tempstr); 510 return result; 511} 512 513static PyObject * 514Pympc_abs(PyObject *self) 515{ 516 PympfrObject *result = 0; 517 PympcObject *tempx = 0; 518 519 result = (PympfrObject*)Pympfr_new(0); 520 tempx = Pympc_From_Complex(self, 0, 0); 521 if (!tempx || !result) { 522 SYSTEM_ERROR("Can't convert argument to 'mpc'."); 523 Py_XDECREF((PyObject*)tempx); 524 Py_XDECREF((PyObject*)result); 525 return NULL; 526 } 527 528 result->rc = mpc_abs(result->f, tempx->c, GET_MPC_ROUND(context)); 529 Py_DECREF((PyObject*)tempx); 530 531 MPFR_SUBNORMALIZE(result); 532 MPFR_CHECK_INVALID(result, "invalid operation in 'mpc' __abs__"); 533 MPFR_CHECK_UNDERFLOW(result, "underflow in 'mpc' __abs__"); 534 MPFR_CHECK_OVERFLOW(result, "overflow in 'mpc' __abs__"); 535 MPFR_CHECK_INEXACT(result, "inexact result in 'mpc' __abs__"); 536 done: 537 if (PyErr_Occurred()) { 538 Py_DECREF((PyObject*)result); 539 result = NULL; 540 } 541 return (PyObject*)result; 542} 543 544static PyObject * 545Pympc_neg(PympcObject *self) 546{ 547 PympcObject *result = 0; 548 549 if (!(result = (PympcObject*)Pympc_new(0, 0))) 550 return NULL; 551 552 if (!(self = Pympc_From_Complex((PyObject*)self, 0, 0))) { 553 SYSTEM_ERROR("__neg__() requires 'mpc' argument"); 554 Py_DECREF(result); 555 return NULL; 556 } 557 558 result->rc = mpc_neg(result->c, self->c, GET_MPC_ROUND(context)); 559 560 MPC_CLEANUP(result, "__neg__"); 561} 562 563static PyObject * 564Pympc_pos(PympcObject *self) 565{ 566 PympcObject *result = 0; 567 568 if (!(result = Pympc_From_Complex((PyObject*)self, 0, 0))) { 569 SYSTEM_ERROR("__pos__ requires 'mpc' argument"); 570 return NULL; 571 } 572 573 MPC_CLEANUP(result, "__pos__"); 574} 575 576/* Support Pympany_square */ 577 578static PyObject * 579Pympc_sqr(PyObject* self, PyObject *other) 580{ 581 PympcObject *result; 582 583 PARSE_ONE_MPC_OTHER("square() requires 'mpc' argument"); 584 585 if (!(result = (PympcObject*)Pympc_new(0, 0))) { 586 Py_DECREF(self); 587 return NULL; 588 } 589 590 result->rc = mpc_sqr(result->c, Pympc_AS_MPC(self), 591 GET_MPC_ROUND(context)); 592 Py_DECREF(self); 593 594 MPC_CLEANUP(result, "square()"); 595} 596 597static PyObject * 598Pympc_pow(PyObject *base, PyObject *exp, PyObject *m) 599{ 600 PympcObject *tempb, *tempe, *result; 601 602 if (m != Py_None) { 603 TYPE_ERROR("pow() 3rd argument not allowed unless all arguments are integers"); 604 return NULL; 605 } 606 607 tempb = Pympc_From_Complex(base, 0, 0); 608 tempe = Pympc_From_Complex(exp, 0, 0); 609 610 if (!tempe || !tempb) { 611 Py_XDECREF((PyObject*)tempe); 612 Py_XDECREF((PyObject*)tempb); 613 Py_RETURN_NOTIMPLEMENTED; 614 } 615 616 result = (PympcObject*)Pympc_new(0, 0); 617 618 if (!result) { 619 Py_DECREF((PyObject*)tempe); 620 Py_DECREF((PyObject*)tempb); 621 return NULL; 622 } 623 624 if (MPC_IS_ZERO_P(tempb) && MPC_IS_ZERO_P(tempe)) { 625 mpc_set_ui(result->c, 1, GET_MPC_ROUND(context)); 626 Py_DECREF((PyObject*)tempe); 627 Py_DECREF((PyObject*)tempb); 628 return (PyObject*)result; 629 } 630 631 if (MPC_IS_ZERO_P(tempb) && 632 (!mpfr_zero_p(mpc_imagref(tempe->c)) || 633 mpfr_sgn(mpc_realref(tempe->c)) < 0)) { 634 635 context->ctx.divzero = 1; 636 if (context->ctx.trap_divzero) { 637 GMPY_DIVZERO("zero cannot be raised to a negative or complex power"); 638 Py_DECREF((PyObject*)tempe); 639 Py_DECREF((PyObject*)tempb); 640 Py_DECREF((PyObject*)result); 641 return NULL; 642 } 643 } 644 645 result->rc = mpc_pow(result->c, tempb->c, 646 tempe->c, GET_MPC_ROUND(context)); 647 Py_DECREF((PyObject*)tempe); 648 Py_DECREF((PyObject*)tempb); 649 650 MPC_CLEANUP(result, "pow()"); 651} 652 653/* Implement the conjugate() method. */ 654 655PyDoc_STRVAR(doc_mpc_conjugate, 656"x.conjugate() -> mpc\n\n" 657"Returns the conjugate of x."); 658 659static PyObject * 660Pympc_conjugate(PyObject *self, PyObject *args) 661{ 662 PympcObject *result; 663 664 PARSE_ONE_MPC_ARGS("conjugate() requires 'mpc' argument"); 665 666 if (!(result = (PympcObject*)Pympc_new(0,0))) { 667 Py_DECREF(self); 668 return NULL; 669 } 670 671 result->rc = mpc_conj(result->c, Pympc_AS_MPC(self), 672 GET_MPC_ROUND(context)); 673 Py_DECREF(self); 674 675 MPC_CLEANUP(result, "conjugate()"); 676} 677 678/* Implement the .precision attribute of an mpfr. */ 679 680static PyObject * 681Pympc_getprec_attrib(PympcObject *self, void *closure) 682{ 683 mpfr_prec_t rprec = 0, iprec = 0; 684 685 mpc_get_prec2(&rprec, &iprec, self->c); 686 return Py_BuildValue("(nn)", rprec, iprec); 687} 688 689/* Implement the .rc attribute of an mpfr. */ 690 691static PyObject * 692Pympc_getrc_attrib(PympcObject *self, void *closure) 693{ 694 return Py_BuildValue("(ii)", MPC_INEX_RE(self->rc), MPC_INEX_IM(self->rc)); 695} 696 697/* Implement the .imag attribute of an mpfr. */ 698 699static PyObject * 700Pympc_getimag_attrib(PympcObject *self, void *closure) 701{ 702 PympfrObject *result; 703 704 if ((result = (PympfrObject*)Pympfr_new(0))) 705 mpc_imag(result->f, self->c, context->ctx.mpfr_round); 706 return (PyObject*)result; 707} 708 709/* Implement the .real attribute of an mpfr. */ 710 711static PyObject * 712Pympc_getreal_attrib(PympcObject *self, void *closure) 713{ 714 PympfrObject *result; 715 716 if ((result = (PympfrObject*)Pympfr_new(0))) 717 mpc_real(result->f, self->c, context->ctx.mpfr_round); 718 return (PyObject*)result; 719} 720 721/* Implement the nb_bool slot. */ 722 723static int 724Pympc_nonzero(PympcObject *self) 725{ 726 return !MPC_IS_ZERO_P(self->c); 727} 728 729/* To work with the MPC_IS_ macros, NAN, INF, FINITE, and ZERO are 730 * all upper-case. 731 */ 732 733#define MPC_TEST_OTHER(NAME, msg) \ 734static PyObject * \ 735Pympc_is_##NAME(PyObject *self, PyObject *other)\ 736{\ 737 if(self && Pympc_Check(self)) {\ 738 Py_INCREF(self);\ 739 }\ 740 else if(Pympc_Check(other)) {\ 741 self = other;\ 742 Py_INCREF((PyObject*)self);\ 743 }\ 744 else if (!(self = (PyObject*)Pympc_From_Complex(other, 0, 0))) {\ 745 PyErr_SetString(PyExc_TypeError, msg);\ 746 return NULL;\ 747 }\ 748 if (MPC_IS_##NAME##_P(self)) {\ 749 Py_DECREF(self);\ 750 Py_RETURN_TRUE;\ 751 }\ 752 else {\ 753 Py_DECREF(self);\ 754 Py_RETURN_FALSE;\ 755 }\ 756} 757 758MPC_TEST_OTHER(NAN, "is_nan() requires 'mpc' argument"); 759 760MPC_TEST_OTHER(INF, "is_infinite() requires 'mpc' argument"); 761 762MPC_TEST_OTHER(FINITE, "is_finite() requires 'mpc' argument"); 763 764MPC_TEST_OTHER(ZERO, "is_zero() requires 'mpc' argument"); 765 766PyDoc_STRVAR(doc_mpc_phase, 767"phase(x) -> mpfr\n\n" 768"Return the phase angle, also known as argument, of a complex x."); 769 770static PyObject * 771Pympc_phase(PyObject *self, PyObject *other) 772{ 773 PympfrObject *result; 774 775 PARSE_ONE_MPC_OTHER("phase() requires 'mpc' argument"); 776 777 if (!(result = (PympfrObject*)Pympfr_new(0))) { 778 Py_DECREF(self); 779 return NULL; 780 } 781 782 result->rc = mpc_arg(result->f, Pympc_AS_MPC(self), 783 context->ctx.mpfr_round); 784 Py_DECREF((PyObject*)self); 785 786 MPFR_SUBNORMALIZE(result); 787 MPFR_CHECK_OVERFLOW(result, "overflow in 'mpc' phase()"); 788 MPFR_CHECK_INVALID(result, "invalid operation 'mpc' phase()"); 789 MPFR_CHECK_UNDERFLOW(result, "underflow in 'mpc' phase()"); 790 MPFR_CHECK_INEXACT(result, "inexact operation in 'mpc' phase()"); 791 done: 792 if (PyErr_Occurred()) { 793 Py_DECREF((PyObject*)result); 794 result = NULL; 795 } 796 return (PyObject*)result; 797} 798 799PyDoc_STRVAR(doc_mpc_norm, 800"norm(x) -> mpfr\n\n" 801"Return the norm of a complex x. The norm(x) is defined as\n" 802"x.real**2 + x.imag**2. abs(x) is the square root of norm(x).\n"); 803 804static PyObject * 805Pympc_norm(PyObject *self, PyObject *other) 806{ 807 PympfrObject *result; 808 809 PARSE_ONE_MPC_OTHER("norm() requires 'mpc' argument"); 810 811 if (!(result = (PympfrObject*)Pympfr_new(0))) { 812 Py_DECREF(self); 813 return NULL; 814 } 815 816 result->rc = mpc_norm(result->f, Pympc_AS_MPC(self), 817 context->ctx.mpfr_round); 818 Py_DECREF((PyObject*)self); 819 820 MPFR_SUBNORMALIZE(result); 821 MPFR_CHECK_OVERFLOW(result, "overflow in 'mpc' norm()"); 822 MPFR_CHECK_INVALID(result, "invalid operation 'mpc' norm()"); 823 MPFR_CHECK_UNDERFLOW(result, "underflow in 'mpc' norm()"); 824 MPFR_CHECK_INEXACT(result, "inexact operation in 'mpc' norm()"); 825 done: 826 if (PyErr_Occurred()) { 827 Py_DECREF((PyObject*)result); 828 result = NULL; 829 } 830 return (PyObject*)result; 831} 832 833PyDoc_STRVAR(doc_mpc_polar, 834"polar(x) -> (abs(x), phase(x))\n\n" 835"Return the polar coordinate form of a complex x that is in\n" 836"rectangular form."); 837 838static PyObject * 839Pympc_polar(PyObject *self, PyObject *other) 840{ 841 PyObject *abs, *phase, *result; 842 843 PARSE_ONE_MPC_OTHER("norm() requires 'mpc' argument"); 844 845 if (!(abs = Pympc_abs(self))) { 846 Py_DECREF(self); 847 return NULL; 848 } 849 if (!(phase = Pympc_phase(self, other))) { 850 Py_DECREF(abs); 851 Py_DECREF(self); 852 return NULL; 853 } 854 855 result = Py_BuildValue("(NN)", abs, phase); 856 if (!result) { 857 Py_DECREF(abs); 858 Py_DECREF(phase); 859 } 860 Py_DECREF(self); 861 return result; 862} 863 864PyDoc_STRVAR(doc_mpc_rect, 865"rect(x) -> mpc\n\n" 866"Return the polar coordinate form of a complex x that is in\n" 867"rectangular form."); 868 869/* Note: does not properly check for inexact or underflow */ 870 871static PyObject * 872Pympc_rect(PyObject *self, PyObject *args) 873{ 874 PyObject *other; 875 PympcObject *result; 876 877 PARSE_TWO_MPFR_ARGS(other, "rect() requires 'mpfr','mpfr' arguments"); 878 879 if (!(result = (PympcObject*)Pympc_new(0, 0))) { 880 Py_DECREF(self); 881 Py_DECREF(other); 882 return NULL; 883 } 884 885 mpfr_cos(mpc_realref(result->c), Pympfr_AS_MPFR(other), 886 GET_REAL_ROUND(context)); 887 mpfr_mul(mpc_realref(result->c), mpc_realref(result->c), 888 Pympfr_AS_MPFR(self), GET_REAL_ROUND(context)); 889 mpfr_sin(mpc_imagref(result->c), Pympfr_AS_MPFR(other), 890 GET_IMAG_ROUND(context)); 891 mpfr_mul(mpc_imagref(result->c), mpc_imagref(result->c), 892 Pympfr_AS_MPFR(self), GET_IMAG_ROUND(context)); 893 Py_DECREF(self); 894 Py_DECREF(other); 895 896 MPC_CLEANUP(result, "rect()"); 897} 898 899PyDoc_STRVAR(doc_mpc_proj, 900"proj(x) -> mpc\n\n" 901"Returns the projection of a complex x on to the Riemann sphere."); 902 903static PyObject * 904Pympc_proj(PyObject *self, PyObject *other) 905{ 906 PympcObject *result; 907 908 PARSE_ONE_MPC_OTHER("proj() requires 'mpc' argument"); 909 910 if (!(result = (PympcObject*)Pympc_new(0, 0))) { 911 Py_DECREF(self); 912 return NULL; 913 } 914 915 result->rc = mpc_proj(result->c, Pympc_AS_MPC(self), 916 GET_MPC_ROUND(context)); 917 Py_DECREF(self); 918 919 MPC_CLEANUP(result, "proj()"); 920} 921 922#define MPC_UNIOP(NAME) \ 923static PyObject * \ 924Pympc_##NAME(PyObject* self, PyObject *other) \ 925{ \ 926 PympcObject *result; \ 927 PARSE_ONE_MPC_OTHER(#NAME "() requires 'mpc' argument"); \ 928 if (!(result = (PympcObject*)Pympc_new(0, 0))) { \ 929 Py_DECREF(self); \ 930 return NULL; \ 931 } \ 932 result->rc = mpc_##NAME(result->c, Pympc_AS_MPC(self), GET_MPC_ROUND(context)); \ 933 Py_DECREF(self); \ 934 MPC_CLEANUP(result, #NAME"()"); \ 935} 936 937MPC_UNIOP(log) 938 939MPC_UNIOP(log10) 940 941MPC_UNIOP(exp) 942 943MPC_UNIOP(sin) 944 945MPC_UNIOP(cos) 946 947MPC_UNIOP(tan) 948 949MPC_UNIOP(sinh) 950 951MPC_UNIOP(cosh) 952 953MPC_UNIOP(tanh) 954 955MPC_UNIOP(asin) 956 957MPC_UNIOP(acos) 958 959MPC_UNIOP(atan) 960 961MPC_UNIOP(asinh) 962 963MPC_UNIOP(acosh) 964 965MPC_UNIOP(atanh) 966 967MPC_UNIOP(sqrt) 968 969static PyObject * 970Pympc_sin_cos(PyObject *self, PyObject *other) 971{ 972 PympcObject *s, *c; 973 PyObject *result; 974 int code; 975 976 PARSE_ONE_MPC_OTHER("sin_cos() requires 'mpc' argument"); 977 978 s = (PympcObject*)Pympc_new(0, 0); 979 c = (PympcObject*)Pympc_new(0, 0); 980 result = PyTuple_New(2); 981 if (!s || !c || !result) { 982 Py_DECREF(self); 983 return NULL; 984 } 985 986 code = mpc_sin_cos(s->c, c->c, Pympc_AS_MPC(self), 987 GET_MPC_ROUND(context), GET_MPC_ROUND(context)); 988 s->rc = MPC_INEX1(code); 989 c->rc = MPC_INEX2(code); 990 MPC_SUBNORMALIZE(s); 991 MPC_SUBNORMALIZE(c); 992 MPC_CHECK_FLAGS(s, "sin_cos()"); 993 MPC_CHECK_FLAGS(c, "sin_cos()"); 994 995 done: 996 Py_DECREF(self); 997 if (PyErr_Occurred()) { 998 Py_XDECREF((PyObject*)s); 999 Py_XDECREF((PyObject*)c); 1000 Py_XDECREF(result); 1001 result = NULL; 1002 } 1003 else { 1004 PyTuple_SET_ITEM(result, 0, (PyObject*)s); 1005 PyTuple_SET_ITEM(result, 1, (PyObject*)c); 1006 } 1007 return result; 1008} 1009 1010static PyObject * 1011Pympc_fma(PyObject *self, PyObject *args) 1012{ 1013 PympcObject *result, *x, *y, *z; 1014 1015 if (PyTuple_GET_SIZE(args) != 3) { 1016 TYPE_ERROR("fma() requires 'mpc','mpc','mpc' arguments."); 1017 return NULL; 1018 } 1019 1020 result = (PympcObject*)Pympc_new(0, 0); 1021 x = Pympc_From_Complex(PyTuple_GET_ITEM(args, 0), 0, 0); 1022 y = Pympc_From_Complex(PyTuple_GET_ITEM(args, 1), 0, 0); 1023 z = Pympc_From_Complex(PyTuple_GET_ITEM(args, 2), 0, 0); 1024 if (!result || !x || !y || !z) { 1025 TYPE_ERROR("fma() requires 'mpc','mpc','mpc' arguments."); 1026 goto done; 1027 } 1028 1029 result->rc = mpc_fma(result->c, x->c, y->c, z->c, 1030 context->ctx.mpfr_round); 1031 MPC_SUBNORMALIZE(result); 1032 MPC_CHECK_FLAGS(result, "fma()"); 1033 1034 done: 1035 Py_XDECREF((PyObject*)x); 1036 Py_XDECREF((PyObject*)y); 1037 Py_XDECREF((PyObject*)z); 1038 if (PyErr_Occurred()) { 1039 Py_XDECREF(result); 1040 result = NULL; 1041 } 1042 return (PyObject*)result; 1043} 1044 1045static PyObject * 1046Pympc_fms(PyObject *self, PyObject *args) 1047{ 1048 PympcObject *result, *x, *y, *z; 1049 1050 if (PyTuple_GET_SIZE(args) != 3) { 1051 TYPE_ERROR("fms() requires 'mpc','mpc','mpc' arguments."); 1052 return NULL; 1053 } 1054 1055 result = (PympcObject*)Pympc_new(0, 0); 1056 x = Pympc_From_Complex(PyTuple_GET_ITEM(args, 0), 0, 0); 1057 y = Pympc_From_Complex(PyTuple_GET_ITEM(args, 1), 0, 0); 1058 z = Pympc_From_Complex(PyTuple_GET_ITEM(args, 2), 0, 0); 1059 if (!result || !x || !y || !z) { 1060 TYPE_ERROR("fms() requires 'mpc','mpc','mpc' arguments."); 1061 goto done; 1062 } 1063 1064 mpc_neg(z->c, z->c, GET_MPC_ROUND(context)); 1065 result->rc = mpc_fma(result->c, x->c, y->c, z->c, 1066 context->ctx.mpfr_round); 1067 MPC_SUBNORMALIZE(result); 1068 MPC_CHECK_FLAGS(result, "fms()"); 1069 1070 done: 1071 Py_XDECREF((PyObject*)x); 1072 Py_XDECREF((PyObject*)y); 1073 Py_XDECREF((PyObject*)z); 1074 if (PyErr_Occurred()) { 1075 Py_XDECREF(result); 1076 result = NULL; 1077 } 1078 return (PyObject*)result; 1079} 1080 1081static PyObject * 1082Pympc_div_2exp(PyObject *self, PyObject *args) 1083{ 1084 PympcObject *result = 0; 1085 unsigned long exp = 0; 1086 1087 if (!PyArg_ParseTuple(args, "O&k", Pympc_convert_arg, &self, &exp)) { 1088 TYPE_ERROR("div_2exp() requires 'mpc', 'int' arguments"); 1089 return NULL; 1090 } 1091 1092 if (!(result = (PympcObject*)Pympc_new(0, 0))) { 1093 Py_DECREF(self); 1094 return NULL; 1095 } 1096 1097 result->rc = mpc_div_2ui(Pympc_AS_MPC(result), Pympc_AS_MPC(self), 1098 exp, GET_MPC_ROUND(context)); 1099 Py_DECREF(self); 1100 1101 MPC_CLEANUP(result, "div_2exp()"); 1102} 1103 1104static PyObject * 1105Pympc_mul_2exp(PyObject *self, PyObject *args) 1106{ 1107 PympcObject *result = 0; 1108 unsigned long exp = 0; 1109 1110 if (!PyArg_ParseTuple(args, "O&k", Pympc_convert_arg, &self, &exp)) { 1111 TYPE_ERROR("mul_2exp() requires 'mpc', 'int' arguments"); 1112 return NULL; 1113 } 1114 1115 if (!(result = (PympcObject*)Pympc_new(0, 0))) { 1116 Py_DECREF(self); 1117 return NULL; 1118 } 1119 1120 result->rc = mpc_mul_2ui(Pympc_AS_MPC(result), Pympc_AS_MPC(self), 1121 exp, GET_MPC_ROUND(context)); 1122 Py_DECREF(self); 1123 1124 MPC_CLEANUP(result, "mul_2exp()"); 1125} 1126 1127static Py_hash_t 1128Pympc_hash(PympcObject *self) 1129{ 1130 Py_uhash_t hashreal, hashimag, combined; 1131 1132 if (self->hash_cache != -1) 1133 return self->hash_cache; 1134 1135 hashreal = (Py_uhash_t)_mpfr_hash(mpc_realref(self->c)); 1136 if (hashreal == (Py_uhash_t)-1) 1137 return -1; 1138 hashimag = (Py_uhash_t)_mpfr_hash(mpc_imagref(self->c)); 1139 if (hashimag == (Py_uhash_t)-1) 1140 return -1; 1141 combined = hashreal + _PyHASH_IMAG * hashimag; 1142 if (combined == (Py_uhash_t)-1) 1143 combined = (Py_uhash_t)-2; 1144 self->hash_cache = combined; 1145 return (Py_hash_t)combined; 1146} 1147 1148static PyObject * 1149Pympc_add_fast(PyObject *x, PyObject *y) 1150{ 1151 PympcObject *result; 1152 1153 if (Pympc_CheckAndExp(x) && Pympc_CheckAndExp(y)) { 1154 if (!(result = (PympcObject*)Pympc_new(0, 0))) { 1155 return NULL; 1156 } 1157 result->rc = mpc_add(result->c, 1158 Pympc_AS_MPC(x), 1159 Pympc_AS_MPC(y), 1160 GET_MPC_ROUND(context)); 1161 MPC_CLEANUP(result, "addition"); 1162 return (PyObject*)result; 1163 } 1164 else { 1165 return Pybasic_add(x, y); 1166 } 1167} 1168 1169static PyObject * 1170Pympc_add(PyObject *self, PyObject *args) 1171{ 1172 PympcObject *result; 1173 PyObject *other; 1174 1175 PARSE_TWO_MPC_ARGS(other, "add() requires 'mpc','mpc' arguments"); 1176 1177 if (!(result = (PympcObject*)Pympc_new(0, 0))) { 1178 Py_DECREF(self); 1179 Py_DECREF(other); 1180 return NULL; 1181 } 1182 1183 result->rc = mpc_add(result->c, Pympc_AS_MPC(self), 1184 Pympc_AS_MPC(other), GET_MPC_ROUND(context)); 1185 Py_DECREF(self); 1186 Py_DECREF(other); 1187 MPC_CLEANUP(result, "add()"); 1188} 1189 1190static PyObject * 1191Pympc_sub_fast(PyObject *x, PyObject *y) 1192{ 1193 PympcObject *result; 1194 1195 if (Pympc_CheckAndExp(x) && Pympc_CheckAndExp(y)) { 1196 if (!(result = (PympcObject*)Pympc_new(0, 0))) { 1197 return NULL; 1198 } 1199 result->rc = mpc_sub(result->c, 1200 Pympc_AS_MPC(x), 1201 Pympc_AS_MPC(y), 1202 GET_MPC_ROUND(context)); 1203 MPC_CLEANUP(result, "subtraction"); 1204 return (PyObject*)result; 1205 } 1206 else { 1207 return Pybasic_sub(x, y); 1208 } 1209} 1210 1211static PyObject * 1212Pympc_sub(PyObject *self, PyObject *args) 1213{ 1214 PympcObject *result; 1215 PyObject *other; 1216 1217 PARSE_TWO_MPC_ARGS(other, "sub() requires 'mpc','mpc' arguments"); 1218 1219 if (!(result = (PympcObject*)Pympc_new(0, 0))) { 1220 Py_DECREF(self); 1221 Py_DECREF(other); 1222 return NULL; 1223 } 1224 1225 result->rc = mpc_sub(result->c, Pympc_AS_MPC(self), 1226 Pympc_AS_MPC(other), GET_MPC_ROUND(context)); 1227 Py_DECREF(self); 1228 Py_DECREF(other); 1229 MPC_CLEANUP(result, "sub()"); 1230} 1231 1232static PyObject * 1233Pympc_mul_fast(PyObject *x, PyObject *y) 1234{ 1235 PympcObject *result; 1236 1237 if (Pympc_CheckAndExp(x) && Pympc_CheckAndExp(y)) { 1238 if (!(result = (PympcObject*)Pympc_new(0, 0))) { 1239 return NULL; 1240 } 1241 result->rc = mpc_mul(result->c, 1242 Pympc_AS_MPC(x), 1243 Pympc_AS_MPC(y), 1244 GET_MPC_ROUND(context)); 1245 MPC_CLEANUP(result, "multiplication"); 1246 return (PyObject*)result; 1247 } 1248 else { 1249 return Pybasic_mul(x, y); 1250 } 1251} 1252 1253static PyObject * 1254Pympc_mul(PyObject *self, PyObject *args) 1255{ 1256 PympcObject *result; 1257 PyObject *other; 1258 1259 PARSE_TWO_MPC_ARGS(other, "mul() requires 'mpc','mpc' arguments"); 1260 1261 if (!(result = (PympcObject*)Pympc_new(0, 0))) { 1262 Py_DECREF(self); 1263 Py_DECREF(other); 1264 return NULL; 1265 } 1266 1267 result->rc = mpc_mul(result->c, Pympc_AS_MPC(self), 1268 Pympc_AS_MPC(other), GET_MPC_ROUND(context)); 1269 Py_DECREF(self); 1270 Py_DECREF(other); 1271 MPC_CLEANUP(result, "mul()"); 1272} 1273 1274static PyObject * 1275Pympc_truediv_fast(PyObject *x, PyObject *y) 1276{ 1277 PympcObject *result; 1278 1279 if (Pympc_CheckAndExp(x) && Pympc_CheckAndExp(y)) { 1280 if (MPC_IS_ZERO_P(y)) { 1281 context->ctx.divzero = 1; 1282 if (context->ctx.trap_divzero) { 1283 GMPY_DIVZERO("'mpc' division by zero"); 1284 return NULL; 1285 } 1286 } 1287 if (!(result = (PympcObject*)Pympc_new(0, 0))) { 1288 return NULL; 1289 } 1290 result->rc = mpc_div(result->c, 1291 Pympc_AS_MPC(x), 1292 Pympc_AS_MPC(y), 1293 GET_MPC_ROUND(context)); 1294 MPC_CLEANUP(result, "division"); 1295 return (PyObject*)result; 1296 } 1297 else { 1298 return Pybasic_truediv(x, y); 1299 } 1300} 1301 1302#ifdef PY2 1303static PyObject * 1304Pympc_div2_fast(PyObject *x, PyObject *y) 1305{ 1306 PympcObject *result; 1307 1308 if (Pympc_CheckAndExp(x) && Pympc_CheckAndExp(y)) { 1309 if (MPC_IS_ZERO_P(y)) { 1310 context->ctx.divzero = 1; 1311 if (context->ctx.trap_divzero) { 1312 GMPY_DIVZERO("'mpc' division by zero"); 1313 return NULL; 1314 } 1315 } 1316 if (!(result = (PympcObject*)Pympc_new(0, 0))) { 1317 return NULL; 1318 } 1319 result->rc = mpc_div(result->c, 1320 Pympc_AS_MPC(x), 1321 Pympc_AS_MPC(y), 1322 GET_MPC_ROUND(context)); 1323 MPC_CLEANUP(result, "division"); 1324 return (PyObject*)result; 1325 } 1326 else { 1327 return Pybasic_div2(x, y); 1328 } 1329} 1330#endif 1331 1332static PyObject * 1333Pympc_div(PyObject *self, PyObject *args) 1334{ 1335 PympcObject *result; 1336 PyObject *other; 1337 1338 PARSE_TWO_MPC_ARGS(other, "div() requires 'mpc','mpc' arguments"); 1339 1340 if (!(result = (PympcObject*)Pympc_new(0, 0))) { 1341 Py_DECREF(self); 1342 Py_DECREF(other); 1343 return NULL; 1344 } 1345 1346 if (MPC_IS_ZERO_P(Pympc_AS_MPC(other))) { 1347 context->ctx.divzero = 1; 1348 if (context->ctx.trap_divzero) { 1349 GMPY_DIVZERO("'mpc' division by zero"); 1350 Py_DECREF(self); 1351 Py_DECREF(other); 1352 return NULL; 1353 } 1354 } 1355 1356 result->rc = mpc_div(result->c, Pympc_AS_MPC(self), 1357 Pympc_AS_MPC(other), GET_MPC_ROUND(context)); 1358 Py_DECREF(self); 1359 Py_DECREF(other); 1360 MPC_CLEANUP(result, "div()"); 1361} 1362 1363PyDoc_STRVAR(doc_mpc_sizeof, 1364"x.__sizeof__()\n\n" 1365"Returns the amount of memory consumed by x."); 1366 1367static PyObject * 1368Pympc_sizeof(PyObject *self, PyObject *other) 1369{ 1370 return PyIntOrLong_FromSize_t(sizeof(PympcObject) + \ 1371 (((mpc_realref(Pympc_AS_MPC(self))->_mpfr_prec + mp_bits_per_limb - 1) / \ 1372 mp_bits_per_limb) * sizeof(mp_limb_t)) + \ 1373 (((mpc_imagref(Pympc_AS_MPC(self))->_mpfr_prec + mp_bits_per_limb - 1) / \ 1374 mp_bits_per_limb) * sizeof(mp_limb_t))); 1375} 1376 1377static PyMethodDef Pympc_methods[] = 1378{ 1379 { "__complex__", Pympc_To_PyComplex, METH_VARARGS, doc_mpc_complex }, 1380 { "__format__", Pympc_format, METH_VARARGS, doc_mpc_format }, 1381 { "__sizeof__", Pympc_sizeof, METH_NOARGS, doc_mpc_sizeof }, 1382 { "conjugate", Pympc_conjugate, METH_NOARGS, doc_mpc_conjugate }, 1383 { "digits", Pympc_digits, METH_VARARGS, doc_mpc_digits }, 1384 { NULL, NULL, 1 } 1385}; 1386 1387 1388#ifdef PY3 1389static PyNumberMethods mpc_number_methods = 1390{ 1391 (binaryfunc) Pympc_add_fast, /* nb_add */ 1392 (binaryfunc) Pympc_sub_fast, /* nb_subtract */ 1393 (binaryfunc) Pympc_mul_fast, /* nb_multiply */ 1394 (binaryfunc) Pybasic_rem, /* nb_remainder */ 1395 (binaryfunc) Pybasic_divmod, /* nb_divmod */ 1396 (ternaryfunc) Pympany_pow, /* nb_power */ 1397 (unaryfunc) Pympc_neg, /* nb_negative */ 1398 (unaryfunc) Pympc_pos, /* nb_positive */ 1399 (unaryfunc) Pympc_abs, /* nb_absolute */ 1400 (inquiry) Pympc_nonzero, /* nb_bool */ 1401 0, /* nb_invert */ 1402 0, /* nb_lshift */ 1403 0, /* nb_rshift */ 1404 0, /* nb_and */ 1405 0, /* nb_xor */ 1406 0, /* nb_or */ 1407 (unaryfunc) Pympc_To_PyLong, /* nb_int */ 1408 0, /* nb_reserved */ 1409 (unaryfunc) Pympc_To_PyFloat, /* nb_float */ 1410 0, /* nb_inplace_add */ 1411 0, /* nb_inplace_subtract */ 1412 0, /* nb_inplace_multiply */ 1413 0, /* nb_inplace_remainder */ 1414 0, /* nb_inplace_power */ 1415 0, /* nb_inplace_lshift */ 1416 0, /* nb_inplace_rshift */ 1417 0, /* nb_inplace_and */ 1418 0, /* nb_inplace_xor */ 1419 0, /* nb_inplace_or */ 1420 (binaryfunc) Pybasic_floordiv, /* nb_floor_divide */ 1421 (binaryfunc) Pympc_truediv_fast, /* nb_true_divide */ 1422 0, /* nb_inplace_floor_divide */ 1423 0, /* nb_inplace_true_divide */ 1424 0, /* nb_index */ 1425}; 1426#else 1427static PyNumberMethods mpc_number_methods = 1428{ 1429 (binaryfunc) Pympc_add_fast, /* nb_add */ 1430 (binaryfunc) Pympc_sub_fast, /* nb_subtract */ 1431 (binaryfunc) Pympc_mul_fast, /* nb_multiply */ 1432 (binaryfunc) Pympc_div2_fast, /* nb_divide */ 1433 (binaryfunc) Pybasic_rem, /* nb_remainder */ 1434 (binaryfunc) Pybasic_divmod, /* nb_divmod */ 1435 (ternaryfunc) Pympany_pow, /* nb_power */ 1436 (unaryfunc) Pympc_neg, /* nb_negative */ 1437 (unaryfunc) Pympc_pos, /* nb_positive */ 1438 (unaryfunc) Pympc_abs, /* nb_absolute */ 1439 (inquiry) Pympc_nonzero, /* nb_bool */ 1440 0, /* nb_invert */ 1441 0, /* nb_lshift */ 1442 0, /* nb_rshift */ 1443 0, /* nb_and */ 1444 0, /* nb_xor */ 1445 0, /* nb_or */ 1446 0, /* nb_coerce */ 1447 (unaryfunc) Pympc_To_PyIntOrLong, /* nb_int */ 1448 (unaryfunc) Pympc_To_PyLong, /* nb_long */ 1449 (unaryfunc) Pympc_To_PyFloat, /* nb_float */ 1450 0, /* nb_oct */ 1451 0, /* nb_hex */ 1452 0, /* nb_inplace_add */ 1453 0, /* nb_inplace_subtract */ 1454 0, /* nb_inplace_multiply */ 1455 0, /* nb_inplace_divide */ 1456 0, /* nb_inplace_remainder */ 1457 0, /* nb_inplace_power */ 1458 0, /* nb_inplace_lshift */ 1459 0, /* nb_inplace_rshift */ 1460 0, /* nb_inplace_and */ 1461 0, /* nb_inplace_xor */ 1462 0, /* nb_inplace_or */ 1463 (binaryfunc) Pybasic_floordiv, /* nb_floor_divide */ 1464 (binaryfunc) Pympc_truediv_fast, /* nb_true_divide */ 1465 0, /* nb_inplace_floor_divide */ 1466 0, /* nb_inplace_true_divide */ 1467}; 1468#endif 1469 1470static PyGetSetDef Pympc_getseters[] = 1471{ 1472 {"precision", (getter)Pympc_getprec_attrib, NULL, "precision in bits", NULL}, 1473 {"rc", (getter)Pympc_getrc_attrib, NULL, "return code", NULL}, 1474 {"imag", (getter)Pympc_getimag_attrib, NULL, "imaginary component", NULL}, 1475 {"real", (getter)Pympc_getreal_attrib, NULL, "real component", NULL}, 1476 {NULL} 1477}; 1478 1479static PyTypeObject Pympc_Type = 1480{ 1481 /* PyObject_HEAD_INIT(&PyType_Type) */ 1482#ifdef PY3 1483 PyVarObject_HEAD_INIT(NULL, 0) 1484#else 1485 PyObject_HEAD_INIT(0) 1486 0, /* ob_size */ 1487#endif 1488 "mpc", /* tp_name */ 1489 sizeof(PympcObject), /* tp_basicsize */ 1490 0, /* tp_itemsize */ 1491 /* methods */ 1492 (destructor) Pympc_dealloc, /* tp_dealloc */ 1493 0, /* tp_print */ 1494 0, /* tp_getattr */ 1495 0, /* tp_setattr */ 1496 0, /* tp_reserved */ 1497 (reprfunc) Pympc_To_Repr, /* tp_repr */ 1498 &mpc_number_methods, /* tp_as_number */ 1499 0, /* tp_as_sequence */ 1500 0, /* tp_as_mapping */ 1501 (hashfunc) Pympc_hash, /* tp_hash */ 1502 0, /* tp_call */ 1503 (reprfunc) Pympc_To_Str, /* tp_str */ 1504 0, /* tp_getattro */ 1505 0, /* tp_setattro */ 1506 0, /* tp_as_buffer */ 1507#ifdef PY3 1508 Py_TPFLAGS_DEFAULT, /* tp_flags */ 1509#else 1510 Py_TPFLAGS_HAVE_RICHCOMPARE|Py_TPFLAGS_CHECKTYPES, /* tp_flags */ 1511#endif 1512 "MPC-based complex number", /* tp_doc */ 1513 0, /* tp_traverse */ 1514 0, /* tp_clear */ 1515 (richcmpfunc)&mpany_richcompare, /* tp_richcompare */ 1516 0, /* tp_weaklistoffset*/ 1517 0, /* tp_iter */ 1518 0, /* tp_iternext */ 1519 Pympc_methods, /* tp_methods */ 1520 0, /* tp_members */ 1521 Pympc_getseters, /* tp_getset */ 1522}; 1523 1524