PageRenderTime 62ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/bignum.c

https://github.com/vuxuandung/ruby
C | 3891 lines | 3010 code | 451 blank | 430 comment | 710 complexity | 6a93ad03b42e9f90c319cf58bab03ca3 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, AGPL-3.0, 0BSD

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

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

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