PageRenderTime 72ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 1ms

/bignum.c

https://github.com/isaac/MacRuby
C | 3671 lines | 2882 code | 423 blank | 366 comment | 673 complexity | f19243715966d2979a1b5e60b3efd5ed MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * This file is covered by the Ruby license. See COPYING for more details.
  3. *
  4. * Copyright (C) 2007-2011, Apple Inc. All rights reserved.
  5. * Copyright (C) 1993-2007 Yukihiro Matsumoto
  6. */
  7. #include "macruby_internal.h"
  8. #include "objc.h"
  9. #include "encoding.h"
  10. #include <math.h>
  11. #include <float.h>
  12. #include <ctype.h>
  13. #ifdef HAVE_IEEEFP_H
  14. #include <ieeefp.h>
  15. #endif
  16. #include <assert.h>
  17. VALUE rb_cBignum;
  18. #if defined __MINGW32__
  19. #define USHORT _USHORT
  20. #endif
  21. #define BDIGITS(x) (RBIGNUM_DIGITS(x))
  22. #define BITSPERDIG (SIZEOF_BDIGITS*CHAR_BIT)
  23. #define BIGRAD ((BDIGIT_DBL)1 << BITSPERDIG)
  24. #define DIGSPERLONG (SIZEOF_LONG/SIZEOF_BDIGITS)
  25. #if HAVE_LONG_LONG
  26. # define DIGSPERLL (SIZEOF_LONG_LONG/SIZEOF_BDIGITS)
  27. #endif
  28. #define BIGUP(x) ((BDIGIT_DBL)(x) << BITSPERDIG)
  29. #define BIGDN(x) RSHIFT(x,BITSPERDIG)
  30. #define BIGLO(x) ((BDIGIT)((x) & (BIGRAD-1)))
  31. #define BDIGMAX ((BDIGIT)-1)
  32. #define BIGZEROP(x) (RBIGNUM_LEN(x) == 0 || \
  33. (BDIGITS(x)[0] == 0 && \
  34. (RBIGNUM_LEN(x) == 1 || bigzero_p(x))))
  35. static int
  36. bigzero_p(VALUE x)
  37. {
  38. long i;
  39. BDIGIT *ds = BDIGITS(x);
  40. for (i = RBIGNUM_LEN(x) - 1; 0 <= i; i--) {
  41. if (ds[i]) return 0;
  42. }
  43. return 1;
  44. }
  45. int
  46. rb_bigzero_p(VALUE x)
  47. {
  48. return BIGZEROP(x);
  49. }
  50. int
  51. rb_cmpint(VALUE val, VALUE a, VALUE b)
  52. {
  53. if (NIL_P(val)) {
  54. rb_cmperr(a, b);
  55. }
  56. if (FIXNUM_P(val)) {
  57. long l = FIX2LONG(val);
  58. if (l > 0) return 1;
  59. if (l < 0) return -1;
  60. return 0;
  61. }
  62. if (TYPE(val) == T_BIGNUM) {
  63. if (BIGZEROP(val)) return 0;
  64. if (RBIGNUM_SIGN(val)) return 1;
  65. return -1;
  66. }
  67. if (RTEST(rb_funcall(val, '>', 1, INT2FIX(0)))) return 1;
  68. if (RTEST(rb_funcall(val, '<', 1, INT2FIX(0)))) return -1;
  69. return 0;
  70. }
  71. #define RBIGNUM_SET_LEN(b,l) \
  72. ((RBASIC(b)->flags & RBIGNUM_EMBED_FLAG) ? \
  73. (RBASIC(b)->flags = (RBASIC(b)->flags & ~RBIGNUM_EMBED_LEN_MASK) | \
  74. ((l) << RBIGNUM_EMBED_LEN_SHIFT)) : \
  75. (RBIGNUM(b)->as.heap.len = (l)))
  76. static void
  77. rb_big_realloc(VALUE big, long len)
  78. {
  79. BDIGIT *ds;
  80. if (RBASIC(big)->flags & RBIGNUM_EMBED_FLAG) {
  81. if (RBIGNUM_EMBED_LEN_MAX < len) {
  82. ds = ALLOC_N(BDIGIT, len);
  83. MEMCPY(ds, RBIGNUM(big)->as.ary, BDIGIT, RBIGNUM_EMBED_LEN_MAX);
  84. RBIGNUM(big)->as.heap.len = RBIGNUM_LEN(big);
  85. GC_WB(&RBIGNUM(big)->as.heap.digits, ds);
  86. RBASIC(big)->flags &= ~RBIGNUM_EMBED_FLAG;
  87. }
  88. }
  89. else {
  90. if (len <= RBIGNUM_EMBED_LEN_MAX) {
  91. ds = RBIGNUM(big)->as.heap.digits;
  92. RBASIC(big)->flags |= RBIGNUM_EMBED_FLAG;
  93. RBIGNUM_SET_LEN(big, len);
  94. if (ds) {
  95. MEMCPY(RBIGNUM(big)->as.ary, ds, BDIGIT, len);
  96. xfree(ds);
  97. }
  98. }
  99. else {
  100. if (RBIGNUM_LEN(big) == 0) {
  101. GC_WB(&RBIGNUM(big)->as.heap.digits, ALLOC_N(BDIGIT, len));
  102. }
  103. else {
  104. void *tmp = ruby_xrealloc(RBIGNUM(big)->as.heap.digits, sizeof(BDIGIT) * len);
  105. if (tmp != RBIGNUM(big)->as.heap.digits) {
  106. GC_WB(&RBIGNUM(big)->as.heap.digits, tmp);
  107. }
  108. }
  109. }
  110. }
  111. }
  112. void
  113. rb_big_resize(VALUE big, long len)
  114. {
  115. rb_big_realloc(big, len);
  116. RBIGNUM_SET_LEN(big, len);
  117. }
  118. static VALUE
  119. bignew_1(VALUE klass, long len, int sign)
  120. {
  121. NEWOBJ(big, struct RBignum);
  122. OBJSETUP(big, klass, T_BIGNUM);
  123. RBIGNUM_SET_SIGN(big, sign?1:0);
  124. if (len <= RBIGNUM_EMBED_LEN_MAX) {
  125. RBASIC(big)->flags |= RBIGNUM_EMBED_FLAG;
  126. RBIGNUM_SET_LEN(big, len);
  127. }
  128. else {
  129. rb_big_resize((VALUE)big, len);
  130. }
  131. return (VALUE)big;
  132. }
  133. #define bignew(len,sign) bignew_1(rb_cBignum,len,sign)
  134. VALUE
  135. rb_bignum_new_retained(const char *str)
  136. {
  137. VALUE v = rb_cstr2inum(str, 10);
  138. GC_RETAIN(v);
  139. return v;
  140. }
  141. VALUE
  142. rb_big_new(long len, int sign)
  143. {
  144. return bignew(len, sign != 0);
  145. }
  146. VALUE
  147. rb_big_clone(VALUE x)
  148. {
  149. long len = RBIGNUM_LEN(x);
  150. VALUE z = bignew_1(CLASS_OF(x), len, RBIGNUM_SIGN(x));
  151. MEMCPY(BDIGITS(z), BDIGITS(x), BDIGIT, len);
  152. return z;
  153. }
  154. /* modify a bignum by 2's complement */
  155. static void
  156. get2comp(VALUE x)
  157. {
  158. long i = RBIGNUM_LEN(x);
  159. BDIGIT *ds = BDIGITS(x);
  160. BDIGIT_DBL num;
  161. if (!i) return;
  162. while (i--) ds[i] = ~ds[i];
  163. i = 0; num = 1;
  164. do {
  165. num += ds[i];
  166. ds[i++] = BIGLO(num);
  167. num = BIGDN(num);
  168. } while (i < RBIGNUM_LEN(x));
  169. if (num != 0) {
  170. rb_big_resize(x, RBIGNUM_LEN(x)+1);
  171. ds = BDIGITS(x);
  172. ds[RBIGNUM_LEN(x)-1] = 1;
  173. }
  174. }
  175. void
  176. rb_big_2comp(VALUE x) /* get 2's complement */
  177. {
  178. get2comp(x);
  179. }
  180. static inline VALUE
  181. bigtrunc(VALUE x)
  182. {
  183. long len = RBIGNUM_LEN(x);
  184. BDIGIT *ds = BDIGITS(x);
  185. if (len == 0) return x;
  186. while (--len && !ds[len]);
  187. if (RBIGNUM_LEN(x) > len+1) {
  188. rb_big_resize(x, len+1);
  189. }
  190. return x;
  191. }
  192. static inline VALUE
  193. bigfixize(VALUE x)
  194. {
  195. long len = RBIGNUM_LEN(x);
  196. BDIGIT *ds = BDIGITS(x);
  197. if (len == 0) return INT2FIX(0);
  198. if ((size_t)(len*SIZEOF_BDIGITS) <= sizeof(long)) {
  199. long num = 0;
  200. #if 2*SIZEOF_BDIGITS > SIZEOF_LONG
  201. num = (long)ds[0];
  202. #else
  203. while (len--) {
  204. num = (long)(BIGUP(num) + ds[len]);
  205. }
  206. #endif
  207. if (num >= 0) {
  208. if (RBIGNUM_SIGN(x)) {
  209. if (POSFIXABLE(num)) return LONG2FIX(num);
  210. }
  211. else {
  212. if (NEGFIXABLE(-num)) return LONG2FIX(-num);
  213. }
  214. }
  215. }
  216. return x;
  217. }
  218. static VALUE
  219. bignorm(VALUE x)
  220. {
  221. if (!FIXNUM_P(x) && TYPE(x) == T_BIGNUM) {
  222. x = bigfixize(bigtrunc(x));
  223. }
  224. return x;
  225. }
  226. VALUE
  227. rb_big_norm(VALUE x)
  228. {
  229. return bignorm(x);
  230. }
  231. VALUE
  232. rb_uint2big(VALUE n)
  233. {
  234. BDIGIT_DBL num = n;
  235. long i = 0;
  236. BDIGIT *digits;
  237. VALUE big;
  238. big = bignew(DIGSPERLONG, 1);
  239. digits = BDIGITS(big);
  240. while (i < DIGSPERLONG) {
  241. digits[i++] = BIGLO(num);
  242. num = BIGDN(num);
  243. }
  244. i = DIGSPERLONG;
  245. while (--i && !digits[i]) ;
  246. RBIGNUM_SET_LEN(big, i+1);
  247. return big;
  248. }
  249. VALUE
  250. rb_int2big(SIGNED_VALUE n)
  251. {
  252. long neg = 0;
  253. VALUE big;
  254. if (n < 0) {
  255. n = -n;
  256. neg = 1;
  257. }
  258. big = rb_uint2big(n);
  259. if (neg) {
  260. RBIGNUM_SET_SIGN(big, 0);
  261. }
  262. return big;
  263. }
  264. #if SIZEOF_LONG % SIZEOF_BDIGITS != 0
  265. # error unexpected SIZEOF_LONG : SIZEOF_BDIGITS ratio
  266. #endif
  267. /*
  268. * buf is an array of long integers.
  269. * buf is ordered from least significant word to most significant word.
  270. * buf[0] is the least significant word and
  271. * buf[num_longs-1] is the most significant word.
  272. * This means words in buf is little endian.
  273. * However each word in buf is native endian.
  274. * (buf[i]&1) is the least significant bit and
  275. * (buf[i]&(1<<(SIZEOF_LONG*CHAR_BIT-1))) is the most significant bit
  276. * for each 0 <= i < num_longs.
  277. * So buf is little endian at whole on a little endian machine.
  278. * But buf is mixed endian on a big endian machine.
  279. */
  280. void
  281. rb_big_pack(VALUE val, unsigned long *buf, long num_longs)
  282. {
  283. val = rb_to_int(val);
  284. if (num_longs == 0)
  285. return;
  286. if (FIXNUM_P(val)) {
  287. long i;
  288. long tmp = FIX2LONG(val);
  289. buf[0] = (unsigned long)tmp;
  290. tmp = tmp < 0 ? ~0L : 0;
  291. for (i = 1; i < num_longs; i++)
  292. buf[i] = (unsigned long)tmp;
  293. return;
  294. }
  295. else {
  296. long len = RBIGNUM_LEN(val);
  297. BDIGIT *ds = BDIGITS(val), *dend = ds + len;
  298. long i, j;
  299. for (i = 0; i < num_longs && ds < dend; i++) {
  300. unsigned long l = 0;
  301. for (j = 0; j < DIGSPERLONG && ds < dend; j++, ds++) {
  302. l |= ((unsigned long)*ds << (j * BITSPERDIG));
  303. }
  304. buf[i] = l;
  305. }
  306. for (; i < num_longs; i++)
  307. buf[i] = 0;
  308. if (RBIGNUM_NEGATIVE_P(val)) {
  309. for (i = 0; i < num_longs; i++) {
  310. buf[i] = ~buf[i];
  311. }
  312. for (i = 0; i < num_longs; i++) {
  313. buf[i]++;
  314. if (buf[i] != 0)
  315. return;
  316. }
  317. }
  318. }
  319. }
  320. /* See rb_big_pack comment for endianness of buf. */
  321. VALUE
  322. rb_big_unpack(unsigned long *buf, long num_longs)
  323. {
  324. while (2 <= num_longs) {
  325. if (buf[num_longs-1] == 0 && (long)buf[num_longs-2] >= 0)
  326. num_longs--;
  327. else if (buf[num_longs-1] == ~0UL && (long)buf[num_longs-2] < 0)
  328. num_longs--;
  329. else
  330. break;
  331. }
  332. if (num_longs == 0)
  333. return INT2FIX(0);
  334. else if (num_longs == 1)
  335. return LONG2NUM((long)buf[0]);
  336. else {
  337. VALUE big;
  338. BDIGIT *ds;
  339. long len = num_longs * DIGSPERLONG;
  340. long i;
  341. big = bignew(len, 1);
  342. ds = BDIGITS(big);
  343. for (i = 0; i < num_longs; i++) {
  344. unsigned long d = buf[i];
  345. #if SIZEOF_LONG == SIZEOF_BDIGITS
  346. *ds++ = d;
  347. #else
  348. int j;
  349. for (j = 0; j < DIGSPERLONG; j++) {
  350. *ds++ = BIGLO(d);
  351. d = BIGDN(d);
  352. }
  353. #endif
  354. }
  355. if ((long)buf[num_longs-1] < 0) {
  356. get2comp(big);
  357. RBIGNUM_SET_SIGN(big, 0);
  358. }
  359. return bignorm(big);
  360. }
  361. }
  362. #define QUAD_SIZE 8
  363. #ifdef HAVE_LONG_LONG
  364. void
  365. rb_quad_pack(char *buf, VALUE val)
  366. {
  367. LONG_LONG q;
  368. val = rb_to_int(val);
  369. if (FIXNUM_P(val)) {
  370. q = FIX2LONG(val);
  371. }
  372. else {
  373. long len = RBIGNUM_LEN(val);
  374. BDIGIT *ds;
  375. if (len > SIZEOF_LONG_LONG/SIZEOF_BDIGITS) {
  376. len = SIZEOF_LONG_LONG/SIZEOF_BDIGITS;
  377. }
  378. ds = BDIGITS(val);
  379. q = 0;
  380. while (len--) {
  381. q = BIGUP(q);
  382. q += ds[len];
  383. }
  384. if (!RBIGNUM_SIGN(val)) q = -q;
  385. }
  386. memcpy(buf, (char*)&q, SIZEOF_LONG_LONG);
  387. }
  388. VALUE
  389. rb_quad_unpack(const char *buf, int sign)
  390. {
  391. BDIGIT_DBL q;
  392. long neg = 0;
  393. long i;
  394. BDIGIT *digits;
  395. VALUE big;
  396. memcpy(&q, buf, SIZEOF_LONG_LONG);
  397. if (sign) {
  398. if (FIXABLE((LONG_LONG)q)) return LONG2FIX((LONG_LONG)q);
  399. if ((LONG_LONG)q < 0) {
  400. q = -(LONG_LONG)q;
  401. neg = 1;
  402. }
  403. }
  404. else {
  405. if (POSFIXABLE(q)) return LONG2FIX(q);
  406. }
  407. i = 0;
  408. big = bignew(DIGSPERLL, 1);
  409. digits = BDIGITS(big);
  410. while (i < DIGSPERLL) {
  411. digits[i++] = BIGLO(q);
  412. q = BIGDN(q);
  413. }
  414. i = DIGSPERLL;
  415. while (i-- && !digits[i]) ;
  416. RBIGNUM_SET_LEN(big, i+1);
  417. if (neg) {
  418. RBIGNUM_SET_SIGN(big, 0);
  419. }
  420. return bignorm(big);
  421. }
  422. #else
  423. static int
  424. quad_buf_complement(char *buf, size_t len)
  425. {
  426. size_t i;
  427. for (i = 0; i < len; i++)
  428. buf[i] = ~buf[i];
  429. for (i = 0; i < len; i++) {
  430. buf[i]++;
  431. if (buf[i] != 0)
  432. return 0;
  433. }
  434. return 1;
  435. }
  436. void
  437. rb_quad_pack(char *buf, VALUE val)
  438. {
  439. long len;
  440. memset(buf, 0, QUAD_SIZE);
  441. val = rb_to_int(val);
  442. if (FIXNUM_P(val)) {
  443. val = rb_int2big(FIX2LONG(val));
  444. }
  445. len = RBIGNUM_LEN(val) * SIZEOF_BDIGITS;
  446. if (len > QUAD_SIZE) {
  447. len = QUAD_SIZE;
  448. }
  449. memcpy(buf, (char*)BDIGITS(val), len);
  450. if (RBIGNUM_NEGATIVE_P(val)) {
  451. quad_buf_complement(buf, QUAD_SIZE);
  452. }
  453. }
  454. #define BNEG(b) (RSHIFT(((BDIGIT*)b)[QUAD_SIZE/SIZEOF_BDIGITS-1],BITSPERDIG-1) != 0)
  455. VALUE
  456. rb_quad_unpack(const char *buf, int sign)
  457. {
  458. VALUE big = bignew(QUAD_SIZE/SIZEOF_BDIGITS, 1);
  459. memcpy((char*)BDIGITS(big), buf, QUAD_SIZE);
  460. if (sign && BNEG(buf)) {
  461. char *tmp = (char*)BDIGITS(big);
  462. RBIGNUM_SET_SIGN(big, 0);
  463. quad_buf_complement(tmp, QUAD_SIZE);
  464. }
  465. return bignorm(big);
  466. }
  467. #endif
  468. VALUE
  469. rb_cstr_to_inum(const char *str, int base, int badcheck)
  470. {
  471. const char *s = str;
  472. char *end;
  473. char sign = 1, nondigit = 0;
  474. int c;
  475. BDIGIT_DBL num;
  476. long len, blen = 1;
  477. long i;
  478. VALUE z;
  479. BDIGIT *zds;
  480. #undef ISDIGIT
  481. #define ISDIGIT(c) ('0' <= (c) && (c) <= '9')
  482. #define conv_digit(c) \
  483. (!ISASCII(c) ? -1 : \
  484. ISDIGIT(c) ? ((c) - '0') : \
  485. ISLOWER(c) ? ((c) - 'a' + 10) : \
  486. ISUPPER(c) ? ((c) - 'A' + 10) : \
  487. -1)
  488. if (!str) {
  489. if (badcheck) goto bad;
  490. return INT2FIX(0);
  491. }
  492. while (ISSPACE(*str)) str++;
  493. if (str[0] == '+') {
  494. str++;
  495. }
  496. else if (str[0] == '-') {
  497. str++;
  498. sign = 0;
  499. }
  500. if (str[0] == '+' || str[0] == '-') {
  501. if (badcheck) goto bad;
  502. return INT2FIX(0);
  503. }
  504. if (base <= 0) {
  505. if (str[0] == '0') {
  506. switch (str[1]) {
  507. case 'x': case 'X':
  508. base = 16;
  509. break;
  510. case 'b': case 'B':
  511. base = 2;
  512. break;
  513. case 'o': case 'O':
  514. base = 8;
  515. break;
  516. case 'd': case 'D':
  517. base = 10;
  518. break;
  519. default:
  520. base = 8;
  521. }
  522. }
  523. else if (base < -1) {
  524. base = -base;
  525. }
  526. else {
  527. base = 10;
  528. }
  529. }
  530. switch (base) {
  531. case 2:
  532. len = 1;
  533. if (str[0] == '0' && (str[1] == 'b'||str[1] == 'B')) {
  534. str += 2;
  535. }
  536. break;
  537. case 3:
  538. len = 2;
  539. break;
  540. case 8:
  541. if (str[0] == '0' && (str[1] == 'o'||str[1] == 'O')) {
  542. str += 2;
  543. }
  544. case 4: case 5: case 6: case 7:
  545. len = 3;
  546. break;
  547. case 10:
  548. if (str[0] == '0' && (str[1] == 'd'||str[1] == 'D')) {
  549. str += 2;
  550. }
  551. case 9: case 11: case 12: case 13: case 14: case 15:
  552. len = 4;
  553. break;
  554. case 16:
  555. len = 4;
  556. if (str[0] == '0' && (str[1] == 'x'||str[1] == 'X')) {
  557. str += 2;
  558. }
  559. break;
  560. default:
  561. if (base < 2 || 36 < base) {
  562. rb_raise(rb_eArgError, "invalid radix %d", base);
  563. }
  564. if (base <= 32) {
  565. len = 5;
  566. }
  567. else {
  568. len = 6;
  569. }
  570. break;
  571. }
  572. if (*str == '0') { /* squeeze preceding 0s */
  573. int us = 0;
  574. while ((c = *++str) == '0' || c == '_') {
  575. if (c == '_') {
  576. if (++us >= 2)
  577. break;
  578. } else
  579. us = 0;
  580. }
  581. if (!(c = *str) || ISSPACE(c)) --str;
  582. }
  583. c = *str;
  584. c = conv_digit(c);
  585. if (c < 0 || c >= base) {
  586. if (badcheck) goto bad;
  587. return INT2FIX(0);
  588. }
  589. len *= strlen(str)*sizeof(char);
  590. if ((size_t)len <= (sizeof(long)*CHAR_BIT)) {
  591. unsigned long val = STRTOUL(str, &end, base);
  592. if (str < end && *end == '_') goto bigparse;
  593. if (badcheck) {
  594. if (end == str) goto bad; /* no number */
  595. while (*end && ISSPACE(*end)) end++;
  596. if (*end) goto bad; /* trailing garbage */
  597. }
  598. if (POSFIXABLE(val)) {
  599. if (sign) return LONG2FIX(val);
  600. else {
  601. long result = -(long)val;
  602. return LONG2FIX(result);
  603. }
  604. }
  605. else {
  606. VALUE big = rb_uint2big(val);
  607. RBIGNUM_SET_SIGN(big, sign);
  608. return bignorm(big);
  609. }
  610. }
  611. bigparse:
  612. len = (len/BITSPERDIG)+1;
  613. if (badcheck && *str == '_') goto bad;
  614. z = bignew(len, sign);
  615. zds = BDIGITS(z);
  616. for (i=len;i--;) zds[i]=0;
  617. while ((c = *str++) != 0) {
  618. if (c == '_') {
  619. if (nondigit) {
  620. if (badcheck) goto bad;
  621. break;
  622. }
  623. nondigit = c;
  624. continue;
  625. }
  626. else if ((c = conv_digit(c)) < 0) {
  627. break;
  628. }
  629. if (c >= base) break;
  630. nondigit = 0;
  631. i = 0;
  632. num = c;
  633. for (;;) {
  634. while (i<blen) {
  635. num += (BDIGIT_DBL)zds[i]*base;
  636. zds[i++] = BIGLO(num);
  637. num = BIGDN(num);
  638. }
  639. if (num) {
  640. blen++;
  641. continue;
  642. }
  643. break;
  644. }
  645. }
  646. if (badcheck) {
  647. str--;
  648. if (s+1 < str && str[-1] == '_') goto bad;
  649. while (*str && ISSPACE(*str)) str++;
  650. if (*str) {
  651. bad:
  652. rb_invalid_str(s, "Integer");
  653. }
  654. }
  655. return bignorm(z);
  656. }
  657. VALUE
  658. rb_str_to_inum(VALUE str, int base, int badcheck)
  659. {
  660. const char *s;
  661. long len;
  662. StringValue(str);
  663. str_check_ascii_compatible(str);
  664. if (badcheck) {
  665. s = StringValueCStr(str);
  666. }
  667. else {
  668. s = RSTRING_PTR(str);
  669. }
  670. if (s) {
  671. len = RSTRING_LEN(str);
  672. if (s[len]) { /* no sentinel somehow */
  673. char *p = ALLOCA_N(char, len+1);
  674. MEMCPY(p, s, char, len);
  675. p[len] = '\0';
  676. s = p;
  677. }
  678. }
  679. return rb_cstr_to_inum(s, base, badcheck);
  680. }
  681. #if HAVE_LONG_LONG
  682. VALUE
  683. rb_ull2big(unsigned long long n)
  684. {
  685. BDIGIT_DBL num = n;
  686. long i = 0;
  687. BDIGIT *digits;
  688. VALUE big;
  689. big = bignew(DIGSPERLL, 1);
  690. digits = BDIGITS(big);
  691. while (i < DIGSPERLL) {
  692. digits[i++] = BIGLO(num);
  693. num = BIGDN(num);
  694. }
  695. i = DIGSPERLL;
  696. while (i-- && !digits[i]) ;
  697. RBIGNUM_SET_LEN(big, i+1);
  698. return big;
  699. }
  700. VALUE
  701. rb_ll2big(long long n)
  702. {
  703. long neg = 0;
  704. VALUE big;
  705. if (n < 0) {
  706. n = -n;
  707. neg = 1;
  708. }
  709. big = rb_ull2big(n);
  710. if (neg) {
  711. RBIGNUM_SET_SIGN(big, 0);
  712. }
  713. return big;
  714. }
  715. #endif /* HAVE_LONG_LONG */
  716. VALUE
  717. rb_cstr2inum(const char *str, int base)
  718. {
  719. return rb_cstr_to_inum(str, base, base==0);
  720. }
  721. VALUE
  722. rb_str2inum(VALUE str, int base)
  723. {
  724. return rb_str_to_inum(str, base, base==0);
  725. }
  726. const char ruby_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz";
  727. static VALUE bigsqr(VALUE x);
  728. static void bigdivmod(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp);
  729. #define POW2_P(x) (((x)&((x)-1))==0)
  730. static inline int
  731. ones(register unsigned long x)
  732. {
  733. #if SIZEOF_LONG == 8
  734. # define MASK_55 0x5555555555555555UL
  735. # define MASK_33 0x3333333333333333UL
  736. # define MASK_0f 0x0f0f0f0f0f0f0f0fUL
  737. #else
  738. # define MASK_55 0x55555555UL
  739. # define MASK_33 0x33333333UL
  740. # define MASK_0f 0x0f0f0f0fUL
  741. #endif
  742. x -= (x >> 1) & MASK_55;
  743. x = ((x >> 2) & MASK_33) + (x & MASK_33);
  744. x = ((x >> 4) + x) & MASK_0f;
  745. x += (x >> 8);
  746. x += (x >> 16);
  747. #if SIZEOF_LONG == 8
  748. x += (x >> 32);
  749. #endif
  750. return (int)(x & 0x7f);
  751. #undef MASK_0f
  752. #undef MASK_33
  753. #undef MASK_55
  754. }
  755. static inline unsigned long
  756. next_pow2(register unsigned long x)
  757. {
  758. x |= x >> 1;
  759. x |= x >> 2;
  760. x |= x >> 4;
  761. x |= x >> 8;
  762. x |= x >> 16;
  763. #if SIZEOF_LONG == 8
  764. x |= x >> 32;
  765. #endif
  766. return x + 1;
  767. }
  768. static inline int
  769. floor_log2(register unsigned long x)
  770. {
  771. x |= x >> 1;
  772. x |= x >> 2;
  773. x |= x >> 4;
  774. x |= x >> 8;
  775. x |= x >> 16;
  776. #if SIZEOF_LONG == 8
  777. x |= x >> 32;
  778. #endif
  779. return (int)ones(x) - 1;
  780. }
  781. static inline int
  782. ceil_log2(register unsigned long x)
  783. {
  784. return floor_log2(x) + !POW2_P(x);
  785. }
  786. #define LOG2_KARATSUBA_DIGITS 7
  787. #define KARATSUBA_DIGITS (1L<<LOG2_KARATSUBA_DIGITS)
  788. #define MAX_BIG2STR_TABLE_ENTRIES 64
  789. static VALUE big2str_power_cache[35][MAX_BIG2STR_TABLE_ENTRIES];
  790. static void
  791. power_cache_init(void)
  792. {
  793. int i, j;
  794. for (i = 0; i < 35; ++i) {
  795. for (j = 0; j < MAX_BIG2STR_TABLE_ENTRIES; ++j) {
  796. big2str_power_cache[i][j] = Qnil;
  797. }
  798. }
  799. }
  800. static inline VALUE
  801. power_cache_get_power0(int base, int i)
  802. {
  803. if (NIL_P(big2str_power_cache[base - 2][i])) {
  804. big2str_power_cache[base - 2][i] =
  805. i == 0 ? rb_big_pow(rb_int2big(base), INT2FIX(KARATSUBA_DIGITS))
  806. : bigsqr(power_cache_get_power0(base, i - 1));
  807. GC_RETAIN(big2str_power_cache[base - 2][i]);
  808. }
  809. return big2str_power_cache[base - 2][i];
  810. }
  811. static VALUE
  812. power_cache_get_power(int base, long n1, long* m1)
  813. {
  814. int i, m;
  815. long j;
  816. VALUE t;
  817. if (n1 <= KARATSUBA_DIGITS)
  818. rb_bug("n1 > KARATSUBA_DIGITS");
  819. m = ceil_log2(n1);
  820. if (m1) *m1 = 1 << m;
  821. i = m - LOG2_KARATSUBA_DIGITS;
  822. if (i >= MAX_BIG2STR_TABLE_ENTRIES)
  823. i = MAX_BIG2STR_TABLE_ENTRIES - 1;
  824. t = power_cache_get_power0(base, i);
  825. j = KARATSUBA_DIGITS*(1 << i);
  826. while (n1 > j) {
  827. t = bigsqr(t);
  828. j *= 2;
  829. }
  830. return t;
  831. }
  832. /* big2str_muraken_find_n1
  833. *
  834. * Let a natural number x is given by:
  835. * x = 2^0 * x_0 + 2^1 * x_1 + ... + 2^(B*n_0 - 1) * x_{B*n_0 - 1},
  836. * where B is BITSPERDIG (i.e. BDIGITS*CHAR_BIT) and n_0 is
  837. * RBIGNUM_LEN(x).
  838. *
  839. * Now, we assume n_1 = min_n \{ n | 2^(B*n_0/2) <= b_1^(n_1) \}, so
  840. * it is realized that 2^(B*n_0) <= {b_1}^{2*n_1}, where b_1 is a
  841. * given radix number. And then, we have n_1 <= (B*n_0) /
  842. * (2*log_2(b_1)), therefore n_1 is given by ceil((B*n_0) /
  843. * (2*log_2(b_1))).
  844. */
  845. static long
  846. big2str_find_n1(VALUE x, int base)
  847. {
  848. static const double log_2[] = {
  849. 1.0, 1.58496250072116, 2.0,
  850. 2.32192809488736, 2.58496250072116, 2.8073549220576,
  851. 3.0, 3.16992500144231, 3.32192809488736,
  852. 3.4594316186373, 3.58496250072116, 3.70043971814109,
  853. 3.8073549220576, 3.90689059560852, 4.0,
  854. 4.08746284125034, 4.16992500144231, 4.24792751344359,
  855. 4.32192809488736, 4.39231742277876, 4.4594316186373,
  856. 4.52356195605701, 4.58496250072116, 4.64385618977472,
  857. 4.70043971814109, 4.75488750216347, 4.8073549220576,
  858. 4.85798099512757, 4.90689059560852, 4.95419631038688,
  859. 5.0, 5.04439411935845, 5.08746284125034,
  860. 5.12928301694497, 5.16992500144231
  861. };
  862. long bits;
  863. if (base < 2 || 36 < base)
  864. rb_bug("invalid radix %d", base);
  865. if (FIXNUM_P(x)) {
  866. bits = (SIZEOF_LONG*CHAR_BIT - 1)/2 + 1;
  867. }
  868. else if (BIGZEROP(x)) {
  869. return 0;
  870. }
  871. else if (RBIGNUM_LEN(x) >= LONG_MAX/BITSPERDIG) {
  872. rb_raise(rb_eRangeError, "bignum too big to convert into `string'");
  873. }
  874. else {
  875. bits = BITSPERDIG*RBIGNUM_LEN(x);
  876. }
  877. return (long)ceil(bits/log_2[base - 2]);
  878. }
  879. static long
  880. big2str_orig(VALUE x, int base, char* ptr, long len, long hbase, int trim)
  881. {
  882. long i = RBIGNUM_LEN(x), j = len;
  883. BDIGIT* ds = BDIGITS(x);
  884. while (i && j > 0) {
  885. long k = i;
  886. BDIGIT_DBL num = 0;
  887. while (k--) { /* x / hbase */
  888. num = BIGUP(num) + ds[k];
  889. ds[k] = (BDIGIT)(num / hbase);
  890. num %= hbase;
  891. }
  892. if (trim && ds[i-1] == 0) i--;
  893. #if defined(__LP64__) && (MAC_OS_X_VERSION_MAX_ALLOWED >= 1060)
  894. k = SIZEOF_BDIGITS/2;
  895. #else
  896. k = SIZEOF_BDIGITS;
  897. #endif
  898. while (k--) {
  899. ptr[--j] = ruby_digitmap[num % base];
  900. num /= base;
  901. if (j <= 0) break;
  902. if (trim && i == 0 && num == 0) break;
  903. }
  904. }
  905. if (trim) {
  906. while (j < len && ptr[j] == '0') j++;
  907. MEMMOVE(ptr, ptr + j, char, len - j);
  908. len -= j;
  909. }
  910. return len;
  911. }
  912. static long
  913. big2str_karatsuba(VALUE x, int base, char* ptr,
  914. long n1, long len, long hbase, int trim)
  915. {
  916. long lh, ll, m1;
  917. VALUE b, q, r;
  918. if (FIXNUM_P(x)) {
  919. VALUE str = rb_fix2str(x, base);
  920. const char* str_ptr = RSTRING_PTR(str);
  921. long str_len = RSTRING_LEN(str);
  922. if (trim) {
  923. if (FIX2INT(x) == 0) return 0;
  924. MEMCPY(ptr, str_ptr, char, str_len);
  925. return str_len;
  926. }
  927. else {
  928. memset(ptr, '0', len - str_len);
  929. MEMCPY(ptr + len - str_len, str_ptr, char, str_len);
  930. return len;
  931. }
  932. }
  933. if (BIGZEROP(x)) {
  934. if (trim) return 0;
  935. else {
  936. memset(ptr, '0', len);
  937. return len;
  938. }
  939. }
  940. if (n1 <= KARATSUBA_DIGITS) {
  941. return big2str_orig(x, base, ptr, len, hbase, trim);
  942. }
  943. b = power_cache_get_power(base, n1, &m1);
  944. bigdivmod(x, b, &q, &r);
  945. lh = big2str_karatsuba(q, base, ptr, (len - m1)/2,
  946. len - m1, hbase, trim);
  947. rb_big_resize(q, 0);
  948. ll = big2str_karatsuba(r, base, ptr + lh, m1/2,
  949. m1, hbase, !lh && trim);
  950. rb_big_resize(r, 0);
  951. return lh + ll;
  952. }
  953. VALUE
  954. rb_big2str0(VALUE x, int base, int trim)
  955. {
  956. int off;
  957. VALUE xx;
  958. long n1, n2, len, hbase;
  959. char* ptr;
  960. if (FIXNUM_P(x)) {
  961. return rb_fix2str(x, base);
  962. }
  963. if (BIGZEROP(x)) {
  964. return rb_usascii_str_new2("0");
  965. }
  966. if (base < 2 || 36 < base)
  967. rb_raise(rb_eArgError, "invalid radix %d", base);
  968. n2 = big2str_find_n1(x, base);
  969. n1 = (n2 + 1) / 2;
  970. ptr = (char *)alloca(n2 + 1); /* plus one for sign */
  971. ptr[0] = RBIGNUM_SIGN(x) ? '+' : '-';
  972. hbase = base*base;
  973. #if SIZEOF_BDIGITS > 2
  974. hbase *= hbase;
  975. #endif
  976. off = !(trim && RBIGNUM_SIGN(x)); /* erase plus sign if trim */
  977. xx = rb_big_clone(x);
  978. RBIGNUM_SET_SIGN(xx, 1);
  979. if (n1 <= KARATSUBA_DIGITS) {
  980. len = off + big2str_orig(xx, base, ptr + off, n2, hbase, trim);
  981. }
  982. else {
  983. len = off + big2str_karatsuba(xx, base, ptr + off, n1,
  984. n2, hbase, trim);
  985. }
  986. rb_big_resize(xx, 0);
  987. ptr[len] = '\0';
  988. return rb_usascii_str_new2(ptr);
  989. }
  990. VALUE
  991. rb_big2str(VALUE x, int base)
  992. {
  993. return rb_big2str0(x, base, 1);
  994. }
  995. /*
  996. * call-seq:
  997. * big.to_s(base=10) -> string
  998. *
  999. * Returns a string containing the representation of <i>big</i> radix
  1000. * <i>base</i> (2 through 36).
  1001. *
  1002. * 12345654321.to_s #=> "12345654321"
  1003. * 12345654321.to_s(2) #=> "1011011111110110111011110000110001"
  1004. * 12345654321.to_s(8) #=> "133766736061"
  1005. * 12345654321.to_s(16) #=> "2dfdbbc31"
  1006. * 78546939656932.to_s(36) #=> "rubyrules"
  1007. */
  1008. static VALUE
  1009. rb_big_to_s(VALUE x, SEL sel, int argc, VALUE *argv)
  1010. {
  1011. int base;
  1012. if (argc == 0) base = 10;
  1013. else {
  1014. VALUE b;
  1015. rb_scan_args(argc, argv, "01", &b);
  1016. base = NUM2INT(b);
  1017. }
  1018. return rb_big2str(x, base);
  1019. }
  1020. static VALUE
  1021. big2ulong(VALUE x, const char *type, int check)
  1022. {
  1023. long len = RBIGNUM_LEN(x);
  1024. BDIGIT_DBL num;
  1025. BDIGIT *ds;
  1026. if (len > DIGSPERLONG) {
  1027. if (check)
  1028. rb_raise(rb_eRangeError, "bignum too big to convert into `%s'", type);
  1029. len = DIGSPERLONG;
  1030. }
  1031. ds = BDIGITS(x);
  1032. num = 0;
  1033. while (len--) {
  1034. num = BIGUP(num);
  1035. num += ds[len];
  1036. }
  1037. return (VALUE)num;
  1038. }
  1039. VALUE
  1040. rb_big2ulong_pack(VALUE x)
  1041. {
  1042. VALUE num = big2ulong(x, "unsigned long", FALSE);
  1043. if (!RBIGNUM_SIGN(x)) {
  1044. return (VALUE)(-(SIGNED_VALUE)num);
  1045. }
  1046. return num;
  1047. }
  1048. VALUE
  1049. rb_big2ulong(VALUE x)
  1050. {
  1051. VALUE num = big2ulong(x, "unsigned long", TRUE);
  1052. if (!RBIGNUM_SIGN(x)) {
  1053. if ((SIGNED_VALUE)num < 0) {
  1054. rb_raise(rb_eRangeError, "bignum out of range of unsigned long");
  1055. }
  1056. return (VALUE)(-(SIGNED_VALUE)num);
  1057. }
  1058. return num;
  1059. }
  1060. SIGNED_VALUE
  1061. rb_big2long(VALUE x)
  1062. {
  1063. VALUE num = big2ulong(x, "long", TRUE);
  1064. if ((SIGNED_VALUE)num < 0 &&
  1065. (RBIGNUM_SIGN(x) || (SIGNED_VALUE)num != LONG_MIN)) {
  1066. rb_raise(rb_eRangeError, "bignum too big to convert into `long'");
  1067. }
  1068. if (!RBIGNUM_SIGN(x)) return -(SIGNED_VALUE)num;
  1069. return num;
  1070. }
  1071. #if HAVE_LONG_LONG
  1072. static unsigned LONG_LONG
  1073. big2ull(VALUE x, const char *type)
  1074. {
  1075. long len = RBIGNUM_LEN(x);
  1076. BDIGIT_DBL num;
  1077. BDIGIT *ds;
  1078. if (len > SIZEOF_LONG_LONG/SIZEOF_BDIGITS)
  1079. rb_raise(rb_eRangeError, "bignum too big to convert into `%s'", type);
  1080. ds = BDIGITS(x);
  1081. num = 0;
  1082. while (len--) {
  1083. num = BIGUP(num);
  1084. num += ds[len];
  1085. }
  1086. return num;
  1087. }
  1088. unsigned LONG_LONG
  1089. rb_big2ull(VALUE x)
  1090. {
  1091. unsigned LONG_LONG num = big2ull(x, "unsigned long long");
  1092. if (!RBIGNUM_SIGN(x)) return -num;
  1093. return num;
  1094. }
  1095. LONG_LONG
  1096. rb_big2ll(VALUE x)
  1097. {
  1098. unsigned LONG_LONG num = big2ull(x, "long long");
  1099. // This check is disabled because this function might be called from
  1100. // compiler stubs which will pass negative values as long long times
  1101. // for certain Cocoa APIs (generally fixed values like -1 or -2).
  1102. #if 0
  1103. if ((LONG_LONG)num < 0 && (RBIGNUM_SIGN(x)
  1104. || (LONG_LONG)num != LLONG_MIN)) {
  1105. rb_raise(rb_eRangeError, "bignum too big to convert into `long long'");
  1106. }
  1107. #endif
  1108. if (!RBIGNUM_SIGN(x)) return -(LONG_LONG)num;
  1109. return num;
  1110. }
  1111. #endif /* HAVE_LONG_LONG */
  1112. static VALUE
  1113. dbl2big(double d)
  1114. {
  1115. long i = 0;
  1116. BDIGIT c;
  1117. BDIGIT *digits;
  1118. VALUE z;
  1119. double u = (d < 0)?-d:d;
  1120. if (isinf(d)) {
  1121. rb_raise(rb_eFloatDomainError, d < 0 ? "-Infinity" : "Infinity");
  1122. }
  1123. if (isnan(d)) {
  1124. rb_raise(rb_eFloatDomainError, "NaN");
  1125. }
  1126. while (!POSFIXABLE(u) || 0 != (long)u) {
  1127. u /= (double)(BIGRAD);
  1128. i++;
  1129. }
  1130. z = bignew(i, d>=0);
  1131. digits = BDIGITS(z);
  1132. while (i--) {
  1133. u *= BIGRAD;
  1134. c = (BDIGIT)u;
  1135. u -= c;
  1136. digits[i] = c;
  1137. }
  1138. return z;
  1139. }
  1140. VALUE
  1141. rb_dbl2big(double d)
  1142. {
  1143. return bignorm(dbl2big(d));
  1144. }
  1145. static int
  1146. nlz(BDIGIT x)
  1147. {
  1148. BDIGIT y;
  1149. int n = BITSPERDIG;
  1150. #if BITSPERDIG > 64
  1151. y = x >> 64; if (y) {n -= 64; x = y;}
  1152. #endif
  1153. #if BITSPERDIG > 32
  1154. y = x >> 32; if (y) {n -= 32; x = y;}
  1155. #endif
  1156. #if BITSPERDIG > 16
  1157. y = x >> 16; if (y) {n -= 16; x = y;}
  1158. #endif
  1159. y = x >> 8; if (y) {n -= 8; x = y;}
  1160. y = x >> 4; if (y) {n -= 4; x = y;}
  1161. y = x >> 2; if (y) {n -= 2; x = y;}
  1162. y = x >> 1; if (y) {return n - 2;}
  1163. return n - x;
  1164. }
  1165. static double
  1166. big2dbl(VALUE x)
  1167. {
  1168. double d = 0.0;
  1169. long i = (bigtrunc(x), RBIGNUM_LEN(x)), lo = 0, bits;
  1170. BDIGIT *ds = BDIGITS(x), dl;
  1171. if (i) {
  1172. bits = i * BITSPERDIG - nlz(ds[i-1]);
  1173. if (bits > DBL_MANT_DIG+DBL_MAX_EXP) {
  1174. d = HUGE_VAL;
  1175. }
  1176. else {
  1177. if (bits > DBL_MANT_DIG+1)
  1178. lo = (bits -= DBL_MANT_DIG+1) / BITSPERDIG;
  1179. else
  1180. bits = 0;
  1181. while (--i > lo) {
  1182. d = ds[i] + BIGRAD*d;
  1183. }
  1184. dl = ds[i];
  1185. if (bits && (dl & (1UL << (bits %= BITSPERDIG)))) {
  1186. int carry = dl & ~(~(BDIGIT)0 << bits);
  1187. if (!carry) {
  1188. while (i-- > 0) {
  1189. if ((carry = ds[i]) != 0) break;
  1190. }
  1191. }
  1192. if (carry) {
  1193. dl &= (BDIGIT)~0 << bits;
  1194. dl += (BDIGIT)1 << bits;
  1195. if (!dl) d += 1;
  1196. }
  1197. }
  1198. d = dl + BIGRAD*d;
  1199. if (lo) {
  1200. if (lo > INT_MAX / BITSPERDIG)
  1201. d = HUGE_VAL;
  1202. else if (lo < INT_MIN / BITSPERDIG)
  1203. d = 0.0;
  1204. else
  1205. d = ldexp(d, (int)(lo * BITSPERDIG));
  1206. }
  1207. }
  1208. }
  1209. if (!RBIGNUM_SIGN(x)) d = -d;
  1210. return d;
  1211. }
  1212. double
  1213. rb_big2dbl(VALUE x)
  1214. {
  1215. double d = big2dbl(x);
  1216. if (isinf(d)) {
  1217. rb_warning("Bignum out of Float range");
  1218. if (d < 0.0)
  1219. d = -HUGE_VAL;
  1220. else
  1221. d = HUGE_VAL;
  1222. }
  1223. return d;
  1224. }
  1225. /*
  1226. * call-seq:
  1227. * big.to_f -> float
  1228. *
  1229. * Converts <i>big</i> to a <code>Float</code>. If <i>big</i> doesn't
  1230. * fit in a <code>Float</code>, the result is infinity.
  1231. *
  1232. */
  1233. static VALUE
  1234. rb_big_to_f(VALUE x, SEL sel)
  1235. {
  1236. return DBL2NUM(rb_big2dbl(x));
  1237. }
  1238. /*
  1239. * call-seq:
  1240. * big <=> numeric -> -1, 0, +1 or nil
  1241. *
  1242. * Comparison---Returns -1, 0, or +1 depending on whether <i>big</i> is
  1243. * less than, equal to, or greater than <i>numeric</i>. This is the
  1244. * basis for the tests in <code>Comparable</code>.
  1245. *
  1246. */
  1247. VALUE
  1248. rb_big_cmp(VALUE x, VALUE y)
  1249. {
  1250. long xlen = RBIGNUM_LEN(x);
  1251. BDIGIT *xds, *yds;
  1252. switch (TYPE(y)) {
  1253. case T_FIXNUM:
  1254. y = rb_int2big(FIX2LONG(y));
  1255. break;
  1256. case T_BIGNUM:
  1257. break;
  1258. case T_FLOAT:
  1259. {
  1260. double a = RFLOAT_VALUE(y);
  1261. if (isinf(a)) {
  1262. if (a > 0.0) return INT2FIX(-1);
  1263. else return INT2FIX(1);
  1264. }
  1265. return rb_dbl_cmp(rb_big2dbl(x), a);
  1266. }
  1267. default:
  1268. return rb_num_coerce_cmp(x, y, rb_intern("<=>"));
  1269. }
  1270. if (RBIGNUM_SIGN(x) > RBIGNUM_SIGN(y)) return INT2FIX(1);
  1271. if (RBIGNUM_SIGN(x) < RBIGNUM_SIGN(y)) return INT2FIX(-1);
  1272. if (xlen < RBIGNUM_LEN(y))
  1273. return (RBIGNUM_SIGN(x)) ? INT2FIX(-1) : INT2FIX(1);
  1274. if (xlen > RBIGNUM_LEN(y))
  1275. return (RBIGNUM_SIGN(x)) ? INT2FIX(1) : INT2FIX(-1);
  1276. xds = BDIGITS(x);
  1277. yds = BDIGITS(y);
  1278. while(xlen-- && (xds[xlen]==yds[xlen]));
  1279. if (-1 == xlen) return INT2FIX(0);
  1280. return (xds[xlen] > yds[xlen]) ?
  1281. (RBIGNUM_SIGN(x) ? INT2FIX(1) : INT2FIX(-1)) :
  1282. (RBIGNUM_SIGN(x) ? INT2FIX(-1) : INT2FIX(1));
  1283. }
  1284. static VALUE
  1285. rb_big_cmp_imp(VALUE x, SEL sel, VALUE y)
  1286. {
  1287. return rb_big_cmp(x, y);
  1288. }
  1289. static VALUE
  1290. big_op(VALUE x, VALUE y, int op)
  1291. {
  1292. VALUE rel;
  1293. int n;
  1294. switch (TYPE(y)) {
  1295. case T_FIXNUM:
  1296. case T_BIGNUM:
  1297. rel = rb_big_cmp(x, y);
  1298. break;
  1299. case T_FLOAT:
  1300. {
  1301. double a = RFLOAT_VALUE(y);
  1302. if (isinf(a)) {
  1303. if (a > 0.0) rel = INT2FIX(-1);
  1304. else rel = INT2FIX(1);
  1305. break;
  1306. }
  1307. rel = rb_dbl_cmp(rb_big2dbl(x), a);
  1308. break;
  1309. }
  1310. default:
  1311. {
  1312. ID id = 0;
  1313. switch (op) {
  1314. case 0: id = '>'; break;
  1315. case 1: id = rb_intern(">="); break;
  1316. case 2: id = '<'; break;
  1317. case 3: id = rb_intern("<="); break;
  1318. }
  1319. return rb_num_coerce_relop(x, y, id);
  1320. }
  1321. }
  1322. if (NIL_P(rel)) return Qfalse;
  1323. n = FIX2INT(rel);
  1324. switch (op) {
  1325. case 0: return n > 0 ? Qtrue : Qfalse;
  1326. case 1: return n >= 0 ? Qtrue : Qfalse;
  1327. case 2: return n < 0 ? Qtrue : Qfalse;
  1328. case 3: return n <= 0 ? Qtrue : Qfalse;
  1329. }
  1330. return Qundef;
  1331. }
  1332. /*
  1333. * call-seq:
  1334. * big > real -> true or false
  1335. *
  1336. * Returns <code>true</code> if the value of <code>big</code> is
  1337. * greater than that of <code>real</code>.
  1338. */
  1339. static VALUE
  1340. big_gt(VALUE x, SEL sel, VALUE y)
  1341. {
  1342. return big_op(x, y, 0);
  1343. }
  1344. /*
  1345. * call-seq:
  1346. * big >= real -> true or false
  1347. *
  1348. * Returns <code>true</code> if the value of <code>big</code> is
  1349. * greater than or equal to that of <code>real</code>.
  1350. */
  1351. static VALUE
  1352. big_ge(VALUE x, SEL sel, VALUE y)
  1353. {
  1354. return big_op(x, y, 1);
  1355. }
  1356. /*
  1357. * call-seq:
  1358. * big < real -> true or false
  1359. *
  1360. * Returns <code>true</code> if the value of <code>big</code> is
  1361. * less than that of <code>real</code>.
  1362. */
  1363. static VALUE
  1364. big_lt(VALUE x, SEL sel, VALUE y)
  1365. {
  1366. return big_op(x, y, 2);
  1367. }
  1368. /*
  1369. * call-seq:
  1370. * big <= real -> true or false
  1371. *
  1372. * Returns <code>true</code> if the value of <code>big</code> is
  1373. * less than or equal to that of <code>real</code>.
  1374. */
  1375. static VALUE
  1376. big_le(VALUE x, SEL sel, VALUE y)
  1377. {
  1378. return big_op(x, y, 3);
  1379. }
  1380. /*
  1381. * call-seq:
  1382. * big == obj -> true or false
  1383. *
  1384. * Returns <code>true</code> only if <i>obj</i> has the same value
  1385. * as <i>big</i>. Contrast this with <code>Bignum#eql?</code>, which
  1386. * requires <i>obj</i> to be a <code>Bignum</code>.
  1387. *
  1388. * 68719476736 == 68719476736.0 #=> true
  1389. */
  1390. VALUE
  1391. rb_big_eq_imp(VALUE x, SEL sel, VALUE y)
  1392. {
  1393. return rb_big_eq(x, y);
  1394. }
  1395. VALUE
  1396. rb_big_eq(VALUE x, VALUE y)
  1397. {
  1398. switch (TYPE(y)) {
  1399. case T_FIXNUM:
  1400. y = rb_int2big(FIX2LONG(y));
  1401. break;
  1402. case T_BIGNUM:
  1403. break;
  1404. case T_FLOAT:
  1405. {
  1406. volatile double a, b;
  1407. a = RFLOAT_VALUE(y);
  1408. if (isnan(a)) return Qfalse;
  1409. b = rb_big2dbl(x);
  1410. return (a == b)?Qtrue:Qfalse;
  1411. }
  1412. default:
  1413. return rb_equal(y, x);
  1414. }
  1415. if (RBIGNUM_SIGN(x) != RBIGNUM_SIGN(y)) return Qfalse;
  1416. if (RBIGNUM_LEN(x) != RBIGNUM_LEN(y)) return Qfalse;
  1417. if (MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,RBIGNUM_LEN(y)) != 0) return Qfalse;
  1418. return Qtrue;
  1419. }
  1420. /*
  1421. * call-seq:
  1422. * big.eql?(obj) -> true or false
  1423. *
  1424. * Returns <code>true</code> only if <i>obj</i> is a
  1425. * <code>Bignum</code> with the same value as <i>big</i>. Contrast this
  1426. * with <code>Bignum#==</code>, which performs type conversions.
  1427. *
  1428. * 68719476736.eql?(68719476736.0) #=> false
  1429. */
  1430. static VALUE
  1431. rb_big_eql(VALUE x, SEL sel, VALUE y)
  1432. {
  1433. if (TYPE(y) != T_BIGNUM) return Qfalse;
  1434. if (RBIGNUM_SIGN(x) != RBIGNUM_SIGN(y)) return Qfalse;
  1435. if (RBIGNUM_LEN(x) != RBIGNUM_LEN(y)) return Qfalse;
  1436. if (MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,RBIGNUM_LEN(y)) != 0) return Qfalse;
  1437. return Qtrue;
  1438. }
  1439. /*
  1440. * call-seq:
  1441. * -big -> integer
  1442. *
  1443. * Unary minus (returns an integer whose value is 0-big)
  1444. */
  1445. VALUE
  1446. rb_big_uminus(VALUE x)
  1447. {
  1448. VALUE z = rb_big_clone(x);
  1449. RBIGNUM_SET_SIGN(z, !RBIGNUM_SIGN(x));
  1450. return bignorm(z);
  1451. }
  1452. static VALUE
  1453. rb_big_uminus_imp(VALUE x, SEL sel)
  1454. {
  1455. return rb_big_uminus(x);
  1456. }
  1457. /*
  1458. * call-seq:
  1459. * ~big -> integer
  1460. *
  1461. * Inverts the bits in big. As Bignums are conceptually infinite
  1462. * length, the result acts as if it had an infinite number of one
  1463. * bits to the left. In hex representations, this is displayed
  1464. * as two periods to the left of the digits.
  1465. *
  1466. * sprintf("%X", ~0x1122334455) #=> "..FEEDDCCBBAA"
  1467. */
  1468. static VALUE
  1469. rb_big_neg(VALUE x, SEL sel)
  1470. {
  1471. VALUE z = rb_big_clone(x);
  1472. BDIGIT *ds;
  1473. long i;
  1474. if (!RBIGNUM_SIGN(x)) get2comp(z);
  1475. ds = BDIGITS(z);
  1476. i = RBIGNUM_LEN(x);
  1477. if (!i) return INT2FIX(~(SIGNED_VALUE)0);
  1478. while (i--) {
  1479. ds[i] = ~ds[i];
  1480. }
  1481. RBIGNUM_SET_SIGN(z, !RBIGNUM_SIGN(z));
  1482. if (RBIGNUM_SIGN(x)) get2comp(z);
  1483. return bignorm(z);
  1484. }
  1485. static void
  1486. bigsub_core(BDIGIT *xds, long xn, BDIGIT *yds, long yn, BDIGIT *zds, long zn)
  1487. {
  1488. BDIGIT_DBL_SIGNED num;
  1489. long i;
  1490. for (i = 0, num = 0; i < yn; i++) {
  1491. num += (BDIGIT_DBL_SIGNED)xds[i] - yds[i];
  1492. zds[i] = BIGLO(num);
  1493. num = BIGDN(num);
  1494. }
  1495. while (num && i < xn) {
  1496. num += xds[i];
  1497. zds[i++] = BIGLO(num);
  1498. num = BIGDN(num);
  1499. }
  1500. while (i < xn) {
  1501. zds[i] = xds[i];
  1502. i++;
  1503. }
  1504. assert(i <= zn);
  1505. while (i < zn) {
  1506. zds[i++] = 0;
  1507. }
  1508. }
  1509. static VALUE
  1510. bigsub(VALUE x, VALUE y)
  1511. {
  1512. VALUE z = 0;
  1513. long i = RBIGNUM_LEN(x);
  1514. BDIGIT *xds, *yds;
  1515. /* if x is larger than y, swap */
  1516. if (RBIGNUM_LEN(x) < RBIGNUM_LEN(y)) {
  1517. z = x; x = y; y = z; /* swap x y */
  1518. }
  1519. else if (RBIGNUM_LEN(x) == RBIGNUM_LEN(y)) {
  1520. xds = BDIGITS(x);
  1521. yds = BDIGITS(y);
  1522. while (i > 0) {
  1523. i--;
  1524. if (xds[i] > yds[i]) {
  1525. break;
  1526. }
  1527. if (xds[i] < yds[i]) {
  1528. z = x; x = y; y = z; /* swap x y */
  1529. break;
  1530. }
  1531. }
  1532. }
  1533. z = bignew(RBIGNUM_LEN(x), z==0);
  1534. bigsub_core(BDIGITS(x), RBIGNUM_LEN(x),
  1535. BDIGITS(y), RBIGNUM_LEN(y),
  1536. BDIGITS(z), RBIGNUM_LEN(z));
  1537. return z;
  1538. }
  1539. static VALUE bigadd_int(VALUE x, long y);
  1540. static VALUE
  1541. bigsub_int(VALUE x, long y0)
  1542. {
  1543. VALUE z;
  1544. BDIGIT *xds, *zds;
  1545. long xn;
  1546. BDIGIT_DBL_SIGNED num;
  1547. long i, y;
  1548. y = y0;
  1549. xds = BDIGITS(x);
  1550. xn = RBIGNUM_LEN(x);
  1551. z = bignew(xn, RBIGNUM_SIGN(x));
  1552. zds = BDIGITS(z);
  1553. #if SIZEOF_BDIGITS == SIZEOF_LONG
  1554. num = (BDIGIT_DBL_SIGNED)xds[0] - y;
  1555. if (xn == 1 && num < 0) {
  1556. RBIGNUM_SET_SIGN(z, !RBIGNUM_SIGN(x));
  1557. zds[0] = (BDIGIT)-num;
  1558. return bignorm(z);
  1559. }
  1560. zds[0] = BIGLO(num);
  1561. num = BIGDN(num);
  1562. i = 1;
  1563. #else
  1564. num = 0;
  1565. for (i=0; i<(int)(sizeof(y)/sizeof(BDIGIT)); i++) {
  1566. num += (BDIGIT_DBL_SIGNED)xds[i] - BIGLO(y);
  1567. zds[i] = BIGLO(num);
  1568. num = BIGDN(num);
  1569. y = BIGDN(y);
  1570. }
  1571. #endif
  1572. while (num && i < xn) {
  1573. num += xds[i];
  1574. zds[i++] = BIGLO(num);
  1575. num = BIGDN(num);
  1576. }
  1577. while (i < xn) {
  1578. zds[i] = xds[i];
  1579. i++;
  1580. }
  1581. if (num < 0) {
  1582. z = bigsub(x, rb_int2big(y0));
  1583. }
  1584. return bignorm(z);
  1585. }
  1586. static VALUE
  1587. bigadd_int(VALUE x, long y)
  1588. {
  1589. VALUE z;
  1590. BDIGIT *xds, *zds;
  1591. long xn, zn;
  1592. BDIGIT_DBL num;
  1593. long i;
  1594. xds = BDIGITS(x);
  1595. xn = RBIGNUM_LEN(x);
  1596. if (xn < 2) {
  1597. zn = 3;
  1598. }
  1599. else {
  1600. zn = xn + 1;
  1601. }
  1602. z = bignew(zn, RBIGNUM_SIGN(x));
  1603. zds = BDIGITS(z);
  1604. #if SIZEOF_BDIGITS == SIZEOF_LONG
  1605. num = (BDIGIT_DBL)xds[0] + y;
  1606. zds[0] = BIGLO(num);
  1607. num = BIGDN(num);
  1608. i = 1;
  1609. #else
  1610. num = 0;
  1611. for (i=0; i<(int)(sizeof(y)/sizeof(BDIGIT)); i++) {
  1612. num += (BDIGIT_DBL)xds[i] + BIGLO(y);
  1613. zds[i] = BIGLO(num);
  1614. num = BIGDN(num);
  1615. y = BIGDN(y);
  1616. }
  1617. #endif
  1618. while (num && i < xn) {
  1619. num += xds[i];
  1620. zds[i++] = BIGLO(num);
  1621. num = BIGDN(num);
  1622. }
  1623. if (num) zds[i++] = (BDIGIT)num;
  1624. else while (i < xn) {
  1625. zds[i] = xds[i];
  1626. i++;
  1627. }
  1628. assert(i <= zn);
  1629. while (i < zn) {
  1630. zds[i++] = 0;
  1631. }
  1632. return bignorm(z);
  1633. }
  1634. static void
  1635. bigadd_core(BDIGIT *xds, long xn, BDIGIT *yds, long yn, BDIGIT *zds, long zn)
  1636. {
  1637. BDIGIT_DBL num = 0;
  1638. long i;
  1639. if (xn > yn) {
  1640. BDIGIT *tds;
  1641. tds = xds; xds = yds; yds = tds;
  1642. i = xn; xn = yn; yn = i;
  1643. }
  1644. i = 0;
  1645. while (i < xn) {
  1646. num += (BDIGIT_DBL)xds[i] + yds[i];
  1647. zds[i++] = BIGLO(num);
  1648. num = BIGDN(num);
  1649. }
  1650. while (num && i < yn) {
  1651. num += yds[i];
  1652. zds[i++] = BIGLO(num);
  1653. num = BIGDN(num);
  1654. }
  1655. while (i < yn) {
  1656. zds[i] = yds[i];
  1657. i++;
  1658. }
  1659. if (num) zds[i++] = (BDIGIT)num;
  1660. assert(i <= zn);
  1661. while (i < zn) {
  1662. zds[i++] = 0;
  1663. }
  1664. }
  1665. static VALUE
  1666. bigadd(VALUE x, VALUE y, int sign)
  1667. {
  1668. VALUE z;
  1669. long len;
  1670. sign = (sign == RBIGNUM_SIGN(y));
  1671. if (RBIGNUM_SIGN(x) != sign) {
  1672. if (sign) return bigsub(y, x);
  1673. return bigsub(x, y);
  1674. }
  1675. if (RBIGNUM_LEN(x) > RBIGNUM_LEN(y)) {
  1676. len = RBIGNUM_LEN(x) + 1;
  1677. }
  1678. else {
  1679. len = RBIGNUM_LEN(y) + 1;
  1680. }
  1681. z = bignew(len, sign);
  1682. bigadd_core(BDIGITS(x), RBIGNUM_LEN(x),
  1683. BDIGITS(y), RBIGNUM_LEN(y),
  1684. BDIGITS(z), RBIGNUM_LEN(z));
  1685. return z;
  1686. }
  1687. /*
  1688. * call-seq:
  1689. * big + other -> Numeric
  1690. *
  1691. * Adds big and other, returning the result.
  1692. */
  1693. static VALUE
  1694. rb_big_plus_imp(VALUE x, SEL sel, VALUE y)
  1695. {
  1696. long n;
  1697. switch (TYPE(y)) {
  1698. case T_FIXNUM:
  1699. n = FIX2LONG(y);
  1700. if ((n > 0) != RBIGNUM_SIGN(x)) {
  1701. if (n < 0) {
  1702. n = -n;
  1703. }
  1704. return bigsub_int(x, n);
  1705. }
  1706. if (n < 0) {
  1707. n = -n;
  1708. }
  1709. return bigadd_int(x, n);
  1710. case T_BIGNUM:
  1711. return bignorm(bigadd(x, y, 1));
  1712. case T_FLOAT:
  1713. return DBL2NUM(rb_big2dbl(x) + RFLOAT_VALUE(y));
  1714. default:
  1715. return rb_num_coerce_bin(x, y, '+');
  1716. }
  1717. }
  1718. VALUE
  1719. rb_big_plus(VALUE x, VALUE y)
  1720. {
  1721. return rb_big_plus_imp(x, 0, y);
  1722. }
  1723. /*
  1724. * call-seq:
  1725. * big - other -> Numeric
  1726. *
  1727. * Subtracts other from big, returning the result.
  1728. */
  1729. VALUE
  1730. rb_big_minus(VALUE x, VALUE y)
  1731. {
  1732. long n;
  1733. switch (TYPE(y)) {
  1734. case T_FIXNUM:
  1735. n = FIX2LONG(y);
  1736. if ((n > 0) != RBIGNUM_SIGN(x)) {
  1737. if (n < 0) {
  1738. n = -n;
  1739. }
  1740. return bigadd_int(x, n);
  1741. }
  1742. if (n < 0) {
  1743. n = -n;
  1744. }
  1745. return bigsub_int(x, n);
  1746. case T_BIGNUM:
  1747. return bignorm(bigadd(x, y, 0));
  1748. case T_FLOAT:
  1749. return DBL2NUM(rb_big2dbl(x) - RFLOAT_VALUE(y));
  1750. default:
  1751. return rb_num_coerce_bin(x, y, '-');
  1752. }
  1753. }
  1754. static VALUE
  1755. rb_big_minus_imp(VALUE x, SEL sel, VALUE y)
  1756. {
  1757. return rb_big_minus(x, y);
  1758. }
  1759. static long
  1760. big_real_len(VALUE x)
  1761. {
  1762. long i = RBIGNUM_LEN(x);
  1763. BDIGIT *xds = BDIGITS(x);
  1764. while (--i && !xds[i]);
  1765. return i + 1;
  1766. }
  1767. static VALUE
  1768. bigmul1_single(VALUE x, VALUE y)
  1769. {
  1770. BDIGIT_DBL n;
  1771. VALUE z = bignew(2, RBIGNUM_SIGN(x)==RBIGNUM_SIGN(y));
  1772. BDIGIT *xds, *yds, *zds;
  1773. xds = BDIGITS(x);
  1774. yds = BDIGITS(y);
  1775. zds = BDIGITS(z);
  1776. n = (BDIGIT_DBL)xds[0] * yds[0];
  1777. zds[0] = BIGLO(n);
  1778. zds[1] = (BDIGIT)BIGDN(n);
  1779. return z;
  1780. }
  1781. static VALUE
  1782. bigmul1_normal(VALUE x, VALUE y)
  1783. {
  1784. long xl = RBIGNUM_LEN(x), yl = RBIGNUM_LEN(y), i, j = xl + yl + 1;
  1785. BDIGIT_DBL n = 0;
  1786. VALUE z = bignew(j, RBIGNUM_SIGN(x)==RBIGNUM_SIGN(y));
  1787. BDIGIT *xds, *yds, *zds;
  1788. xds = BDIGITS(x);
  1789. yds = BDIGITS(y);
  1790. zds = BDIGITS(z);
  1791. while (j--) zds[j] = 0;
  1792. for (i = 0; i < xl; i++) {
  1793. BDIGIT_DBL dd;
  1794. dd = xds[i];
  1795. if (dd == 0) continue;
  1796. n = 0;
  1797. for (j = 0; j < yl; j++) {
  1798. BDIGIT_DBL ee = n + (BDIGIT_DBL)dd * yds[j];
  1799. n = zds[i + j] + ee;
  1800. if (ee) zds[i + j] = BIGLO(n);
  1801. n = BIGDN(n);
  1802. }
  1803. if (n) {
  1804. zds[i + j] = (BDIGIT)n;
  1805. }
  1806. }
  1807. //rb_thread_check_ints();
  1808. return z;
  1809. }
  1810. static VALUE bigmul0(VALUE x, VALUE y);
  1811. /* balancing multiplication by slicing larger argument */
  1812. static VALUE
  1813. bigmul1_balance(VALUE x, VALUE y)
  1814. {
  1815. VALUE z, t1, t2;
  1816. long i, xn, yn, r, n;
  1817. BDIGIT *yds, *zds, *t1ds;
  1818. xn = RBIGNUM_LEN(x);
  1819. yn = RBIGNUM_LEN(y);
  1820. assert(2 * xn <= yn);
  1821. z = bignew(xn + yn, RBIGNUM_SIGN(x)==RBIGNUM_SIGN(y));
  1822. t1 = bignew(xn, 1);
  1823. yds = BDIGITS(y);
  1824. zds = BDIGITS(z);
  1825. t1ds = BDIGITS(t1);
  1826. for (i = 0; i < xn + yn; i++) zds[i] = 0;
  1827. n = 0;
  1828. while (yn > 0) {
  1829. r = xn > yn ? yn : xn;
  1830. MEMCPY(t1ds, yds + n, BDIGIT, r);
  1831. RBIGNUM_SET_LEN(t1, r);
  1832. t2 = bigmul0(x, t1);
  1833. bigadd_core(zds + n, RBIGNUM_LEN(z) - n,
  1834. BDIGITS(t2), big_real_len(t2),
  1835. zds + n, RBIGNUM_LEN(z) - n);
  1836. yn -= r;
  1837. n += r;
  1838. }
  1839. return z;
  1840. }
  1841. /* split a bignum into high and low bignums */
  1842. static void
  1843. big_split(VALUE v, long n, volatile VALUE *ph, volatile VALUE *pl)
  1844. {
  1845. long hn = 0, ln = RBIGNUM_LEN(v);
  1846. VALUE h, l;
  1847. BDIGIT *vds = BDIGITS(v);
  1848. if (ln > n) {
  1849. hn = ln - n;
  1850. ln = n;
  1851. }
  1852. while (--hn && !vds[hn + ln]);
  1853. h = bignew(hn += 2, 1);
  1854. MEMCPY(BDIGITS(h), vds + ln, BDIGIT, hn - 1);
  1855. BDIGITS(h)[hn - 1] = 0; /* margin for carry */
  1856. while (--ln && !vds[ln]);
  1857. l = bignew(ln += 2, 1);
  1858. MEMCPY(BDIGITS(l), vds, BDIGIT, ln - 1);
  1859. BDIGITS(l)[ln - 1] = 0; /* margin for carry */
  1860. *pl = l;
  1861. *ph = h;
  1862. }
  1863. /* multiplication by karatsuba method */
  1864. static VALUE
  1865. bigmul1_karatsuba(VALUE x, VALUE y)
  1866. {
  1867. long i, n, xn, yn, t1n, t2n;
  1868. VALUE xh, xl, yh, yl, z, t1, t2, t3;
  1869. BDIGIT *zds;
  1870. xn = RBIGNUM_LEN(x);
  1871. yn = RBIGNUM_LEN(y);
  1872. n = yn / 2;
  1873. big_split(x, n, &xh, &xl);
  1874. if (x == y) {
  1875. yh = xh; yl = xl;
  1876. }
  1877. else big_split(y, n, &yh, &yl);
  1878. /* x = xh * b + xl
  1879. * y = yh * b + yl
  1880. *
  1881. * Karatsuba method:
  1882. * x * y = z2 * b^2 + z1 * b + z0
  1883. * where
  1884. * z2 = xh * yh
  1885. * z0 = xl * yl
  1886. * z1 = (xh + xl) * (yh + yl) - z2 - z0
  1887. *
  1888. * ref: http://en.wikipedia.org/wiki/Karatsuba_algorithm
  1889. */
  1890. /* allocate a result bignum */
  1891. z = bignew(xn + yn, RBIGNUM_SIGN(x)==RBIGNUM_SIGN(y));
  1892. zds = BDIGITS(z);
  1893. /* t1 <- xh * yh */
  1894. t1 = bigmul0(xh, yh);
  1895. t1n = big_real_len(t1);
  1896. /* copy t1 into high bytes of the result (z2) */
  1897. MEMCPY(zds + 2 * n, BDIGITS(t1), BDIGIT, t1n);
  1898. for (i = 2 * n + t1n; i < xn + yn; i++) zds[i] = 0;
  1899. if (!BIGZEROP(xl) && !BIGZEROP(yl)) {
  1900. /* t2 <- xl * yl */
  1901. t2 = bigmul0(xl, yl);
  1902. t2n = big_real_len(t2);
  1903. /* copy t2 into low bytes of the result (z0) */
  1904. MEMCPY(zds, BDIGITS(t2), BDIGIT, t2n);
  1905. for (i = t2n; i < 2 * n; i++) zds[i] = 0;
  1906. }
  1907. else {
  1908. t2 = Qundef;
  1909. t2n = 0;
  1910. /* copy 0 into low bytes of the result (z0) */
  1911. for (i = 0; i < 2 * n; i++) zds[i] = 0;
  1912. }
  1913. /* xh <- xh + xl */
  1914. if (RBIGNUM_LEN(xl) > RBIGNUM_LEN(xh)) {
  1915. t3 = xl; xl = xh; xh = t3;
  1916. }
  1917. /* xh has a margin for carry */
  1918. bigadd_core(BDIGITS(xh), RBIGNUM_LEN(xh),
  1919. BDIGITS(xl), RBIGNUM_LEN(xl),
  1920. BDIGITS(xh), RBIGNUM_LEN(xh));
  1921. /* yh <- yh + yl */
  1922. if (x != y) {
  1923. if (RBIGNUM_LEN(yl) > RBIGNUM_LEN(yh)) {
  1924. t3 = yl; yl = yh; yh = t3;
  1925. }
  1926. /* yh has a margin for carry */
  1927. bigadd_core(BDIGITS(yh), RBIGNUM_LEN(yh),
  1928. BDIGITS(yl), RBIGNUM_LEN(yl),
  1929. BDIGITS(yh), RBIGNUM_LEN(yh));
  1930. }
  1931. else yh = xh;
  1932. /* t3 <- xh * yh */
  1933. t3 = bigmul0(xh, yh);
  1934. i = xn + yn - n;
  1935. /* subtract t1 from t3 */
  1936. bigsub_core(BDIGITS(t3), big_real_len(t3), BDIGITS(t1), t1n, BDIGITS(t3), big_real_len(t3));
  1937. /* subtract t2 from t3; t3 is now the middle term of the product */
  1938. if (t2 != Qundef) bigsub_core(BDIGITS(t3), big_real_len(t3), BDIGITS(t2), t2n, BDIGITS(t3), big_real_len(t3));
  1939. /* add t3 to middle bytes of the result (z1) */
  1940. bigadd_core(zds + n, i, BDIGITS(t3), big_real_len(t3), zds + n, i);
  1941. return z;
  1942. }
  1943. /* efficient squaring (2 times faster than normal multiplication)
  1944. * ref: Handbook of Applied Cryptography, Algorithm 14.16
  1945. * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
  1946. */
  1947. static VALUE
  1948. bigsqr_fast(VALUE x)
  1949. {
  1950. long len = RBIGNUM_LEN(x), i, j;
  1951. VALUE z = bignew(2 * len + 1, 1);
  1952. BDIGIT *xds = BDIGITS(x), *zds = BDIGITS(z);
  1953. BDIGIT_DBL c, v, w;
  1954. for (i = 2 * len + 1; i--; ) zds[i] = 0;
  1955. for (i = 0; i < len; i++) {
  1956. v = (BDIGIT_DBL)xds[i];
  1957. if (!v) continue;
  1958. c = (BDIGIT_DBL)zds[i + i] + v * v;
  1959. zds[i + i] = BIGLO(c);
  1960. c = BIGDN(c);
  1961. v *= 2;
  1962. for (j = i + 1; j < len; j++) {
  1963. w = (BDIGIT_DBL)xds[j];
  1964. c += (BDIGIT_DBL)zds[i + j] + BIGLO(v) * w;
  1965. zds[i + j] = BIGLO(c);
  1966. c = BIGDN(c);
  1967. if (BIGDN(v)) c += w;
  1968. }
  1969. if (c) {
  1970. c += (BDIGIT_DBL)zds[i + len];
  1971. zds[i + len] = BIGLO(c);
  1972. c = BIGDN(c);
  1973. }
  1974. if (c) zds[i + len + 1] += (BDIGIT)c;
  1975. }
  1976. return z;
  1977. }
  1978. #define KARATSUBA_MUL_DIGITS 70
  1979. /* determine whether a bignum is sparse or not by random sampling */
  1980. static inline VALUE
  1981. big_sparse_p(VALUE x)
  1982. {
  1983. long c = 0, n = RBIGNUM_LEN(x);
  1984. unsigned long rb_rand_internal(unsigned long i);
  1985. if ( BDIGITS(x)[rb_rand_internal(n / 2) + n / 4]) c++;
  1986. if (c <= 1 && BDIGITS(x)[rb_rand_internal(n / 2) + n / 4]) c++;
  1987. if (c <= 1 && BDIGITS(x)[rb_rand_internal(n / 2) + n / 4]) c++;
  1988. return (c <= 1) ? Qtrue : Qfalse;
  1989. }
  1990. #if 0
  1991. static void
  1992. dump_bignum(VALUE x)
  1993. {
  1994. long i;
  1995. printf("0x0");
  1996. for (i = RBIGNUM_LEN(x); i--; ) {
  1997. printf("_%08x", BDIGITS(x)[i]);
  1998. }
  1999. puts("");
  2000. }
  2001. #endif
  2002. static VALUE
  2003. bigmul0(VALUE x, VALUE y)
  2004. {
  2005. long xn, yn;
  2006. xn = RBIGNUM_LEN(x);
  2007. yn = RBIGNUM_LEN(y);
  2008. /* make sure that y is longer than x */
  2009. if (xn > yn) {
  2010. VALUE t;
  2011. long tn;
  2012. t = x; x = y; y = t;
  2013. tn = xn; xn = yn; yn = tn;
  2014. }
  2015. assert(xn <= yn);
  2016. /* normal multiplication when x is small */
  2017. if (xn < KARATSUBA_MUL_DIGITS) {
  2018. normal:
  2019. if (x == y) return bigsqr_fast(x);
  2020. if (xn == 1 && yn == 1) return bigmul1_single(x, y);
  2021. return bigmul1_normal(x, y);
  2022. }
  2023. /* normal multiplication when x or y is a sparse bignum */
  2024. if (big_sparse_p(x)) goto normal;
  2025. if (big_sparse_p(y)) return bigmul1_normal(y, x);
  2026. /* balance multiplication by slicing y when x is much smaller than y */
  2027. if (2 * xn <= yn) return bigmul1_balance(x, y);
  2028. /* multiplication by karatsuba method */
  2029. return bigmul1_karatsuba(x, y);
  2030. }
  2031. /*
  2032. * call-seq:
  2033. * big * other -> Numeric
  2034. *
  2035. * Multiplies big and other, returning the result.
  2036. */
  2037. VALUE
  2038. rb_big_mul(VALUE x, VALUE y)
  2039. {
  2040. switch (TYPE(y)) {
  2041. case T_FIXNUM:
  2042. y = rb_int2big(FIX2LONG(y));
  2043. break;
  2044. case T_BIGNUM:
  2045. break;
  2046. case T_FLOAT:
  2047. return DBL2NUM(rb_big2dbl(x) * RFLOAT_VALUE(y));
  2048. default:
  2049. return rb_num_coerce_bin(x, y, '*');
  2050. }
  2051. return bignorm(bigmul0(x, y));
  2052. }
  2053. static VALUE
  2054. rb_big_mul_imp(VALUE x, SEL sel, VALUE y)
  2055. {
  2056. return bignorm(rb_big_mul(x, y));
  2057. }
  2058. struct big_div_struct {
  2059. long nx, ny;
  2060. BDIGIT *yds, *zds;
  2061. VALUE stop;
  2062. };
  2063. static VALUE
  2064. bigdivrem1(void *ptr)
  2065. {
  2066. struct big_div_struct *bds = (struct big_div_struct*)ptr;
  2067. long nx = bds->nx, ny = bds->ny;
  2068. long i, j, nyzero;
  2069. BDIGIT *yds = bds->yds, *zds = bds->zds;
  2070. BDIGIT_DBL t2;
  2071. BDIGIT_DBL_SIGNED num;
  2072. BDIGIT q;
  2073. j = nx==ny?nx+1:nx;
  2074. for (nyzero = 0; !yds[nyzero]; nyzero++);
  2075. do {
  2076. if (bds->stop) return Qnil;
  2077. if (zds[j] == yds[ny-1]) q = (BDIGIT)BIGRAD-1;
  2078. else q = (BDIGIT)((BIGUP(zds[j]) + zds[j-1])/yds[ny-1]);
  2079. if (q) {
  2080. i = nyzero; num = 0; t2 = 0;
  2081. do { /* multiply and subtract */
  2082. BDIGIT_DBL ee;
  2083. t2 += (BDIGIT_DBL)yds[i] * q;
  2084. ee = num - BIGLO(t2);
  2085. num = (BDIGIT_DBL)zds[j - ny + i] + ee;
  2086. if (ee) zds[j - ny + i] = BIGLO(num);
  2087. num = BIGDN(num);
  2088. t2 = BIGDN(t2);
  2089. } while (++i < ny);
  2090. num += zds[j - ny + i] - t2;/* borrow from high digit; don't update */
  2091. while (num) { /* "add back" required */
  2092. i = 0; num = 0; q--;
  2093. do {
  2094. BDIGIT_DBL ee = num + yds[i];
  2095. num = (BDIGIT_DBL)zds[j - ny + i] + ee;
  2096. if (ee) zds[j - ny + i] = BIGLO(num);
  2097. num = BIGDN(num);
  2098. } while (++i < ny);
  2099. num--;
  2100. }
  2101. }
  2102. zds[j] = q;
  2103. } while (--j >= ny);
  2104. return Qnil;
  2105. }
  2106. #if 0
  2107. static void
  2108. rb_big_stop(void *ptr)
  2109. {
  2110. VALUE *stop = (VALUE*)ptr;
  2111. *stop = Qtrue;
  2112. }
  2113. #endif
  2114. static VALUE
  2115. bigdivrem(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp)
  2116. {
  2117. struct big_div_struct bds;
  2118. long nx = RBIGNUM_LEN(x), ny = RBIGNUM_LEN(y);
  2119. long i, j;
  2120. VALUE z, yy, zz;
  2121. BDIGIT *xds, *yds, *zds, *tds;
  2122. BDIGIT_DBL t2;
  2123. BDIGIT dd, q;
  2124. if (BIGZEROP(y)) rb_num_zerodiv();
  2125. xds = BDIGITS(x);
  2126. yds = BDIGITS(y);
  2127. if (nx < ny || (nx == ny && xds[nx - 1] < yds[ny - 1])) {
  2128. if (divp) *divp = rb_int2big(0);
  2129. if (modp) *modp = x;
  2130. return Qnil;
  2131. }
  2132. if (ny == 1) {
  2133. dd = yds[0];
  2134. z = rb_big_clone(x);
  2135. zds = BDIGITS(z);
  2136. t2 = 0; i = nx;
  2137. while (i--) {
  2138. t2 = BIGUP(t2) + zds[i];
  2139. zds[i] = (BDIGIT)(t2 / dd);
  2140. t2 %= dd;
  2141. }
  2142. RBIGNUM_SET_SIGN(z, R

Large files files are truncated, but you can click here to view the full file