bignum.cpp 16 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009
  1. #include "stdafx.h"
  2. #include "defs.h"
  3. #define MP_MIN_SIZE 2
  4. #define MP_MAX_FREE 500
  5. double convert_rational_to_double(U *);
  6. double convert_bignum_to_double(unsigned int *);
  7. int ge(unsigned int *, unsigned int *, int);
  8. int mtotal, mfreecount;
  9. unsigned int **free_stack;
  10. unsigned int *
  11. mnew(int n)
  12. {
  13. unsigned int *p;
  14. if (n < MP_MIN_SIZE)
  15. n = MP_MIN_SIZE;
  16. if (n == MP_MIN_SIZE && mfreecount)
  17. p = free_stack[--mfreecount];
  18. else {
  19. p = (unsigned int *) malloc((n + 3) * sizeof (int));
  20. if (p == 0)
  21. stop("malloc failure");
  22. }
  23. p[0] = n;
  24. mtotal += n;
  25. return p + 3;
  26. }
  27. void
  28. mfree(unsigned int *p)
  29. {
  30. p -= 3;
  31. mtotal -= p[0];
  32. if (p[0] == MP_MIN_SIZE && mfreecount < MP_MAX_FREE)
  33. free_stack[mfreecount++] = p;
  34. else
  35. free(p);
  36. }
  37. // convert int to bignum
  38. unsigned int *
  39. mint(int n)
  40. {
  41. unsigned int *p = mnew(1);
  42. if (n < 0)
  43. MSIGN(p) = -1;
  44. else
  45. MSIGN(p) = 1;
  46. MLENGTH(p) = 1;
  47. p[0] = abs(n);
  48. return p;
  49. }
  50. // copy bignum
  51. unsigned int *
  52. mcopy(unsigned int *a)
  53. {
  54. int i;
  55. unsigned int *b;
  56. b = mnew(MLENGTH(a));
  57. MSIGN(b) = MSIGN(a);
  58. MLENGTH(b) = MLENGTH(a);
  59. for (i = 0; i < MLENGTH(a); i++)
  60. b[i] = a[i];
  61. return b;
  62. }
  63. // a >= b ?
  64. int
  65. ge(unsigned int *a, unsigned int *b, int len)
  66. {
  67. int i;
  68. for (i = len - 1; i > 0; i--)
  69. if (a[i] == b[i])
  70. continue;
  71. else
  72. break;
  73. if (a[i] >= b[i])
  74. return 1;
  75. else
  76. return 0;
  77. }
  78. void
  79. add_numbers(void)
  80. {
  81. double a, b;
  82. if (isrational(stack[tos - 1]) && isrational(stack[tos - 2])) {
  83. qadd();
  84. return;
  85. }
  86. save();
  87. p2 = pop();
  88. p1 = pop();
  89. if (isdouble(p1))
  90. a = p1->u.d;
  91. else
  92. a = convert_rational_to_double(p1);
  93. if (isdouble(p2))
  94. b = p2->u.d;
  95. else
  96. b = convert_rational_to_double(p2);
  97. push_double(a + b);
  98. restore();
  99. }
  100. void
  101. subtract_numbers(void)
  102. {
  103. double a, b;
  104. if (isrational(stack[tos - 1]) && isrational(stack[tos - 2])) {
  105. qsub();
  106. return;
  107. }
  108. save();
  109. p2 = pop();
  110. p1 = pop();
  111. if (isdouble(p1))
  112. a = p1->u.d;
  113. else
  114. a = convert_rational_to_double(p1);
  115. if (isdouble(p2))
  116. b = p2->u.d;
  117. else
  118. b = convert_rational_to_double(p2);
  119. push_double(a - b);
  120. restore();
  121. }
  122. void
  123. multiply_numbers(void)
  124. {
  125. double a, b;
  126. if (isrational(stack[tos - 1]) && isrational(stack[tos - 2])) {
  127. qmul();
  128. return;
  129. }
  130. save();
  131. p2 = pop();
  132. p1 = pop();
  133. if (isdouble(p1))
  134. a = p1->u.d;
  135. else
  136. a = convert_rational_to_double(p1);
  137. if (isdouble(p2))
  138. b = p2->u.d;
  139. else
  140. b = convert_rational_to_double(p2);
  141. push_double(a * b);
  142. restore();
  143. }
  144. void
  145. divide_numbers(void)
  146. {
  147. double a, b;
  148. if (isrational(stack[tos - 1]) && isrational(stack[tos - 2])) {
  149. qdiv();
  150. return;
  151. }
  152. save();
  153. p2 = pop();
  154. p1 = pop();
  155. if (iszero(p2))
  156. stop("divide by zero");
  157. if (isdouble(p1))
  158. a = p1->u.d;
  159. else
  160. a = convert_rational_to_double(p1);
  161. if (isdouble(p2))
  162. b = p2->u.d;
  163. else
  164. b = convert_rational_to_double(p2);
  165. push_double(a / b);
  166. restore();
  167. }
  168. void
  169. invert_number(void)
  170. {
  171. unsigned int *a, *b;
  172. save();
  173. p1 = pop();
  174. if (iszero(p1))
  175. stop("divide by zero");
  176. if (isdouble(p1)) {
  177. push_double(1 / p1->u.d);
  178. restore();
  179. return;
  180. }
  181. a = mcopy(p1->u.q.a);
  182. b = mcopy(p1->u.q.b);
  183. MSIGN(b) = MSIGN(a);
  184. MSIGN(a) = 1;
  185. p1 = alloc();
  186. p1->k = NUM;
  187. p1->u.q.a = b;
  188. p1->u.q.b = a;
  189. push(p1);
  190. restore();
  191. }
  192. int
  193. compare_rationals(U *a, U *b)
  194. {
  195. int t;
  196. unsigned int *ab, *ba;
  197. ab = mmul(a->u.q.a, b->u.q.b);
  198. ba = mmul(a->u.q.b, b->u.q.a);
  199. t = mcmp(ab, ba);
  200. mfree(ab);
  201. mfree(ba);
  202. return t;
  203. }
  204. int
  205. compare_numbers(U *a, U *b)
  206. {
  207. double x, y;
  208. if (isrational(a) && isrational(b))
  209. return compare_rationals(a, b);
  210. if (isdouble(a))
  211. x = a->u.d;
  212. else
  213. x = convert_rational_to_double(a);
  214. if (isdouble(b))
  215. y = b->u.d;
  216. else
  217. y = convert_rational_to_double(b);
  218. if (x < y)
  219. return -1;
  220. if (x > y)
  221. return 1;
  222. return 0;
  223. }
  224. void
  225. negate_number(void)
  226. {
  227. save();
  228. p1 = pop();
  229. if (iszero(p1)) {
  230. push(p1);
  231. restore();
  232. return;
  233. }
  234. switch (p1->k) {
  235. case NUM:
  236. p2 = alloc();
  237. p2->k = NUM;
  238. p2->u.q.a = mcopy(p1->u.q.a);
  239. p2->u.q.b = mcopy(p1->u.q.b);
  240. MSIGN(p2->u.q.a) *= -1;
  241. push(p2);
  242. break;
  243. case DOUBLE:
  244. push_double(-p1->u.d);
  245. break;
  246. default:
  247. stop("bug caught in mp_negate_number");
  248. break;
  249. }
  250. restore();
  251. }
  252. void
  253. bignum_truncate(void)
  254. {
  255. unsigned int *a;
  256. save();
  257. p1 = pop();
  258. a = mdiv(p1->u.q.a, p1->u.q.b);
  259. p1 = alloc();
  260. p1->k = NUM;
  261. p1->u.q.a = a;
  262. p1->u.q.b = mint(1);
  263. push(p1);
  264. restore();
  265. }
  266. void
  267. mp_numerator(void)
  268. {
  269. save();
  270. p1 = pop();
  271. if (p1->k != NUM) {
  272. push(one);
  273. restore();
  274. return;
  275. }
  276. p2 = alloc();
  277. p2->k = NUM;
  278. p2->u.q.a = mcopy(p1->u.q.a);
  279. p2->u.q.b = mint(1);
  280. push(p2);
  281. restore();
  282. }
  283. void
  284. mp_denominator(void)
  285. {
  286. save();
  287. p1 = pop();
  288. if (p1->k != NUM) {
  289. push(one);
  290. restore();
  291. return;
  292. }
  293. p2 = alloc();
  294. p2->k = NUM;
  295. p2->u.q.a = mcopy(p1->u.q.b);
  296. p2->u.q.b = mint(1);
  297. push(p2);
  298. restore();
  299. }
  300. void
  301. bignum_power_number(int expo)
  302. {
  303. unsigned int *a, *b, *t;
  304. save();
  305. p1 = pop();
  306. a = mpow(p1->u.q.a, abs(expo));
  307. b = mpow(p1->u.q.b, abs(expo));
  308. if (expo < 0) {
  309. t = a;
  310. a = b;
  311. b = t;
  312. MSIGN(a) = MSIGN(b);
  313. MSIGN(b) = 1;
  314. }
  315. p1 = alloc();
  316. p1->k = NUM;
  317. p1->u.q.a = a;
  318. p1->u.q.b = b;
  319. push(p1);
  320. restore();
  321. }
  322. double
  323. convert_bignum_to_double(unsigned int *p)
  324. {
  325. int i;
  326. double d = 0.0;
  327. for (i = MLENGTH(p) - 1; i >= 0; i--)
  328. d = 4294967296.0 * d + p[i];
  329. if (MSIGN(p) == -1)
  330. d = -d;
  331. return d;
  332. }
  333. double
  334. convert_rational_to_double(U *p)
  335. {
  336. int i, n, na, nb;
  337. double a = 0.0, b = 0.0;
  338. na = MLENGTH(p->u.q.a);
  339. nb = MLENGTH(p->u.q.b);
  340. if (na < nb)
  341. n = na;
  342. else
  343. n = nb;
  344. for (i = 0; i < n; i++) {
  345. a = a / 4294967296.0 + p->u.q.a[i];
  346. b = b / 4294967296.0 + p->u.q.b[i];
  347. }
  348. if (na > nb)
  349. for (i = nb; i < na; i++) {
  350. a = a / 4294967296.0 + p->u.q.a[i];
  351. b = b / 4294967296.0;
  352. }
  353. if (na < nb)
  354. for (i = na; i < nb; i++) {
  355. a = a / 4294967296.0;
  356. b = b / 4294967296.0 + p->u.q.b[i];
  357. }
  358. if (MSIGN(p->u.q.a) == -1)
  359. a = -a;
  360. return a / b;
  361. }
  362. void
  363. push_integer(int n)
  364. {
  365. save();
  366. p1 = alloc();
  367. p1->k = NUM;
  368. p1->u.q.a = mint(n);
  369. p1->u.q.b = mint(1);
  370. push(p1);
  371. restore();
  372. }
  373. void
  374. push_double(double d)
  375. {
  376. save();
  377. p1 = alloc();
  378. p1->k = DOUBLE;
  379. p1->u.d = d;
  380. push(p1);
  381. restore();
  382. }
  383. void
  384. push_rational(int a, int b)
  385. {
  386. save();
  387. p1 = alloc();
  388. p1->k = NUM;
  389. p1->u.q.a = mint(a);
  390. p1->u.q.b = mint(b);
  391. /* FIXME -- normalize */
  392. push(p1);
  393. restore();
  394. }
  395. int
  396. pop_integer(void)
  397. {
  398. int n;
  399. save();
  400. p1 = pop();
  401. switch (p1->k) {
  402. case NUM:
  403. if (isinteger(p1) && MLENGTH(p1->u.q.a) == 1) {
  404. n = p1->u.q.a[0];
  405. if (n & 0x80000000)
  406. n = 0x80000000;
  407. else
  408. n *= MSIGN(p1->u.q.a);
  409. } else
  410. n = 0x80000000;
  411. break;
  412. case DOUBLE:
  413. n = (int) p1->u.d;
  414. if ((double) n != p1->u.d)
  415. n = 0x80000000;
  416. break;
  417. default:
  418. n = 0x80000000;
  419. break;
  420. }
  421. restore();
  422. return n;
  423. }
  424. void
  425. print_double(U *p, int flag)
  426. {
  427. static char buf[80];
  428. sprintf(buf, "%g", p->u.d);
  429. if (flag == 1 && *buf == '-')
  430. print_str(buf + 1);
  431. else
  432. print_str(buf);
  433. }
  434. void
  435. bignum_scan_integer(char *s)
  436. {
  437. unsigned int *a;
  438. char sign;
  439. save();
  440. sign = *s;
  441. if (sign == '+' || sign == '-')
  442. s++;
  443. a = mscan(s);
  444. p1 = alloc();
  445. p1->k = NUM;
  446. p1->u.q.a = a;
  447. p1->u.q.b = mint(1);
  448. push(p1);
  449. if (sign == '-')
  450. negate();
  451. restore();
  452. }
  453. #define FLT_MIN (1e-999)
  454. #define FLT_MAX (9.999999999999999e999)
  455. // the following strtod isn't used. but if I remove it, GCC's linker starts giving errors somewhere inside libm
  456. // *magic* DO NOT TOUCH *magic*
  457. // this strtod was deprecated because it didn't have enough precision
  458. double amystrtod(char *s, char **str_end) {
  459. // TODO handle exponential format, hex format, inf, nan
  460. double r = 0.0;
  461. int negative = 0;
  462. union { double rr; unsigned long long dd; } raw;
  463. while (isspace(*s)) s++; //skip leading whitespace
  464. if ((s[0] == 'i' || s[0] == 'I') && (s[1] == 'n' || s[1] == 'N') && (s[2] == 'f' || s[2] == 'F')) {
  465. if (str_end != NULL)
  466. *str_end = s+3;
  467. raw.dd = 0x7FF0000000000000; //positive infinity
  468. return raw.rr;
  469. }
  470. if ((s[0] == 'n' || s[0] == 'N') && (s[1] == 'a' || s[1] == 'A') && (s[2] == 'n' || s[2] == 'N')) {
  471. if (str_end != NULL)
  472. *str_end = s+3;
  473. raw.dd = 0x7FFFFFFFFFFFFFFF; //QNaN
  474. return raw.rr;
  475. }
  476. if (!isdigit(*s) && *s != '-' && *s != '+' && *s != '.') {
  477. if (str_end != NULL)
  478. *str_end = (char *)s;
  479. return 0;
  480. }
  481. switch (*s)
  482. {
  483. case '-':
  484. negative = 1;
  485. // Deliberate fallthrough
  486. case '+':
  487. s++;
  488. break;
  489. }
  490. while (isdigit(*s))
  491. {
  492. r *= 10.0;
  493. r += *s++ - '0';
  494. }
  495. if (*s == '.')
  496. {
  497. float f = 10.0f;
  498. s++;
  499. while (isdigit(*s))
  500. {
  501. r += (*s - '0')/f;
  502. f *= 10.0f;
  503. s++;
  504. }
  505. }
  506. if (*s == 'e' || *s == 'E') {
  507. int exponent = 0;
  508. bool sign = false;
  509. if (*(s+1) == '-' || *(s+1) == '+') {
  510. if (*(s+1) == '-') sign = true;
  511. if (isdigit(*(s+2))) {
  512. s+=2;
  513. while(isdigit(*s)) {
  514. exponent = (exponent*10) + (*s - '0');
  515. s++;
  516. }
  517. r = pow(r,((sign)?-exponent:exponent));
  518. }
  519. } else if (isdigit(*(s+1))) {
  520. s++;
  521. while(isdigit(*s)) {
  522. exponent = (exponent*10) + (*s - '0');
  523. s++;
  524. }
  525. r = pow(r,exponent);
  526. }
  527. }
  528. if (str_end != NULL)
  529. *str_end = (char *)s;
  530. // Portable? Nope. Fast? Yup.
  531. raw.rr = r;
  532. raw.dd |= (unsigned long long)negative << 63;
  533. if(raw.rr >= FLT_MIN || raw.rr <= -FLT_MIN)
  534. return raw.rr;
  535. else return 0;
  536. }
  537. #define DBL_MAX_EXP 999
  538. #define DBL_MIN_EXP (-999)
  539. //
  540. // strtod.c
  541. //
  542. // Convert string to double
  543. //
  544. // Copyright (C) 2002 Michael Ringgaard. All rights reserved.
  545. //
  546. // Redistribution and use in source and binary forms, with or without
  547. // modification, are permitted provided that the following conditions
  548. // are met:
  549. //
  550. // 1. Redistributions of source code must retain the above copyright
  551. // notice, this list of conditions and the following disclaimer.
  552. // 2. Redistributions in binary form must reproduce the above copyright
  553. // notice, this list of conditions and the following disclaimer in the
  554. // documentation and/or other materials provided with the distribution.
  555. // 3. Neither the name of the project nor the names of its contributors
  556. // may be used to endorse or promote products derived from this software
  557. // without specific prior written permission.
  558. //
  559. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  560. // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  561. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  562. // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
  563. // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  564. // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  565. // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  566. // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  567. // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  568. // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  569. // SUCH DAMAGE.
  570. //
  571. double mystrtod(const char *str, char **endptr) {
  572. double number;
  573. int exponent;
  574. int negative;
  575. char *p = (char *) str;
  576. double p10;
  577. int n;
  578. int num_digits;
  579. int num_decimals;
  580. // Skip leading whitespace
  581. while (isspace(*p)) p++;
  582. // Handle optional sign
  583. negative = 0;
  584. switch (*p) {
  585. case '-': negative = 1; // Fall through to increment position
  586. case '+': p++;
  587. }
  588. number = 0.;
  589. exponent = 0;
  590. num_digits = 0;
  591. num_decimals = 0;
  592. // Process string of digits
  593. while (isdigit(*p)) {
  594. number = number * 10. + (*p - '0');
  595. p++;
  596. num_digits++;
  597. }
  598. // Process decimal part
  599. if (*p == '.') {
  600. p++;
  601. while (isdigit(*p)) {
  602. number = number * 10. + (*p - '0');
  603. p++;
  604. num_digits++;
  605. num_decimals++;
  606. }
  607. exponent -= num_decimals;
  608. }
  609. if (num_digits == 0) {
  610. errno = ERANGE;
  611. return 0.0;
  612. }
  613. // Correct for sign
  614. if (negative) number = -number;
  615. // Process an exponent string
  616. if (*p == 'e' || *p == 'E') {
  617. // Handle optional sign
  618. negative = 0;
  619. switch (*++p) {
  620. case '-': negative = 1; // Fall through to increment pos
  621. case '+': p++;
  622. }
  623. // Process string of digits
  624. n = 0;
  625. while (isdigit(*p)) {
  626. n = n * 10 + (*p - '0');
  627. p++;
  628. }
  629. if (negative) {
  630. exponent -= n;
  631. } else {
  632. exponent += n;
  633. }
  634. }
  635. if (exponent < DBL_MIN_EXP || exponent > DBL_MAX_EXP) {
  636. errno = ERANGE;
  637. return HUGE_VAL;
  638. }
  639. // Scale the result
  640. p10 = 10.;
  641. n = exponent;
  642. if (n < 0) n = -n;
  643. while (n) {
  644. if (n & 1) {
  645. if (exponent < 0) {
  646. number /= p10;
  647. } else {
  648. number *= p10;
  649. }
  650. }
  651. n >>= 1;
  652. p10 *= p10;
  653. }
  654. if (number == HUGE_VAL) errno = ERANGE;
  655. if (endptr) *endptr = p;
  656. return number;
  657. }
  658. void
  659. bignum_scan_float(char *s)
  660. {
  661. //push_double(atof(s));
  662. push_double(mystrtod((char*)s, NULL));
  663. }
  664. // print as unsigned
  665. void
  666. print_number(U *p)
  667. {
  668. char *s;
  669. static char buf[100];
  670. switch (p->k) {
  671. case NUM:
  672. s = mstr(p->u.q.a);
  673. if (*s == '+' || *s == '-')
  674. s++;
  675. print_str(s);
  676. if (isfraction(p)) {
  677. print_str("/");
  678. s = mstr(p->u.q.b);
  679. print_str(s);
  680. }
  681. break;
  682. case DOUBLE:
  683. sprintf(buf, "%.10g", p->u.d);
  684. if (*buf == '+' || *buf == '-')
  685. print_str(buf + 1);
  686. else
  687. print_str(buf);
  688. break;
  689. default:
  690. break;
  691. }
  692. }
  693. void
  694. gcd_numbers(void)
  695. {
  696. save();
  697. p2 = pop();
  698. p1 = pop();
  699. // if (!isinteger(p1) || !isinteger(p2))
  700. // stop("integer args expected for gcd");
  701. p3 = alloc();
  702. p3->k = NUM;
  703. p3->u.q.a = mgcd(p1->u.q.a, p2->u.q.a);
  704. p3->u.q.b = mgcd(p1->u.q.b, p2->u.q.b);
  705. MSIGN(p3->u.q.a) = 1;
  706. push(p3);
  707. restore();
  708. }
  709. double
  710. pop_double(void)
  711. {
  712. double d;
  713. save();
  714. p1 = pop();
  715. switch (p1->k) {
  716. case NUM:
  717. d = convert_rational_to_double(p1);
  718. break;
  719. case DOUBLE:
  720. d = p1->u.d;
  721. break;
  722. default:
  723. d = 0.0;
  724. break;
  725. }
  726. restore();
  727. return d;
  728. }
  729. void
  730. bignum_float(void)
  731. {
  732. double d;
  733. d = convert_rational_to_double(pop());
  734. push_double(d);
  735. }
  736. static unsigned int *__factorial(int);
  737. void
  738. bignum_factorial(int n)
  739. {
  740. save();
  741. p1 = alloc();
  742. p1->k = NUM;
  743. p1->u.q.a = __factorial(n);
  744. p1->u.q.b = mint(1);
  745. push(p1);
  746. restore();
  747. }
  748. static unsigned int *
  749. __factorial(int n)
  750. {
  751. int i;
  752. unsigned int *a, *b, *t;
  753. if (n == 0 || n == 1) {
  754. a = mint(1);
  755. return a;
  756. }
  757. a = mint(2);
  758. b = mint(0);
  759. for (i = 3; i <= n; i++) {
  760. b[0] = (unsigned int) i;
  761. t = mmul(a, b);
  762. mfree(a);
  763. a = t;
  764. }
  765. mfree(b);
  766. return a;
  767. }
  768. static unsigned int mask[32] = {
  769. 0x00000001,
  770. 0x00000002,
  771. 0x00000004,
  772. 0x00000008,
  773. 0x00000010,
  774. 0x00000020,
  775. 0x00000040,
  776. 0x00000080,
  777. 0x00000100,
  778. 0x00000200,
  779. 0x00000400,
  780. 0x00000800,
  781. 0x00001000,
  782. 0x00002000,
  783. 0x00004000,
  784. 0x00008000,
  785. 0x00010000,
  786. 0x00020000,
  787. 0x00040000,
  788. 0x00080000,
  789. 0x00100000,
  790. 0x00200000,
  791. 0x00400000,
  792. 0x00800000,
  793. 0x01000000,
  794. 0x02000000,
  795. 0x04000000,
  796. 0x08000000,
  797. 0x10000000,
  798. 0x20000000,
  799. 0x40000000,
  800. 0x80000000,
  801. };
  802. void
  803. mp_set_bit(unsigned int *x, unsigned int k)
  804. {
  805. x[k / 32] |= mask[k % 32];
  806. }
  807. void
  808. mp_clr_bit(unsigned int *x, unsigned int k)
  809. {
  810. x[k / 32] &= ~mask[k % 32];
  811. }
  812. void
  813. mshiftright(unsigned int *a)
  814. {
  815. int c, i, n;
  816. n = MLENGTH(a);
  817. c = 0;
  818. for (i = n - 1; i >= 0; i--)
  819. if (a[i] & 1) {
  820. a[i] = (a[i] >> 1) | c;
  821. c = 0x80000000;
  822. } else {
  823. a[i] = (a[i] >> 1) | c;
  824. c = 0;
  825. }
  826. if (n > 1 && a[n - 1] == 0)
  827. MLENGTH(a) = n - 1;
  828. }