/src/gmpy_mpc.c

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