mp.c
资源名称:c.rar [点击查看]
上传用户:shmaik
上传日期:2014-06-01
资源大小:45093k
文件大小:16k
源码类别:

VC书籍

开发平台:

C/C++

  1. static char rcsid[] = "$Id: H:/drh/idioms/book/RCS/mp.doc,v 1.11 1996/06/26 23:02:01 drh Exp $";
  2. #include <ctype.h>
  3. #include <string.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <limits.h>
  7. #include "assert.h"
  8. #include "fmt.h"
  9. #include "mem.h"
  10. #include "xp.h"
  11. #include "mp.h"
  12. #define T MP_T
  13. #define sign(x) ((x)[nbytes-1]>>shift)
  14. #define ones(n) (~(~0UL<<(((n)-1)%8+1)))
  15. #define iszero(x) (XP_length(nbytes,(x))==1 && (x)[0]==0)
  16. #define BASE (1<<8)
  17. #define bitop(op) 
  18. int i; assert(z); assert(x); assert(y); 
  19. for (i = 0; i < nbytes; i++) z[i] = x[i] op y[i]; 
  20. return z
  21. #define bitopi(op) assert(z); assert(x); 
  22. applyu(op, z, x, y); 
  23. return z
  24. #define shft(fill, op) 
  25. assert(x); assert(z); assert(s >= 0); 
  26. if (s >= nbits) memset(z, fill, nbytes); 
  27. else op(nbytes, z, nbytes, x, s, fill); 
  28. z[nbytes-1] &= msb; 
  29. return z
  30. const Except_T MP_Dividebyzero = { "Division by zero" };
  31. const Except_T MP_Overflow     = { "Overflow" };
  32. static int nbits  =  32;
  33. static int nbytes = (32-1)/8 + 1;
  34. static int shift  = (32-1)%8;
  35. static unsigned char msb = 0xFF;
  36. static unsigned char temp[16 + 16 + 16 + 2*16+2];
  37. static T tmp[] = {temp, temp+1*16, temp+2*16, temp+3*16};
  38. static int applyu(T op(T, T, T), T z, T x,
  39. unsigned long u) {
  40. unsigned long carry;
  41. { T z = tmp[2]; carry = XP_fromint(nbytes, z, u);
  42. carry |= z[nbytes-1]&~msb;
  43. z[nbytes-1] &= msb; }
  44. op(z, x, tmp[2]);
  45. return carry != 0;
  46. }
  47. static int apply(T op(T, T, T), T z, T x, long v) {
  48. { T z = tmp[2]; if (v == LONG_MIN) {
  49. XP_fromint(nbytes, z, LONG_MAX + 1UL);
  50. XP_neg(nbytes, z, z, 1);
  51. } else if (v < 0) {
  52. XP_fromint(nbytes, z, -v);
  53. XP_neg(nbytes, z, z, 1);
  54. } else
  55. XP_fromint(nbytes, z, v);
  56. z[nbytes-1] &= msb; }
  57. op(z, x, tmp[2]);
  58. return (nbits < 8*(int)sizeof (v) &&
  59.         (v < -(1L<<(nbits-1)) || v >= (1L<<(nbits-1))));
  60. }
  61. int MP_set(int n) {
  62. int prev = nbits;
  63. assert(n > 1);
  64. nbits  = n;
  65. nbytes = (n-1)/8 + 1;
  66. shift  = (n-1)%8;
  67. msb    = ones(n);
  68. if (tmp[0] != temp)
  69. FREE(tmp[0]);
  70. if (nbytes <= 16)
  71. tmp[0] = temp;
  72. else
  73. tmp[0] = ALLOC(3*nbytes + 2*nbytes + 2);
  74. tmp[1] = tmp[0] + 1*nbytes;
  75. tmp[2] = tmp[0] + 2*nbytes;
  76. tmp[3] = tmp[0] + 3*nbytes;
  77. return prev;
  78. }
  79. T MP_new(unsigned long u) {
  80. return MP_fromintu(ALLOC(nbytes), u);
  81. }
  82. T MP_fromintu(T z, unsigned long u) {
  83. unsigned long carry;
  84. assert(z);
  85. carry = XP_fromint(nbytes, z, u);
  86. carry |= z[nbytes-1]&~msb;
  87. z[nbytes-1] &= msb;
  88. if (carry)
  89. RAISE(MP_Overflow);
  90. return z;
  91. }
  92. T MP_fromint(T z, long v) {
  93. assert(z);
  94. if (v == LONG_MIN) {
  95. XP_fromint(nbytes, z, LONG_MAX + 1UL);
  96. XP_neg(nbytes, z, z, 1);
  97. } else if (v < 0) {
  98. XP_fromint(nbytes, z, -v);
  99. XP_neg(nbytes, z, z, 1);
  100. } else
  101. XP_fromint(nbytes, z, v);
  102. z[nbytes-1] &= msb;
  103. if ((nbits < 8*(int)sizeof (v) &&
  104.      (v < -(1L<<(nbits-1)) || v >= (1L<<(nbits-1)))))
  105. RAISE(MP_Overflow);
  106. return z;
  107. }
  108. long MP_toint(T x) {
  109. unsigned char d[sizeof (unsigned long)];
  110. assert(x);
  111. MP_cvt(8*sizeof d, d, x);
  112. return XP_toint(sizeof d, d);
  113. }
  114. T MP_cvt(int m, T z, T x) {
  115. int fill, i, mbytes = (m - 1)/8 + 1;
  116. assert(m > 1);
  117. assert(x); assert(z);
  118. fill = sign(x) ? 0xFF : 0;
  119. if (m < nbits) {
  120. int carry = (x[mbytes-1]^fill)&~ones(m);
  121. for (i = mbytes; i < nbytes; i++)
  122. carry |= x[i]^fill;
  123. memcpy(z, x, mbytes);
  124. z[mbytes-1] &= ones(m);
  125. if (carry)
  126. RAISE(MP_Overflow);
  127. } else {
  128. memcpy(z, x, nbytes);
  129. z[nbytes-1] |= fill&~msb;
  130. for (i = nbytes; i < mbytes; i++)
  131. z[i] = fill;
  132. z[mbytes-1] &= ones(m);
  133. }
  134. return z;
  135. }
  136. unsigned long MP_tointu(T x) {
  137. unsigned char d[sizeof (unsigned long)];
  138. assert(x);
  139. MP_cvtu(8*sizeof d, d, x);
  140. return XP_toint(sizeof d, d);
  141. }
  142. T MP_cvtu(int m, T z, T x) {
  143. int i, mbytes = (m - 1)/8 + 1;
  144. assert(m > 1);
  145. assert(x); assert(z);
  146. if (m < nbits) {
  147. int carry = x[mbytes-1]&~ones(m);
  148. for (i = mbytes; i < nbytes; i++)
  149. carry |= x[i];
  150. memcpy(z, x, mbytes);
  151. z[mbytes-1] &= ones(m);
  152. if (carry)
  153. RAISE(MP_Overflow);
  154. } else {
  155. memcpy(z, x, nbytes);
  156. for (i = nbytes; i < mbytes; i++)
  157. z[i] = 0;
  158. }
  159. return z;
  160. }
  161. T MP_addu(T z, T x, T y) {
  162. int carry;
  163. assert(x); assert(y); assert(z);
  164. carry = XP_add(nbytes, z, x, y, 0);
  165. carry |= z[nbytes-1]&~msb;
  166. z[nbytes-1] &= msb;
  167. if (carry)
  168. RAISE(MP_Overflow);
  169. return z;
  170. }
  171. T MP_subu(T z, T x, T y) {
  172. int borrow;
  173. assert(x); assert(y); assert(z);
  174. borrow = XP_sub(nbytes, z, x, y, 0);
  175. borrow |= z[nbytes-1]&~msb;
  176. z[nbytes-1] &= msb;
  177. if (borrow)
  178. RAISE(MP_Overflow);
  179. return z;
  180. }
  181. T MP_mul2u(T z, T x, T y) {
  182. assert(x); assert(y); assert(z);
  183. memset(tmp[3], '', 2*nbytes);
  184. XP_mul(tmp[3], nbytes, x, nbytes, y);
  185. memcpy(z, tmp[3], (2*nbits - 1)/8 + 1);
  186. return z;
  187. }
  188. T MP_mulu(T z, T x, T y) {
  189. assert(x); assert(y); assert(z);
  190. memset(tmp[3], '', 2*nbytes);
  191. XP_mul(tmp[3], nbytes, x, nbytes, y);
  192. memcpy(z, tmp[3], nbytes);
  193. z[nbytes-1] &= msb;
  194. {
  195. int i;
  196. if (tmp[3][nbytes-1]&~msb)
  197. RAISE(MP_Overflow);
  198. for (i = 0; i < nbytes; i++)
  199. if (tmp[3][i+nbytes] != 0)
  200. RAISE(MP_Overflow);
  201. }
  202. return z;
  203. }
  204. T MP_divu(T z, T x, T y) {
  205. assert(x); assert(y); assert(z);
  206. {
  207. memcpy(tmp[1], y, nbytes);
  208. y = tmp[1];
  209. }
  210. if (!XP_div(nbytes, z, x, nbytes, y, tmp[2], tmp[3]))
  211. RAISE(MP_Dividebyzero);
  212. return z;
  213. }
  214. T MP_modu(T z, T x, T y) {
  215. assert(x); assert(y); assert(z);
  216. {
  217. memcpy(tmp[1], y, nbytes);
  218. y = tmp[1];
  219. }
  220. if (!XP_div(nbytes, tmp[2], x, nbytes, y, z, tmp[3]))
  221. RAISE(MP_Dividebyzero);
  222. return z;
  223. }
  224. T MP_add(T z, T x, T y) {
  225. int sx, sy;
  226. assert(x); assert(y); assert(z);
  227. sx = sign(x);
  228. sy = sign(y);
  229. XP_add(nbytes, z, x, y, 0);
  230. z[nbytes-1] &= msb;
  231. if (sx == sy && sy != sign(z))
  232. RAISE(MP_Overflow);
  233. return z;
  234. }
  235. T MP_sub(T z, T x, T y) {
  236. int sx, sy;
  237. assert(x); assert(y); assert(z);
  238. sx = sign(x);
  239. sy = sign(y);
  240. XP_sub(nbytes, z, x, y, 0);
  241. z[nbytes-1] &= msb;
  242. if (sx != sy && sy == sign(z))
  243. RAISE(MP_Overflow);
  244. return z;
  245. }
  246. T MP_neg(T z, T x) {
  247. int sx;
  248. assert(x); assert(z);
  249. sx = sign(x);
  250. XP_neg(nbytes, z, x, 1);
  251. z[nbytes-1] &= msb;
  252. if (sx && sx == sign(z))
  253. RAISE(MP_Overflow);
  254. return z;
  255. }
  256. T MP_mul2(T z, T x, T y) {
  257. int sx, sy;
  258. assert(x); assert(y); assert(z);
  259. sx = sign(x);
  260. sy = sign(y);
  261. if (sx) {
  262. XP_neg(nbytes, tmp[0], x, 1);
  263. x = tmp[0];
  264. x[nbytes-1] &= msb;
  265. }
  266. if (sy) {
  267. XP_neg(nbytes, tmp[1], y, 1);
  268. y = tmp[1];
  269. y[nbytes-1] &= msb;
  270. }
  271. memset(tmp[3], '', 2*nbytes);
  272. XP_mul(tmp[3], nbytes, x, nbytes, y);
  273. if (sx != sy)
  274. XP_neg((2*nbits - 1)/8 + 1, z, tmp[3], 1);
  275. else
  276. memcpy(z, tmp[3], (2*nbits - 1)/8 + 1);
  277. return z;
  278. }
  279. T MP_mul(T z, T x, T y) {
  280. int sx, sy;
  281. assert(x); assert(y); assert(z);
  282. sx = sign(x);
  283. sy = sign(y);
  284. if (sx) {
  285. XP_neg(nbytes, tmp[0], x, 1);
  286. x = tmp[0];
  287. x[nbytes-1] &= msb;
  288. }
  289. if (sy) {
  290. XP_neg(nbytes, tmp[1], y, 1);
  291. y = tmp[1];
  292. y[nbytes-1] &= msb;
  293. }
  294. memset(tmp[3], '', 2*nbytes);
  295. XP_mul(tmp[3], nbytes, x, nbytes, y);
  296. if (sx != sy)
  297. XP_neg(nbytes, z, tmp[3], 1);
  298. else
  299. memcpy(z, tmp[3], nbytes);
  300. z[nbytes-1] &= msb;
  301. {
  302. int i;
  303. if (tmp[3][nbytes-1]&~msb)
  304. RAISE(MP_Overflow);
  305. for (i = 0; i < nbytes; i++)
  306. if (tmp[3][i+nbytes] != 0)
  307. RAISE(MP_Overflow);
  308. }
  309. if (sx == sy && sign(z))
  310. RAISE(MP_Overflow);
  311. return z;
  312. }
  313. T MP_div(T z, T x, T y) {
  314. int sx, sy;
  315. assert(x); assert(y); assert(z);
  316. sx = sign(x);
  317. sy = sign(y);
  318. if (sx) {
  319. XP_neg(nbytes, tmp[0], x, 1);
  320. x = tmp[0];
  321. x[nbytes-1] &= msb;
  322. }
  323. if (sy) {
  324. XP_neg(nbytes, tmp[1], y, 1);
  325. y = tmp[1];
  326. y[nbytes-1] &= msb;
  327. } else {
  328.      memcpy(tmp[1], y, nbytes);
  329.      y = tmp[1];
  330.     }
  331. if (!XP_div(nbytes, z, x, nbytes, y, tmp[2], tmp[3]))
  332. RAISE(MP_Dividebyzero);
  333. if (sx != sy) {
  334. XP_neg(nbytes, z, z, 1);
  335. if (!iszero(tmp[2]))
  336. XP_diff(nbytes, z, z, 1);
  337. z[nbytes-1] &= msb;
  338. } else if (sx && sign(z))
  339. RAISE(MP_Overflow);
  340. return z;
  341. }
  342. T MP_mod(T z, T x, T y) {
  343. int sx, sy;
  344. assert(x); assert(y); assert(z);
  345. sx = sign(x);
  346. sy = sign(y);
  347. if (sx) {
  348. XP_neg(nbytes, tmp[0], x, 1);
  349. x = tmp[0];
  350. x[nbytes-1] &= msb;
  351. }
  352. if (sy) {
  353. XP_neg(nbytes, tmp[1], y, 1);
  354. y = tmp[1];
  355. y[nbytes-1] &= msb;
  356. } else {
  357.      memcpy(tmp[1], y, nbytes);
  358.      y = tmp[1];
  359.     }
  360. if (!XP_div(nbytes, tmp[2], x, nbytes, y, z, tmp[3]))
  361. RAISE(MP_Dividebyzero);
  362. if (sx != sy) {
  363. if (!iszero(z))
  364. XP_sub(nbytes, z, y, z, 0);
  365. } else if (sx && sign(tmp[2]))
  366. RAISE(MP_Overflow);
  367. return z;
  368. }
  369. T MP_addui(T z, T x, unsigned long y) {
  370. assert(x); assert(z);
  371. if (y < BASE) {
  372. int carry = XP_sum(nbytes, z, x, y);
  373. carry |= z[nbytes-1]&~msb;
  374. z[nbytes-1] &= msb;
  375. if (carry)
  376. RAISE(MP_Overflow);
  377. } else if (applyu(MP_addu, z, x, y))
  378. RAISE(MP_Overflow);
  379. return z;
  380. }
  381. T MP_subui(T z, T x, unsigned long y) {
  382. assert(x); assert(z);
  383. if (y < BASE) {
  384. int borrow = XP_diff(nbytes, z, x, y);
  385. borrow |= z[nbytes-1]&~msb;
  386. z[nbytes-1] &= msb;
  387. if (borrow)
  388. RAISE(MP_Overflow);
  389. } else if (applyu(MP_subu, z, x, y))
  390. RAISE(MP_Overflow);
  391. return z;
  392. }
  393. T MP_mului(T z, T x, unsigned long y) {
  394. assert(x); assert(z);
  395. if (y < BASE) {
  396. int carry = XP_product(nbytes, z, x, y);
  397. carry |= z[nbytes-1]&~msb;
  398. z[nbytes-1] &= msb;
  399. if (carry)
  400. RAISE(MP_Overflow);
  401. if (nbits < 8 && y >= (1U<<nbits))
  402. RAISE(MP_Overflow);
  403. } else if (applyu(MP_mulu, z, x, y))
  404. RAISE(MP_Overflow);
  405. return z;
  406. }
  407. T MP_divui(T z, T x, unsigned long y) {
  408. assert(x); assert(z);
  409. if (y == 0)
  410. RAISE(MP_Dividebyzero);
  411. else if (y < BASE) {
  412. XP_quotient(nbytes, z, x, y);
  413. if (nbits < 8 && y >= (1U<<nbits))
  414. RAISE(MP_Overflow);
  415. } else if (applyu(MP_divu, z, x, y))
  416. RAISE(MP_Overflow);
  417. return z;
  418. }
  419. unsigned long MP_modui(T x, unsigned long y) {
  420. assert(x);
  421. if (y == 0)
  422. RAISE(MP_Dividebyzero);
  423. else if (y < BASE) {
  424. int r = XP_quotient(nbytes, tmp[2], x, y);
  425. if (nbits < 8 && y >= (1U<<nbits))
  426. RAISE(MP_Overflow);
  427. return r;
  428. } else if (applyu(MP_modu, tmp[2], x, y))
  429. RAISE(MP_Overflow);
  430. return XP_toint(nbytes, tmp[2]);
  431. }
  432. T MP_addi(T z, T x, long y) {
  433. assert(x); assert(z);
  434. if (-BASE < y && y < BASE) {
  435. int sx = sign(x), sy = y < 0;
  436. if (sy)
  437. XP_diff(nbytes, z, x, -y);
  438. else
  439. XP_sum (nbytes, z, x,  y);
  440. z[nbytes-1] &= msb;
  441. if (sx == sy && sy != sign(z))
  442. RAISE(MP_Overflow);
  443. if (nbits < 8
  444. && (y < -(1<<(nbits-1)) || y >= (1<<(nbits-1))))
  445. RAISE(MP_Overflow);
  446. } else if (apply(MP_add, z, x, y))
  447. RAISE(MP_Overflow);
  448. return z;
  449. }
  450. T MP_subi(T z, T x, long y) {
  451. assert(x); assert(z);
  452. if (-BASE < y && y < BASE) {
  453. int sx = sign(x), sy = y < 0;
  454. if (sy)
  455. XP_sum (nbytes, z, x, -y);
  456. else
  457. XP_diff(nbytes, z, x,  y);
  458. z[nbytes-1] &= msb;
  459. if (sx != sy && sy == sign(z))
  460. RAISE(MP_Overflow);
  461. if (nbits < 8
  462. && (y < -(1<<(nbits-1)) || y >= (1<<(nbits-1))))
  463. RAISE(MP_Overflow);
  464. } else if (apply(MP_sub, z, x, y))
  465. RAISE(MP_Overflow);
  466. return z;
  467. }
  468. T MP_muli(T z, T x, long y) {
  469. assert(x); assert(z);
  470. if (-BASE < y && y < BASE) {
  471. int sx = sign(x), sy = y < 0;
  472. if (sx) {
  473. XP_neg(nbytes, tmp[0], x, 1);
  474. x = tmp[0];
  475. x[nbytes-1] &= msb;
  476. }
  477. XP_product(nbytes, z, x, sy ? -y : y);
  478. if (sx != sy)
  479. XP_neg(nbytes, z, x, 1);
  480. z[nbytes-1] &= msb;
  481. if (sx == sy && sign(z))
  482. RAISE(MP_Overflow);
  483. if (nbits < 8
  484. && (y < -(1<<(nbits-1)) || y >= (1<<(nbits-1))))
  485. RAISE(MP_Overflow);
  486. } else if (apply(MP_mul, z, x, y))
  487. RAISE(MP_Overflow);
  488. return z;
  489. }
  490. T MP_divi(T z, T x, long y) {
  491. assert(x); assert(z);
  492. if (y == 0)
  493. RAISE(MP_Dividebyzero);
  494. else if (-BASE < y && y < BASE) {
  495. int r;
  496. int sx = sign(x), sy = y < 0;
  497. if (sx) {
  498. XP_neg(nbytes, tmp[0], x, 1);
  499. x = tmp[0];
  500. x[nbytes-1] &= msb;
  501. }
  502. r = XP_quotient(nbytes, z, x, sy ? -y : y);
  503. if (sx != sy) {
  504. XP_neg(nbytes, z, z, 1);
  505. if (r != 0) {
  506. XP_diff(nbytes, z, z, 1);
  507. r = y - r;
  508. }
  509. z[nbytes-1] &= msb;
  510. } else if (sx && sign(z))
  511. RAISE(MP_Overflow);
  512. if (nbits < 8
  513. && (y < -(1<<(nbits-1)) || y >= (1<<(nbits-1))))
  514. RAISE(MP_Overflow);
  515. } else if (apply(MP_div, z, x, y))
  516. RAISE(MP_Overflow);
  517. return z;
  518. }
  519. long MP_modi(T x, long y) {
  520. assert(x);
  521. if (y == 0)
  522. RAISE(MP_Dividebyzero);
  523. else if (-BASE < y && y < BASE) {
  524. T z = tmp[2];
  525. int r;
  526. int sx = sign(x), sy = y < 0;
  527. if (sx) {
  528. XP_neg(nbytes, tmp[0], x, 1);
  529. x = tmp[0];
  530. x[nbytes-1] &= msb;
  531. }
  532. r = XP_quotient(nbytes, z, x, sy ? -y : y);
  533. if (sx != sy) {
  534. XP_neg(nbytes, z, z, 1);
  535. if (r != 0) {
  536. XP_diff(nbytes, z, z, 1);
  537. r = y - r;
  538. }
  539. z[nbytes-1] &= msb;
  540. } else if (sx && sign(z))
  541. RAISE(MP_Overflow);
  542. if (nbits < 8
  543. && (y < -(1<<(nbits-1)) || y >= (1<<(nbits-1))))
  544. RAISE(MP_Overflow);
  545. return r;
  546. } else if (apply(MP_mod, tmp[2], x, y))
  547. RAISE(MP_Overflow);
  548. return MP_toint(tmp[2]);
  549. }
  550. int MP_cmpu(T x, T y) {
  551. assert(x);
  552. assert(y);
  553. return XP_cmp(nbytes, x, y);
  554. }
  555. int MP_cmp(T x, T y) {
  556. int sx, sy;
  557. assert(x);
  558. assert(y);
  559. sx = sign(x);
  560. sy = sign(y);
  561. if (sx != sy)
  562. return sy - sx;
  563. else
  564. return XP_cmp(nbytes, x, y);
  565. }
  566. int MP_cmpui(T x, unsigned long y) {
  567. assert(x);
  568. if ((int)sizeof y >= nbytes) {
  569. unsigned long v = XP_toint(nbytes, x);
  570. if (v < y)
  571. return -1;
  572. else if (v > y)
  573. return 1;
  574. else
  575. return 0;
  576. } else {
  577. XP_fromint(nbytes, tmp[2], y);
  578. return XP_cmp(nbytes, x, tmp[2]);
  579. }
  580. }
  581. int MP_cmpi(T x, long y) {
  582. int sx, sy = y < 0;
  583. assert(x);
  584. sx = sign(x);
  585. if (sx != sy)
  586. return sy - sx;
  587. else if ((int)sizeof y >= nbytes) {
  588. long v = MP_toint(x);
  589. if (v < y)
  590. return -1;
  591. else if (v > y)
  592. return 1;
  593. else
  594. return 0;
  595. } else {
  596. MP_fromint(tmp[2], y);
  597. return XP_cmp(nbytes, x, tmp[2]);
  598. }
  599. }
  600. T MP_and(T z, T x, T y) { bitop(&); }
  601. T MP_or (T z, T x, T y) { bitop(|); }
  602. T MP_xor(T z, T x, T y) { bitop(^); }
  603. T MP_not(T z, T x) {
  604. int i;
  605. assert(x); assert(z);
  606. for (i = 0; i < nbytes; i++)
  607. z[i] = ~x[i];
  608. z[nbytes-1] &= msb;
  609. return z;
  610. }
  611. T MP_andi(T z, T x, unsigned long y) { bitopi(MP_and); }
  612. T MP_ori (T z, T x, unsigned long y) { bitopi(MP_or);  }
  613. T MP_xori(T z, T x, unsigned long y) { bitopi(MP_xor); }
  614. T MP_lshift(T z, T x, int s) { shft(0, XP_lshift); }
  615. T MP_rshift(T z, T x, int s) { shft(0, XP_rshift); }
  616. T MP_ashift(T z, T x, int s) { shft(sign(x),XP_rshift); }
  617. T MP_fromstr(T z, const char *str, int base, char **end){
  618. int carry;
  619. assert(z);
  620. memset(z, '', nbytes);
  621. carry = XP_fromstr(nbytes, z, str, base, end);
  622. carry |= z[nbytes-1]&~msb;
  623. z[nbytes-1] &= msb;
  624. if (carry)
  625. RAISE(MP_Overflow);
  626. return z;
  627. }
  628. char *MP_tostr(char *str, int size, int base, T x) {
  629. assert(x);
  630. assert(base >= 2 && base <= 36);
  631. assert(str == NULL || size > 1);
  632. if (str == NULL) {
  633. {
  634. int k;
  635. for (k = 5; (1<<k) > base; k--)
  636. ;
  637. size = nbits/k + 1 + 1;
  638. }
  639. str = ALLOC(size);
  640. }
  641. memcpy(tmp[1], x, nbytes);
  642. XP_tostr(str, size, base, nbytes, tmp[1]);
  643. return str;
  644. }
  645. void MP_fmtu(int code, va_list *app,
  646. int put(int c, void *cl), void *cl,
  647. unsigned char flags[], int width, int precision) {
  648. T x;
  649. char *buf;
  650. assert(app && flags);
  651. x = va_arg(*app, T);
  652. assert(x);
  653. buf = MP_tostr(NULL, 0, va_arg(*app, int), x);
  654. Fmt_putd(buf, strlen(buf), put, cl, flags,
  655. width, precision);
  656. FREE(buf);
  657. }
  658. void MP_fmt(int code, va_list *app,
  659. int put(int c, void *cl), void *cl,
  660. unsigned char flags[], int width, int precision) {
  661. T x;
  662. int base, size, sx;
  663. char *buf;
  664. assert(app && flags);
  665. x = va_arg(*app, T);
  666. assert(x);
  667. base = va_arg(*app, int);
  668. assert(base >= 2 && base <= 36);
  669. sx = sign(x);
  670. if (sx) {
  671. XP_neg(nbytes, tmp[0], x, 1);
  672. x = tmp[0];
  673. x[nbytes-1] &= msb;
  674. }
  675. {
  676. int k;
  677. for (k = 5; (1<<k) > base; k--)
  678. ;
  679. size = nbits/k + 1 + 1;
  680. }
  681. buf = ALLOC(size+1);
  682. if (sx) {
  683. buf[0] = '-';
  684. MP_tostr(buf + 1, size, base, x);
  685. } else
  686. MP_tostr(buf, size + 1, base, x);
  687. Fmt_putd(buf, strlen(buf), put, cl, flags,
  688. width, precision);
  689. FREE(buf);
  690. }