/src/gmpy_binary.c

http://gmpy.googlecode.com/ · C · 1175 lines · 884 code · 122 blank · 169 comment · 239 complexity · d113c4c7e8cc78bcb45c235ab25417e1 MD5 · raw file

  1. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2. * gmpy_binary.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. /* Conversion routines between GMPY2 objects and a compact, portable
  28. * binary representation. The binary format of GMPY2 is not compatible
  29. * with GMPY 1.x. Methods to read the old format are provided.
  30. */
  31. /* Provide functions to access the old binary formats. */
  32. PyDoc_STRVAR(doc_g_mpz_from_old_binary,
  33. "mpz_from_old_binary(string) -> mpz\n\n"
  34. "Return an 'mpz' from a GMPY 1.x binary format.");
  35. static PyObject *
  36. Pympz_From_Old_Binary(PyObject *self, PyObject *other)
  37. {
  38. unsigned char *cp;
  39. Py_ssize_t len;
  40. int negative = 0;
  41. PympzObject *result;
  42. if (!(PyBytes_Check(other))) {
  43. TYPE_ERROR("mpz_from_old_binary() requires bytes argument");
  44. return NULL;
  45. }
  46. if (!(result = (PympzObject*)Pympz_new()))
  47. return NULL;
  48. len = PyBytes_Size(other);
  49. cp = (unsigned char*)PyBytes_AsString(other);
  50. if (cp[len-1] == 0xFF) {
  51. negative = 1;
  52. --len;
  53. }
  54. mpz_import(result->z, len, -1, sizeof(char), 0, 0, cp);
  55. if (negative)
  56. mpz_neg(result->z, result->z);
  57. return (PyObject*)result;
  58. }
  59. PyDoc_STRVAR(doc_g_mpq_from_old_binary,
  60. "mpq_from_old_binary(string) -> mpq\n\n"
  61. "Return an 'mpq' from a GMPY 1.x binary format.");
  62. static PyObject *
  63. Pympq_From_Old_Binary(PyObject *self, PyObject *other)
  64. {
  65. unsigned char *cp;
  66. Py_ssize_t len;
  67. int topper, negative, numlen;
  68. mpz_t numerator, denominator;
  69. PympqObject *result;
  70. if (!(PyBytes_Check(other))) {
  71. TYPE_ERROR("mpq_from_old_binary() requires bytes argument");
  72. return NULL;
  73. }
  74. if (!(result = (PympqObject*)Pympq_new()))
  75. return NULL;
  76. len = PyBytes_Size(other);
  77. cp = (unsigned char*)PyBytes_AsString(other);
  78. if (len < 6) {
  79. VALUE_ERROR("invalid mpq binary (too short)");
  80. Py_DECREF((PyObject*)result);
  81. return NULL;
  82. }
  83. topper = cp[3] & 0x7f;
  84. negative = cp[3] & 0x80;
  85. numlen = cp[0] + 256 * (cp[1] + 256 * (cp[2] + 256 * topper));
  86. if (len < (4 + numlen + 1)) {
  87. VALUE_ERROR("invalid mpq binary (num len)");
  88. Py_DECREF((PyObject*)result);
  89. return NULL;
  90. }
  91. mpz_inoc(numerator);
  92. mpz_inoc(denominator);
  93. mpz_import(numerator, numlen, -1, sizeof(char), 0, 0, cp+4);
  94. mpz_import(denominator, len-4-numlen, -1, sizeof(char), 0, 0, cp+4+numlen);
  95. if (negative)
  96. mpz_neg(numerator, numerator);
  97. mpq_set_num(result->q, numerator);
  98. mpq_set_den(result->q, denominator);
  99. mpq_canonicalize(result->q);
  100. mpz_cloc(numerator);
  101. mpz_cloc(denominator);
  102. return (PyObject*)result;
  103. }
  104. #ifdef WITHMPFR
  105. PyDoc_STRVAR(doc_g_mpfr_from_old_binary,
  106. "mpfr_from_old_binary(string) -> mpfr\n\n"
  107. "Return an 'mpfr' from a GMPY 1.x binary mpf format.");
  108. static PyObject *
  109. Pympfr_From_Old_Binary(PyObject *self, PyObject *other)
  110. {
  111. unsigned char *cp;
  112. Py_ssize_t len;
  113. PympfrObject *result;
  114. mpfr_t digit;
  115. mpfr_prec_t prec;
  116. int i, codebyte, resusign, exposign, resuzero, precilen;
  117. unsigned int expomag = 0;
  118. if (!(PyBytes_Check(other))) {
  119. TYPE_ERROR("mpfr_from_old_binary() requires bytes argument");
  120. return NULL;
  121. }
  122. len = PyBytes_Size(other);
  123. cp = (unsigned char*)PyBytes_AsString(other);
  124. if (len == 1) {
  125. prec = 0;
  126. }
  127. else {
  128. prec = (mpfr_prec_t)(8 * (len - 5));
  129. if ((len>=5) && (cp[0]&8)) {
  130. prec = 0;
  131. for (i=4; i>0; --i) {
  132. prec = (prec << 8) | cp[i];
  133. }
  134. }
  135. }
  136. /*
  137. * binary format for MP floats: first, a code-byte, then, a LSB
  138. * 4-byte unsigned int (exponent magnitude), then the "mantissa"
  139. * (actually, "significand", but "mantissa" is the usual term...)
  140. * in MSB form.
  141. *
  142. * The codebyte encodes both the signs, exponent and result, or
  143. * also the zeroness of the result (in which case, nothing more).
  144. */
  145. codebyte = cp[0];
  146. resusign = codebyte & 1;
  147. exposign = codebyte & 2;
  148. resuzero = codebyte & 4;
  149. precilen = (codebyte & 8)?4:0;
  150. /* mpfr zero has a very compact (1-byte) binary encoding!-) */
  151. if (resuzero) {
  152. if (!(result = (PympfrObject*)Pympfr_new(prec)))
  153. return NULL;
  154. result->rc = mpfr_set_ui(result->f, 0, context->ctx.mpfr_round);
  155. return (PyObject*)result;
  156. }
  157. /* all other numbers are 6+ bytes: codebyte, 4-byte exp, 1+
  158. * bytes for the mantissa; check this string is 6+ bytes
  159. */
  160. if (len < 6 + precilen) {
  161. VALUE_ERROR("invalid mpf binary encoding (too short)");
  162. return NULL;
  163. }
  164. if (!(result = (PympfrObject*)Pympfr_new(prec)))
  165. return NULL;
  166. /* reconstruct exponent */
  167. for (i = 4 + precilen; i > precilen; --i) {
  168. expomag = (expomag<<8) | cp[i];
  169. }
  170. /* reconstruct 'mantissa' (significand) */
  171. mpfr_set_si(result->f, 0, context->ctx.mpfr_round);
  172. mpfr_init2(digit, prec);
  173. for (i = 5 + precilen; i<len; i++) {
  174. mpfr_set_ui(digit, cp[i], context->ctx.mpfr_round);
  175. mpfr_div_2ui(digit, digit, (unsigned long)((i-4-precilen) * 8),
  176. context->ctx.mpfr_round);
  177. mpfr_add(result->f, result->f, digit, context->ctx.mpfr_round);
  178. }
  179. mpfr_clear(digit);
  180. /* apply exponent, with its appropriate sign */
  181. if (exposign)
  182. mpfr_div_2ui(result->f, result->f, 8*expomag, context->ctx.mpfr_round);
  183. else
  184. mpfr_mul_2ui(result->f, result->f, 8*expomag, context->ctx.mpfr_round);
  185. /* apply significand-sign (sign of the overall number) */
  186. if (resusign)
  187. mpfr_neg(result->f, result->f, context->ctx.mpfr_round);
  188. return (PyObject*)result;
  189. }
  190. #endif
  191. /* Format of the binary representation of an mpz/xmpz.
  192. *
  193. * byte[0]: 1 => mpz
  194. * 2 => xmpz
  195. * 3 => mpq (see Pympq_To_Binary)
  196. * 4 => mpfr (see Pympfr_To_Binary)
  197. * 5 => mpc (see Pympc_To_Binary)
  198. * byte[1:0-1]: 0 => value is 0
  199. * 1 => value is > 0
  200. * 2 => value is < 0
  201. * 3 => unassigned
  202. * byte[2]+: value
  203. */
  204. static PyObject *
  205. Pympz_To_Binary(PympzObject *self)
  206. {
  207. size_t size = 2;
  208. int sgn;
  209. char *buffer;
  210. PyObject *result;
  211. sgn = mpz_sgn(self->z);
  212. if (sgn == 0) {
  213. TEMP_ALLOC(buffer, size);
  214. buffer[0] = 0x01;
  215. buffer[1] = 0x00;
  216. goto done;
  217. }
  218. size = ((mpz_sizeinbase(self->z, 2) + 7) / 8) + 2;
  219. TEMP_ALLOC(buffer, size);
  220. buffer[0] = 0x01;
  221. if (sgn > 0)
  222. buffer[1] = 0x01;
  223. else
  224. buffer[1] = 0x02;
  225. mpz_export(buffer+2, NULL, -1, sizeof(char), 0, 0, self->z);
  226. done:
  227. result = PyBytes_FromStringAndSize(buffer, size);
  228. TEMP_FREE(buffer, size);
  229. return result;
  230. }
  231. static PyObject *
  232. Pyxmpz_To_Binary(PyxmpzObject *self)
  233. {
  234. size_t size = 2;
  235. int sgn;
  236. char *buffer;
  237. PyObject *result;
  238. sgn = mpz_sgn(self->z);
  239. if (sgn == 0) {
  240. TEMP_ALLOC(buffer, size);
  241. buffer[0] = 0x02;
  242. buffer[1] = 0x00;
  243. goto done;
  244. }
  245. size = ((mpz_sizeinbase(self->z, 2) + 7) / 8) + 2;
  246. TEMP_ALLOC(buffer, size);
  247. buffer[0] = 0x02;
  248. if (sgn > 0)
  249. buffer[1] = 0x01;
  250. else
  251. buffer[1] = 0x02;
  252. mpz_export(buffer+2, NULL, -1, sizeof(char), 0, 0, self->z);
  253. done:
  254. result = PyBytes_FromStringAndSize(buffer, size);
  255. TEMP_FREE(buffer, size);
  256. return result;
  257. }
  258. /* Format of the binary representation of an mpq.
  259. *
  260. * byte[0]: 1 => mpz (see Pympz_To_Binary)
  261. * 2 => xmpz (see Pyxmpz_To_Binary)
  262. * 3 => mpq
  263. * 4 => mpfr (see Pympfr_To_Binary)
  264. * 5 => mpc (see Pympc_To_Binary)
  265. * byte[1:0-1]: 0 => value is 0
  266. * 1 => value is > 0
  267. * 2 => value is < 0
  268. * 3 => unassigned
  269. * byte[1:2-2]: 0 => 32-bit length (n=4)
  270. * 1 => 64-bit length (n=8)
  271. * byte[2+]: numerator length, using either 4 or 8 bytes
  272. * byte[2+n]+: numerator, followed by denominator
  273. */
  274. static PyObject *
  275. Pympq_To_Binary(PympqObject *self)
  276. {
  277. size_t sizenum, sizeden, sizesize = 4, size = 2, sizetemp, i;
  278. size_t count = 0;
  279. int sgn;
  280. char *buffer, large = 0x00;
  281. PyObject *result = 0;
  282. sgn = mpq_sgn(self->q);
  283. if (sgn == 0) {
  284. TEMP_ALLOC(buffer, size);
  285. buffer[0] = 0x03;
  286. buffer[1] = 0x00;
  287. goto done;
  288. }
  289. sizenum = (mpz_sizeinbase(mpq_numref(self->q), 2) + 7) / 8;
  290. sizeden = (mpz_sizeinbase(mpq_denref(self->q), 2) + 7) / 8;
  291. size = sizenum + sizeden + 2;
  292. /* Check if sizenum larger than 32 bits. */
  293. if ((sizenum >> 16) >> 16) {
  294. large = 0x04;
  295. sizesize = 8;
  296. }
  297. size += sizesize;
  298. TEMP_ALLOC(buffer, size);
  299. buffer[0] = 0x03;
  300. if (sgn > 0)
  301. buffer[1] = 0x01 | large;
  302. else
  303. buffer[1] = 0x02 | large;
  304. /* Copy sizenum to the buffer. */
  305. sizetemp = sizenum;
  306. for (i=0; i<sizesize; i++) {
  307. buffer[i+2] = (char)(sizetemp & 0xff);
  308. sizetemp >>= 8;
  309. }
  310. mpz_export(buffer+sizesize+2, &count, -1,
  311. sizeof(char), 0, 0, mpq_numref(self->q));
  312. if (count != sizenum) {
  313. SYSTEM_ERROR("internal error in Pympq_To_Binary");
  314. TEMP_FREE(buffer, size);
  315. return NULL;
  316. }
  317. count = 0;
  318. mpz_export(buffer+sizenum+sizesize+2, &count, -1,
  319. sizeof(char), 0, 0, mpq_denref(self->q));
  320. if (count != sizeden) {
  321. SYSTEM_ERROR("internal error in Pympq_To_Binary");
  322. TEMP_FREE(buffer, size);
  323. return NULL;
  324. }
  325. done:
  326. result = PyBytes_FromStringAndSize(buffer, size);
  327. TEMP_FREE(buffer, size);
  328. return result;
  329. }
  330. #ifdef WITHMPFR
  331. /* Format of the binary representation of an mpfr.
  332. *
  333. * byte[0]: 1 => mpz (see Pympz_To_Binary)
  334. * 2 => xmpz (see Pyxmpz_To_Binary)
  335. * 3 => mpq (see Pympq_To_Binary)
  336. * 4 => mpfr
  337. * 5 => mpc (see Pympc_To_Binary)
  338. * byte[1:0]: 0 => value is "special"
  339. * 1 => value is an actual number
  340. * byte[1:1]: 0 => signbit is clear
  341. * 1 => signbit is set
  342. * byte[1:2-2]: 0 => 32-bit lengths (n=4)
  343. * 1 => 64-bit lengths (n=8)
  344. * byte[1:3-4]: 0 => 0 (see signbit)
  345. * 1 => value is NaN
  346. * 2 => value is Inf (see signbit)
  347. * 3 => unassigned
  348. * byte[1:5]: 0 => exponent is positive
  349. * 1 => exponent is negative
  350. * byte[1:6]: 0 => 4 byte limbs
  351. * 1 => 8 byte limbs
  352. * byte[2]: 0 => rc = 0
  353. * 1 => rc > 0
  354. * 2 => rc < 0
  355. * byte[3]: mpfr.round_mode
  356. * byte[4]+: precision, saved in 4 or 8 bytes
  357. * byte[4+n]+: exponent, saved in 4 or 8 bytes
  358. * byte[4+2n]+: mantissa
  359. */
  360. static PyObject *
  361. Pympfr_To_Binary(PympfrObject *self)
  362. {
  363. size_t sizemant = 0, sizesize = 4, size = 4, sizetemp, i;
  364. mp_limb_t templimb;
  365. mpfr_prec_t precision;
  366. mpfr_exp_t exponent = 0;
  367. int sgn;
  368. char *buffer, *cp, large = 0x00, expsgn = 0x00;
  369. PyObject *result = 0;
  370. /* Check if the precision, exponent and mantissa length can fit in
  371. * 32 bits.
  372. */
  373. sgn = mpfr_signbit(self->f);
  374. precision = mpfr_get_prec(self->f);
  375. /* Exponent and mantiss are only valid for regular numbers
  376. * (not 0, Nan, Inf, -Inf).
  377. */
  378. if (mpfr_regular_p(self->f)) {
  379. exponent = self->f->_mpfr_exp;
  380. if (exponent < 0) {
  381. exponent = -exponent;
  382. expsgn = 0x20;
  383. }
  384. /* Calculate the size of mantissa in limbs */
  385. sizemant = (self->f->_mpfr_prec + mp_bits_per_limb - 1)/mp_bits_per_limb;
  386. }
  387. if (((exponent >> 16) >> 16) ||
  388. ((precision >> 16) >> 16) ||
  389. ((sizemant >> 16) >> 16)) {
  390. sizesize = 8;
  391. large = 0x04;
  392. }
  393. if (!mpfr_regular_p(self->f)) {
  394. /* Only need to save the precision. */
  395. size += sizesize;
  396. TEMP_ALLOC(buffer, size);
  397. buffer[0] = 0x04;
  398. /* Set to all 0 since we are special. */
  399. buffer[1] = 0x00;
  400. /* Set the sign bit. */
  401. if (sgn) buffer[1] |= 0x02;
  402. /* 4 or 8 byte values. */
  403. buffer[1] |= large;
  404. /* Check if NaN. */
  405. if (mpfr_nan_p(self->f)) buffer[1] |= 0x08;
  406. /* Check if Infinity. */
  407. if (mpfr_inf_p(self->f)) buffer[1] |= 0x10;
  408. /* Save the result code */
  409. if (self->rc == 0) buffer[2] = 0x00;
  410. else if (self->rc > 0) buffer[2] = 0x01;
  411. else buffer[2] = 0x02;
  412. /* Save the rounding mode active when the mpfr was created. */
  413. buffer[3] = (char)(self->round_mode);
  414. /* Save the precision */
  415. sizetemp = precision;
  416. for (i=0; i<sizesize; i++) {
  417. buffer[i+4] = (char)(sizetemp & 0xff);
  418. sizetemp >>= 8;
  419. }
  420. goto done;
  421. }
  422. /* Now process all actual numbers. */
  423. size += (2 * sizesize) + (sizemant * (mp_bits_per_limb >> 3));
  424. TEMP_ALLOC(buffer, size);
  425. buffer[0] = 0x04;
  426. /* Set bit 0 to 1 since we are an actual number. */
  427. buffer[1] = 0x01;
  428. /* Save the sign bit. */
  429. if (sgn) buffer[1] |= 0x02;
  430. /* Save the size of the values. */
  431. buffer[1] |= large;
  432. /* Save the exponent sign. */
  433. buffer[1] |= expsgn;
  434. /* Save the limb size. */
  435. if ((mp_bits_per_limb >> 3) == 8)
  436. buffer[1] |= 0x40;
  437. else if ((mp_bits_per_limb >> 3) != 4) {
  438. SYSTEM_ERROR("cannot support current limb size");
  439. TEMP_FREE(buffer, size);
  440. return NULL;
  441. }
  442. /* Save the result code. */
  443. if (self->rc == 0) buffer[2] = 0x00;
  444. else if (self->rc > 0) buffer[2] = 0x01;
  445. else buffer[2] = 0x02;
  446. /* Save the original rounding mode. */
  447. buffer[3] = (char)(self->round_mode);
  448. /* Save the precision */
  449. cp = buffer + 4;
  450. sizetemp = precision;
  451. for (i=0; i<sizesize; i++) {
  452. cp[i] = (char)(sizetemp & 0xff);
  453. sizetemp >>= 8;
  454. }
  455. /* Save the exponenet */
  456. cp += sizesize;
  457. sizetemp = exponent;
  458. for (i=0; i<sizesize; i++) {
  459. cp[i] = (char)(sizetemp & 0xff);
  460. sizetemp >>= 8;
  461. }
  462. /* Save the actual mantissa */
  463. cp += sizesize;
  464. for (i=0; i<sizemant; i++) {
  465. templimb = self->f->_mpfr_d[i];
  466. #if GMP_LIMB_BITS == 64
  467. cp[0] = (char)(templimb & 0xff);
  468. templimb >>= 8;
  469. cp[1] = (char)(templimb & 0xff);
  470. templimb >>= 8;
  471. cp[2] = (char)(templimb & 0xff);
  472. templimb >>= 8;
  473. cp[3] = (char)(templimb & 0xff);
  474. templimb >>= 8;
  475. cp[4] = (char)(templimb & 0xff);
  476. templimb >>= 8;
  477. cp[5] = (char)(templimb & 0xff);
  478. templimb >>= 8;
  479. cp[6] = (char)(templimb & 0xff);
  480. templimb >>= 8;
  481. cp[7] = (char)(templimb & 0xff);
  482. cp += 8;
  483. #endif
  484. #if GMP_LIMB_BITS == 32
  485. cp[0] = (char)(templimb & 0xff);
  486. templimb >>= 8;
  487. cp[1] = (char)(templimb & 0xff);
  488. templimb >>= 8;
  489. cp[2] = (char)(templimb & 0xff);
  490. templimb >>= 8;
  491. cp[3] = (char)(templimb & 0xff);
  492. cp += 4;
  493. #endif
  494. }
  495. done:
  496. result = PyBytes_FromStringAndSize(buffer, size);
  497. TEMP_FREE(buffer, size);
  498. return result;
  499. }
  500. #endif
  501. #ifdef WITHMPC
  502. /* Format of the binary representation of an mpc.
  503. *
  504. * The format consists of the concatenation of mpfrs (real and imaginary)
  505. * converted to binary format. The 0x04 leading byte of each binary string
  506. * is replaced by 0x05.
  507. */
  508. static PyObject *
  509. Pympc_To_Binary(PympcObject *self)
  510. {
  511. PympfrObject *real = 0, *imag = 0;
  512. PyObject *result = 0, *temp = 0;
  513. mpfr_prec_t rprec = 0, cprec = 0;
  514. mpc_get_prec2(&rprec, &cprec, self->c);
  515. real = (PympfrObject*)Pympfr_new(rprec);
  516. imag = (PympfrObject*)Pympfr_new(cprec);
  517. if (!real || !imag) {
  518. Py_XDECREF((PyObject*)real);
  519. Py_XDECREF((PyObject*)imag);
  520. return NULL;
  521. }
  522. mpfr_set(real->f, mpc_realref(self->c), MPFR_RNDN);
  523. mpfr_set(imag->f, mpc_imagref(self->c), MPFR_RNDN);
  524. real->rc = self->rc;
  525. real->round_mode = self->round_mode;
  526. result = Pympfr_To_Binary(real);
  527. temp = Pympfr_To_Binary(imag);
  528. Py_DECREF((PyObject*)real);
  529. Py_DECREF((PyObject*)imag);
  530. if (!result || !temp) {
  531. Py_XDECREF((PyObject*)result);
  532. Py_XDECREF((PyObject*)temp);
  533. return NULL;
  534. }
  535. PyBytes_AS_STRING(result)[0] = 0x05;
  536. PyBytes_AS_STRING(temp)[0] = 0x05;
  537. PyBytes_ConcatAndDel(&result, temp);
  538. return result;
  539. }
  540. #endif
  541. PyDoc_STRVAR(doc_from_binary,
  542. "from_binary(bytes) -> gmpy2 object\n"
  543. "Return a Python object from a byte sequence created by\n"
  544. "gmpy2.to_binary().");
  545. static PyObject *
  546. Pympany_From_Binary(PyObject *self, PyObject *other)
  547. {
  548. unsigned char *buffer, *cp;
  549. Py_ssize_t len;
  550. if (!(PyBytes_Check(other))) {
  551. TYPE_ERROR("from_binary() requires bytes argument");
  552. return NULL;
  553. }
  554. len = PyBytes_Size(other);
  555. if (len < 2) {
  556. VALUE_ERROR("byte sequence too short for from_binary()");
  557. return NULL;
  558. }
  559. buffer = (unsigned char*)PyBytes_AsString(other);
  560. cp = buffer;
  561. switch (cp[0]) {
  562. case 0x01: {
  563. PympzObject *result;
  564. if (!(result = (PympzObject*)Pympz_new()))
  565. return NULL;
  566. if (cp[1] == 0x00) {
  567. mpz_set_ui(result->z, 0);
  568. return (PyObject*)result;
  569. }
  570. mpz_import(result->z, len-2, -1, sizeof(char), 0, 0, cp+2);
  571. if (cp[1] == 0x02)
  572. mpz_neg(result->z, result->z);
  573. return (PyObject*)result;
  574. break;
  575. }
  576. case 0x02: {
  577. PyxmpzObject *result;
  578. if (!(result = (PyxmpzObject*)Pyxmpz_new()))
  579. return NULL;
  580. if (cp[1] == 0x00) {
  581. mpz_set_ui(result->z, 0);
  582. return (PyObject*)result;
  583. }
  584. mpz_import(result->z, len-2, -1, sizeof(char), 0, 0, cp+2);
  585. if (cp[1] == 0x02)
  586. mpz_neg(result->z, result->z);
  587. return (PyObject*)result;
  588. break;
  589. }
  590. case 0x03: {
  591. PympqObject *result;
  592. size_t numlen = 0, sizesize = 4, i;
  593. mpz_t num, den;
  594. if (!(result = (PympqObject*)Pympq_new()))
  595. return NULL;
  596. if (cp[1] == 0x00) {
  597. mpq_set_ui(result->q, 0, 1);
  598. return (PyObject*)result;
  599. }
  600. if (cp[1] & 0x04)
  601. sizesize = 8;
  602. if (len < 2 + sizesize) {
  603. VALUE_ERROR("byte sequence too short for from_binary()");
  604. return NULL;
  605. }
  606. for (i=sizesize; i>0; --i) {
  607. numlen = (numlen << 8) + cp[i+1];
  608. }
  609. if (len < 2 + sizesize + numlen + 1) {
  610. VALUE_ERROR("byte sequence too short for from_binary()");
  611. return NULL;
  612. }
  613. mpz_inoc(num);
  614. mpz_inoc(den);
  615. mpz_import(num, numlen, -1,
  616. sizeof(char), 0, 0, cp+sizesize+2);
  617. mpz_import(den, len-numlen-sizesize-2, -1,
  618. sizeof(char), 0, 0, cp+sizesize+numlen+2);
  619. mpq_set_num(result->q, num);
  620. mpq_set_den(result->q, den);
  621. mpq_canonicalize(result->q);
  622. mpz_cloc(num);
  623. mpz_cloc(den);
  624. if (cp[1] == 0x02)
  625. mpq_neg(result->q, result->q);
  626. return (PyObject*)result;
  627. break;
  628. }
  629. case 0x04: {
  630. #ifndef WITHMPFR
  631. VALUE_ERROR("creating 'mpfr' object not supported");
  632. return NULL;
  633. }
  634. #else
  635. PympfrObject *result;
  636. size_t sizemant = 0, sizesize = 4, i, newmant;
  637. mpfr_prec_t precision = 0;
  638. mpfr_exp_t exponent = 0;
  639. mp_limb_t templimb;
  640. int sgn = 1, expsgn = 1, limbsize = 4;
  641. int newlimbsize = (mp_bits_per_limb >> 3);
  642. if (len < 4) {
  643. VALUE_ERROR("byte sequence too short for from_binary()");
  644. return NULL;
  645. }
  646. /* Get size of values. */
  647. if (cp[1] & 0x04) sizesize = 8;
  648. /* Get the original precision. */
  649. for (i=sizesize; i>0; --i) {
  650. precision = (precision << 8) + cp[i+3];
  651. }
  652. /* Get the original sign bit. */
  653. if (cp[1] & 0x02) sgn = -1;
  654. /* Get the original exponent sign. */
  655. if (cp[1] & 0x20) expsgn = -1;
  656. /* Get the limb size of the originating system. */
  657. if (cp[1] & 0x40) limbsize = 8;
  658. if (!(result = (PympfrObject*)Pympfr_new(precision)))
  659. return NULL;
  660. /* Restore the original result code and rounding mode. */
  661. /* Get the original result code. */
  662. if (cp[2] == 0) result->rc = 0;
  663. else if (cp[2] == 1) result->rc = 1;
  664. else result->rc = -1;
  665. /* Get the original rounding mode. */
  666. result->round_mode = cp[3];
  667. if (!(cp[1] & 0x01)) {
  668. /* Process special numbers. */
  669. if ((cp[1] & 0x18) == 0x00)
  670. mpfr_set_zero(result->f, sgn);
  671. else if ((cp[1] & 0x18) == 0x08)
  672. mpfr_set_nan(result->f);
  673. else
  674. mpfr_set_inf(result->f, sgn);
  675. return (PyObject*)result;
  676. }
  677. /* Process actual numbers. */
  678. /* Calculate the number of limbs on the original system. */
  679. if (limbsize == 8) sizemant = ((precision + 63) / 64);
  680. else sizemant = ((precision + 31) / 32);
  681. /* Calculate the number of limbs on the current system. */
  682. newmant = (precision + mp_bits_per_limb - 1) / mp_bits_per_limb;
  683. /* Get the original exponent. */
  684. cp = buffer + 4 + sizesize - 1;
  685. for (i=sizesize; i>0; --i) {
  686. exponent = (exponent << 8) + cp[i];
  687. }
  688. if (len < 2 + sizesize) {
  689. VALUE_ERROR("byte sequence too short for from_binary()");
  690. return NULL;
  691. }
  692. /* Check if the mantissa occupies the same number of bytes
  693. * on both the source and target system. */
  694. if (limbsize * sizemant == newmant * newlimbsize) {
  695. mpfr_set_ui(result->f, 1, MPFR_RNDN);
  696. cp = buffer + 4 + (2 * sizesize);
  697. for (i=0; i<newmant; i++) {
  698. #if GMP_LIMB_BITS == 64
  699. templimb = cp[7];
  700. templimb = (templimb << 8) + cp[6];
  701. templimb = (templimb << 8) + cp[5];
  702. templimb = (templimb << 8) + cp[4];
  703. templimb = (templimb << 8) + cp[3];
  704. templimb = (templimb << 8) + cp[2];
  705. templimb = (templimb << 8) + cp[1];
  706. templimb = (templimb << 8) + cp[0];
  707. #endif
  708. #if GMP_LIMB_BITS == 32
  709. templimb = cp[3];
  710. templimb = (templimb << 8) + cp[2];
  711. templimb = (templimb << 8) + cp[1];
  712. templimb = (templimb << 8) + cp[0];
  713. #endif
  714. result->f->_mpfr_d[i] = templimb;
  715. cp += newlimbsize;
  716. }
  717. result->f->_mpfr_exp = expsgn * exponent;
  718. if (sgn == -1)
  719. mpfr_neg(result->f, result->f, MPFR_RNDN);
  720. return (PyObject*)result;
  721. }
  722. else if (limbsize * sizemant > newmant * newlimbsize) {
  723. /* Since the amount of saved data is greater than the amount of
  724. * data needed on the new system, we skip the first 32 bits
  725. * since they must be 0.
  726. */
  727. /* Verify we are on a 32-bit system and the source was 64-bit. */
  728. if ((limbsize == 8) && (newlimbsize == 4)) {
  729. VALUE_ERROR("byte sequence invalid for from_binary()");
  730. return NULL;
  731. }
  732. mpfr_set_ui(result->f, 1, MPFR_RNDN);
  733. cp = buffer + 4 + (2 * sizesize) + 4;
  734. for (i=0; i<newmant; i++) {
  735. templimb = cp[3];
  736. templimb = (templimb << 8) + cp[2];
  737. templimb = (templimb << 8) + cp[1];
  738. templimb = (templimb << 8) + cp[0];
  739. result->f->_mpfr_d[i] = templimb;
  740. cp += newlimbsize;
  741. }
  742. result->f->_mpfr_exp = expsgn * exponent;
  743. if (sgn == -1)
  744. mpfr_neg(result->f, result->f, MPFR_RNDN);
  745. return (PyObject*)result;
  746. }
  747. else {
  748. /* Since the amount of saved data is less than the amount of
  749. * data needed on the new system, we must "add" 32 0-bits at
  750. * the low end.
  751. */
  752. /* Verify we are on a 64-bit system and the source was 32-bit. */
  753. if ((limbsize == 4) && (newlimbsize == 8)) {
  754. VALUE_ERROR("byte sequence invalid for from_binary()");
  755. return NULL;
  756. }
  757. mpfr_set_ui(result->f, 1, MPFR_RNDN);
  758. cp = buffer + 4 + (2 * sizesize);
  759. templimb = cp[3];
  760. templimb = (templimb << 8) + cp[2];
  761. templimb = (templimb << 8) + cp[1];
  762. templimb = (templimb << 8) + cp[0];
  763. result->f->_mpfr_d[i] = ((templimb << 16) << 16);
  764. cp += 4;
  765. for (i=0; i<newmant-1; i++) {
  766. templimb = cp[7];
  767. templimb = (templimb << 8) + cp[6];
  768. templimb = (templimb << 8) + cp[5];
  769. templimb = (templimb << 8) + cp[4];
  770. templimb = (templimb << 8) + cp[3];
  771. templimb = (templimb << 8) + cp[2];
  772. templimb = (templimb << 8) + cp[1];
  773. templimb = (templimb << 8) + cp[0];
  774. result->f->_mpfr_d[i] = templimb;
  775. cp += newlimbsize;
  776. }
  777. result->f->_mpfr_exp = expsgn * exponent;
  778. if (sgn == -1)
  779. mpfr_neg(result->f, result->f, MPFR_RNDN);
  780. return (PyObject*)result;
  781. }
  782. }
  783. #endif
  784. case 0x05: {
  785. #ifndef WITHMPC
  786. VALUE_ERROR("creating 'mpc' object not supported");
  787. return NULL;
  788. }
  789. #else
  790. PympcObject *result;
  791. PympfrObject *real = 0, *imag = 0;
  792. size_t sizemant = 0, sizesize = 4, i, newmant;
  793. mpfr_prec_t precision = 0;
  794. mpfr_exp_t exponent = 0;
  795. mp_limb_t templimb;
  796. int sgn = 1, expsgn = 1, limbsize = 4;
  797. int newlimbsize = (mp_bits_per_limb >> 3);
  798. unsigned char *tempbuf;
  799. if (len < 4) {
  800. VALUE_ERROR("byte sequence too short for from_binary()");
  801. return NULL;
  802. }
  803. /* read the real part first */
  804. if (cp[1] & 0x04) sizesize = 8;
  805. for (i=sizesize; i>0; --i) {
  806. precision = (precision << 8) + cp[i+3];
  807. }
  808. if (cp[1] & 0x02) sgn = -1;
  809. if (cp[1] & 0x20) expsgn = -1;
  810. if (cp[1] & 0x40) limbsize = 8;
  811. if (!(real = (PympfrObject*)Pympfr_new(precision)))
  812. return NULL;
  813. if (cp[2] == 0) real->rc = 0;
  814. else if (cp[2] == 1) real->rc = 1;
  815. else real->rc = -1;
  816. real->round_mode = cp[3];
  817. if (!(cp[1] & 0x01)) {
  818. if ((cp[1] & 0x18) == 0x00)
  819. mpfr_set_zero(real->f, sgn);
  820. else if ((cp[1] & 0x18) == 0x08)
  821. mpfr_set_nan(real->f);
  822. else
  823. mpfr_set_inf(real->f, sgn);
  824. cp += 4 + sizesize;
  825. goto readimag;
  826. }
  827. if (limbsize == 8) sizemant = ((precision + 63) / 64);
  828. else sizemant = ((precision + 31) / 32);
  829. newmant = (precision + mp_bits_per_limb - 1) / mp_bits_per_limb;
  830. cp = buffer + 4 + sizesize - 1;
  831. for (i=sizesize; i>0; --i) {
  832. exponent = (exponent << 8) + cp[i];
  833. }
  834. if (limbsize * sizemant == newmant * newlimbsize) {
  835. mpfr_set_ui(real->f, 1, MPFR_RNDN);
  836. cp = buffer + 4 + (2 * sizesize);
  837. for (i=0; i<newmant; i++) {
  838. #if GMP_LIMB_BITS == 64
  839. templimb = cp[7];
  840. templimb = (templimb << 8) + cp[6];
  841. templimb = (templimb << 8) + cp[5];
  842. templimb = (templimb << 8) + cp[4];
  843. templimb = (templimb << 8) + cp[3];
  844. templimb = (templimb << 8) + cp[2];
  845. templimb = (templimb << 8) + cp[1];
  846. templimb = (templimb << 8) + cp[0];
  847. #endif
  848. #if GMP_LIMB_BITS == 32
  849. templimb = cp[3];
  850. templimb = (templimb << 8) + cp[2];
  851. templimb = (templimb << 8) + cp[1];
  852. templimb = (templimb << 8) + cp[0];
  853. #endif
  854. real->f->_mpfr_d[i] = templimb;
  855. cp += newlimbsize;
  856. }
  857. real->f->_mpfr_exp = expsgn * exponent;
  858. if (sgn == -1)
  859. mpfr_neg(real->f, real->f, MPFR_RNDN);
  860. }
  861. else if (limbsize * sizemant > newmant * newlimbsize) {
  862. if ((limbsize == 8) && (newlimbsize == 4)) {
  863. VALUE_ERROR("byte sequence invalid for from_binary()");
  864. Py_DECREF((PyObject*)real);
  865. return NULL;
  866. }
  867. mpfr_set_ui(real->f, 1, MPFR_RNDN);
  868. cp = buffer + 4 + (2 * sizesize) + 4;
  869. for (i=0; i<newmant; i++) {
  870. templimb = cp[3];
  871. templimb = (templimb << 8) + cp[2];
  872. templimb = (templimb << 8) + cp[1];
  873. templimb = (templimb << 8) + cp[0];
  874. real->f->_mpfr_d[i] = templimb;
  875. cp += newlimbsize;
  876. }
  877. real->f->_mpfr_exp = expsgn * exponent;
  878. if (sgn == -1)
  879. mpfr_neg(real->f, real->f, MPFR_RNDN);
  880. }
  881. else {
  882. if ((limbsize == 4) && (newlimbsize == 8)) {
  883. VALUE_ERROR("byte sequence invalid for from_binary()");
  884. Py_DECREF((PyObject*)real);
  885. return NULL;
  886. }
  887. mpfr_set_ui(real->f, 1, MPFR_RNDN);
  888. cp = buffer + 4 + (2 * sizesize);
  889. templimb = cp[3];
  890. templimb = (templimb << 8) + cp[2];
  891. templimb = (templimb << 8) + cp[1];
  892. templimb = (templimb << 8) + cp[0];
  893. real->f->_mpfr_d[i] = ((templimb << 16) << 16);
  894. cp += 4;
  895. for (i=0; i<newmant-1; i++) {
  896. templimb = cp[7];
  897. templimb = (templimb << 8) + cp[6];
  898. templimb = (templimb << 8) + cp[5];
  899. templimb = (templimb << 8) + cp[4];
  900. templimb = (templimb << 8) + cp[3];
  901. templimb = (templimb << 8) + cp[2];
  902. templimb = (templimb << 8) + cp[1];
  903. templimb = (templimb << 8) + cp[0];
  904. real->f->_mpfr_d[i] = templimb;
  905. cp += newlimbsize;
  906. }
  907. real->f->_mpfr_exp = expsgn * exponent;
  908. if (sgn == -1)
  909. mpfr_neg(real->f, real->f, MPFR_RNDN);
  910. }
  911. readimag:
  912. /* Set all the variables back to default. */
  913. tempbuf = cp;
  914. sizemant = 0;
  915. sizesize = 4;
  916. precision = 0;
  917. exponent = 0;
  918. sgn = 1;
  919. expsgn = 1;
  920. limbsize = 4;
  921. /* Done reading the real part. The next byte should be 0x05. */
  922. if (!(cp[0] == 0x05)) {
  923. VALUE_ERROR("byte sequence invalid for from_binary()");
  924. Py_DECREF((PyObject*)real);
  925. return NULL;
  926. }
  927. if (cp[1] & 0x04) sizesize = 8;
  928. for (i=sizesize; i>0; --i) {
  929. precision = (precision << 8) + cp[i+3];
  930. }
  931. if (cp[1] & 0x02) sgn = -1;
  932. if (cp[1] & 0x20) expsgn = -1;
  933. if (cp[1] & 0x40) limbsize = 8;
  934. if (!(imag = (PympfrObject*)Pympfr_new(precision)))
  935. return NULL;
  936. if (cp[2] == 0) imag->rc = 0;
  937. else if (cp[2] == 1) imag->rc = 1;
  938. else imag->rc = -1;
  939. imag->round_mode = cp[3];
  940. if (!(cp[1] & 0x01)) {
  941. if ((cp[1] & 0x18) == 0x00)
  942. mpfr_set_zero(imag->f, sgn);
  943. else if ((cp[1] & 0x18) == 0x08)
  944. mpfr_set_nan(imag->f);
  945. else
  946. mpfr_set_inf(imag->f, sgn);
  947. goto alldone;
  948. }
  949. if (limbsize == 8) sizemant = ((precision + 63) / 64);
  950. else sizemant = ((precision + 31) / 32);
  951. newmant = (precision + mp_bits_per_limb - 1) / mp_bits_per_limb;
  952. cp = tempbuf + 4 + sizesize - 1;
  953. for (i=sizesize; i>0; --i) {
  954. exponent = (exponent << 8) + cp[i];
  955. }
  956. if (limbsize * sizemant == newmant * newlimbsize) {
  957. mpfr_set_ui(imag->f, 1, MPFR_RNDN);
  958. cp = tempbuf + 4 + (2 * sizesize);
  959. for (i=0; i<newmant; i++) {
  960. #if GMP_LIMB_BITS == 64
  961. templimb = cp[7];
  962. templimb = (templimb << 8) + cp[6];
  963. templimb = (templimb << 8) + cp[5];
  964. templimb = (templimb << 8) + cp[4];
  965. templimb = (templimb << 8) + cp[3];
  966. templimb = (templimb << 8) + cp[2];
  967. templimb = (templimb << 8) + cp[1];
  968. templimb = (templimb << 8) + cp[0];
  969. #endif
  970. #if GMP_LIMB_BITS == 32
  971. templimb = cp[3];
  972. templimb = (templimb << 8) + cp[2];
  973. templimb = (templimb << 8) + cp[1];
  974. templimb = (templimb << 8) + cp[0];
  975. #endif
  976. imag->f->_mpfr_d[i] = templimb;
  977. cp += newlimbsize;
  978. }
  979. imag->f->_mpfr_exp = expsgn * exponent;
  980. if (sgn == -1)
  981. mpfr_neg(imag->f, imag->f, MPFR_RNDN);
  982. }
  983. else if (limbsize * sizemant > newmant * newlimbsize) {
  984. if ((limbsize == 8) && (newlimbsize == 4)) {
  985. VALUE_ERROR("byte sequence invalid for from_binary()");
  986. Py_DECREF((PyObject*)real);
  987. Py_DECREF((PyObject*)imag);
  988. return NULL;
  989. }
  990. mpfr_set_ui(imag->f, 1, MPFR_RNDN);
  991. cp = tempbuf + 4 + (2 * sizesize) + 4;
  992. for (i=0; i<newmant; i++) {
  993. templimb = cp[3];
  994. templimb = (templimb << 8) + cp[2];
  995. templimb = (templimb << 8) + cp[1];
  996. templimb = (templimb << 8) + cp[0];
  997. imag->f->_mpfr_d[i] = templimb;
  998. cp += newlimbsize;
  999. }
  1000. imag->f->_mpfr_exp = expsgn * exponent;
  1001. if (sgn == -1)
  1002. mpfr_neg(imag->f, imag->f, MPFR_RNDN);
  1003. }
  1004. else {
  1005. if ((limbsize == 4) && (newlimbsize == 8)) {
  1006. VALUE_ERROR("byte sequence invalid for from_binary()");
  1007. Py_DECREF((PyObject*)real);
  1008. Py_DECREF((PyObject*)imag);
  1009. return NULL;
  1010. }
  1011. mpfr_set_ui(imag->f, 1, MPFR_RNDN);
  1012. cp = tempbuf + 4 + (2 * sizesize);
  1013. templimb = cp[3];
  1014. templimb = (templimb << 8) + cp[2];
  1015. templimb = (templimb << 8) + cp[1];
  1016. templimb = (templimb << 8) + cp[0];
  1017. imag->f->_mpfr_d[i] = ((templimb << 16) << 16);
  1018. cp += 4;
  1019. for (i=0; i<newmant-1; i++) {
  1020. templimb = cp[7];
  1021. templimb = (templimb << 8) + cp[6];
  1022. templimb = (templimb << 8) + cp[5];
  1023. templimb = (templimb << 8) + cp[4];
  1024. templimb = (templimb << 8) + cp[3];
  1025. templimb = (templimb << 8) + cp[2];
  1026. templimb = (templimb << 8) + cp[1];
  1027. templimb = (templimb << 8) + cp[0];
  1028. imag->f->_mpfr_d[i] = templimb;
  1029. cp += newlimbsize;
  1030. }
  1031. imag->f->_mpfr_exp = expsgn * exponent;
  1032. if (sgn == -1)
  1033. mpfr_neg(imag->f, imag->f, MPFR_RNDN);
  1034. }
  1035. alldone:
  1036. if (!(result = (PympcObject*)Pympc_new(0,0))) {
  1037. Py_DECREF((PyObject*)real);
  1038. Py_DECREF((PyObject*)imag);
  1039. return NULL;
  1040. }
  1041. mpfr_swap(mpc_realref(result->c), real->f);
  1042. mpfr_swap(mpc_imagref(result->c), imag->f);
  1043. Py_DECREF((PyObject*)real);
  1044. Py_DECREF((PyObject*)imag);
  1045. return (PyObject*)result;
  1046. }
  1047. #endif
  1048. default: {
  1049. TYPE_ERROR("from_binary() argument type not supported");
  1050. return NULL;
  1051. }
  1052. }
  1053. }