PageRenderTime 36ms CodeModel.GetById 42ms RepoModel.GetById 2ms app.codeStats 0ms

/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
  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(-1) = (x0 - x1 + x2) * (y0 - y1 + y2)
  2133. * z(-2) = x(-2) * y(-2) = (x0 - 2 * (x1 - 2 * x2)) * (y0 - 2 * (y1 - 2 * y2))
  2134. * z(inf) = x(inf) * y(inf) = x2 * y2
  2135. *
  2136. * (Step2) interpolating z0, z1, z2, z3, z4, and z5.
  2137. *
  2138. * (Step3) Substituting base value into b of the polynomial z(b),
  2139. */
  2140. /*
  2141. * [Step1] calculating 5 points z(b0), z(b1), z(b2), z(b3), z(b4)
  2142. */
  2143. /* u1 <- x0 + x2 */
  2144. u1 = bigtrunc(bigadd(x0, x2, 1));
  2145. /* x(-1) : u2 <- u1 - x1 = x0 - x1 + x2 */
  2146. u2 = bigtrunc(bigsub(u1, x1));
  2147. /* x(1) : u1 <- u1 + x1 = x0 + x1 + x2 */
  2148. u1 = bigtrunc(bigadd(u1, x1, 1));
  2149. /* x(-2) : u3 <- 2 * (u2 + x2) - x0 = x0 - 2 * (x1 - 2 * x2) */
  2150. u3 = bigadd(u2, x2, 1);
  2151. if (BDIGITS(u3)[RBIGNUM_LEN(u3)-1] & BIGRAD_HALF) {
  2152. rb_big_resize(u3, RBIGNUM_LEN(u3) + 1);
  2153. BDIGITS(u3)[RBIGNUM_LEN(u3)-1] = 0;
  2154. }
  2155. biglsh_bang(BDIGITS(u3), RBIGNUM_LEN(u3), 1);
  2156. u3 = bigtrunc(bigadd(bigtrunc(u3), x0, 0));
  2157. if (x == y) {
  2158. v1 = u1; v2 = u2; v3 = u3;
  2159. }
  2160. else {
  2161. /* v1 <- y0 + y2 */
  2162. v1 = bigtrunc(bigadd(y0, y2, 1));
  2163. /* y(-1) : v2 <- v1 - y1 = y0 - y1 + y2 */
  2164. v2 = bigtrunc(bigsub(v1, y1));
  2165. /* y(1) : v1 <- v1 + y1 = y0 + y1 + y2 */
  2166. v1 = bigtrunc(bigadd(v1, y1, 1));
  2167. /* y(-2) : v3 <- 2 * (v2 + y2) - y0 = y0 - 2 * (y1 - 2 * y2) */
  2168. v3 = bigadd(v2, y2, 1);
  2169. if (BDIGITS(v3)[RBIGNUM_LEN(v3)-1] & BIGRAD_HALF) {
  2170. rb_big_resize(v3, RBIGNUM_LEN(v3) + 1);
  2171. BDIGITS(v3)[RBIGNUM_LEN(v3)-1] = 0;
  2172. }
  2173. biglsh_bang(BDIGITS(v3), RBIGNUM_LEN(v3), 1);
  2174. v3 = bigtrunc(bigadd(bigtrunc(v3), y0, 0));
  2175. }
  2176. /* z(0) : u0 <- x0 * y0 */
  2177. u0 = bigtrunc(bigmul0(x0, y0));
  2178. /* z(1) : u1 <- u1 * v1 */
  2179. u1 = bigtrunc(bigmul0(u1, v1));
  2180. /* z(-1) : u2 <- u2 * v2 */
  2181. u2 = bigtrunc(bigmul0(u2, v2));
  2182. /* z(-2) : u3 <- u3 * v3 */
  2183. u3 = bigtrunc(bigmul0(u3, v3));
  2184. /* z(inf) : u4 <- x2 * y2 */
  2185. u4 = bigtrunc(bigmul0(x2, y2));
  2186. /* for GC */
  2187. v1 = v2 = v3 = Qnil;
  2188. /*
  2189. * [Step2] interpolating z0, z1, z2, z3, z4, and z5.
  2190. */
  2191. /* z0 <- z(0) == u0 */
  2192. z0 = u0;
  2193. /* z4 <- z(inf) == u4 */
  2194. z4 = u4;
  2195. /* z3 <- (z(-2) - z(1)) / 3 == (u3 - u1) / 3 */
  2196. z3 = bigadd(u3, u1, 0);
  2197. bigdivrem(z3, big_three, &z3, NULL); /* TODO: optimize */
  2198. bigtrunc(z3);
  2199. /* z1 <- (z(1) - z(-1)) / 2 == (u1 - u2) / 2 */
  2200. z1 = bigtrunc(bigadd(u1, u2, 0));
  2201. bigrsh_bang(BDIGITS(z1), RBIGNUM_LEN(z1), 1);
  2202. /* z2 <- z(-1) - z(0) == u2 - u0 */
  2203. z2 = bigtrunc(bigadd(u2, u0, 0));
  2204. /* z3 <- (z2 - z3) / 2 + 2 * z(inf) == (z2 - z3) / 2 + 2 * u4 */
  2205. z3 = bigtrunc(bigadd(z2, z3, 0));
  2206. bigrsh_bang(BDIGITS(z3), RBIGNUM_LEN(z3), 1);
  2207. t = big_lshift(u4, 1); /* TODO: combining with next addition */
  2208. z3 = bigtrunc(bigadd(z3, t, 1));
  2209. /* z2 <- z2 + z1 - z(inf) == z2 + z1 - u4 */
  2210. z2 = bigtrunc(bigadd(z2, z1, 1));
  2211. z2 = bigtrunc(bigadd(z2, u4, 0));
  2212. /* z1 <- z1 - z3 */
  2213. z1 = bigtrunc(bigadd(z1, z3, 0));
  2214. /*
  2215. * [Step3] Substituting base value into b of the polynomial z(b),
  2216. */
  2217. zn = 6*n + 1;
  2218. z = bignew(zn, RBIGNUM_SIGN(x)==RBIGNUM_SIGN(y));
  2219. zds = BDIGITS(z);
  2220. MEMCPY(zds, BDIGITS(z0), BDIGIT, RBIGNUM_LEN(z0));
  2221. MEMZERO(zds + RBIGNUM_LEN(z0), BDIGIT, zn - RBIGNUM_LEN(z0));
  2222. bigadd_core(zds + n, zn - n, BDIGITS(z1), big_real_len(z1), zds + n, zn - n);
  2223. bigadd_core(zds + 2*n, zn - 2*n, BDIGITS(z2), big_real_len(z2), zds + 2*n, zn - 2*n);
  2224. bigadd_core(zds + 3*n, zn - 3*n, BDIGITS(z3), big_real_len(z3), zds + 3*n, zn - 3*n);
  2225. bigadd_core(zds + 4*n, zn - 4*n, BDIGITS(z4), big_real_len(z4), zds + 4*n, zn - 4*n);
  2226. z = bignorm(z);
  2227. return bignorm(z);
  2228. }
  2229. /* efficient squaring (2 times faster than normal multiplication)
  2230. * ref: Handbook of Applied Cryptography, Algorithm 14.16
  2231. * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
  2232. */
  2233. static VALUE
  2234. bigsqr_fast(VALUE x)
  2235. {
  2236. long len = RBIGNUM_LEN(x), i, j;
  2237. VALUE z = bignew(2 * len + 1, 1);
  2238. BDIGIT *xds = BDIGITS(x), *zds = BDIGITS(z);
  2239. BDIGIT_DBL c, v, w;
  2240. for (i = 2 * len + 1; i--; ) zds[i] = 0;
  2241. for (i = 0; i < len; i++) {
  2242. v = (BDIGIT_DBL)xds[i];
  2243. if (!v) continue;
  2244. c = (BDIGIT_DBL)zds[i + i] + v * v;
  2245. zds[i + i] = BIGLO(c);
  2246. c = BIGDN(c);
  2247. v *= 2;
  2248. for (j = i + 1; j < len; j++) {
  2249. w = (BDIGIT_DBL)xds[j];
  2250. c += (BDIGIT_DBL)zds[i + j] + BIGLO(v) * w;
  2251. zds[i + j] = BIGLO(c);
  2252. c = BIGDN(c);
  2253. if (BIGDN(v)) c += w;
  2254. }
  2255. if (c) {
  2256. c += (BDIGIT_DBL)zds[i + len];
  2257. zds[i + len] = BIGLO(c);
  2258. c = BIGDN(c);
  2259. }
  2260. if (c) zds[i + len + 1] += (BDIGIT)c;
  2261. }
  2262. return z;
  2263. }
  2264. #define KARATSUBA_MUL_DIGITS 70
  2265. #define TOOM3_MUL_DIGITS 150
  2266. /* determine whether a bignum is sparse or not by random sampling */
  2267. static inline VALUE
  2268. big_sparse_p(VALUE x)
  2269. {
  2270. long c = 0, n = RBIGNUM_LEN(x);
  2271. if ( BDIGITS(x)[rb_genrand_ulong_limited(n / 2) + n / 4]) c++;
  2272. if (c <= 1 && BDIGITS(x)[rb_genrand_ulong_limited(n / 2) + n / 4]) c++;
  2273. if (c <= 1 && BDIGITS(x)[rb_genrand_ulong_limited(n / 2) + n / 4]) c++;
  2274. return (c <= 1) ? Qtrue : Qfalse;
  2275. }
  2276. static VALUE
  2277. bigmul0(VALUE x, VALUE y)
  2278. {
  2279. long xn, yn;
  2280. xn = RBIGNUM_LEN(x);
  2281. yn = RBIGNUM_LEN(y);
  2282. /* make sure that y is longer than x */
  2283. if (xn > yn) {
  2284. VALUE t;
  2285. long tn;
  2286. t = x; x = y; y = t;
  2287. tn = xn; xn = yn; yn = tn;
  2288. }
  2289. assert(xn <= yn);
  2290. /* normal multiplication when x is small */
  2291. if (xn < KARATSUBA_MUL_DIGITS) {
  2292. normal:
  2293. if (x == y) return bigsqr_fast(x);
  2294. if (xn == 1 && yn == 1) return bigmul1_single(x, y);
  2295. return bigmul1_normal(x, y);
  2296. }
  2297. /* normal multiplication when x or y is a sparse bignum */
  2298. if (big_sparse_p(x)) goto normal;
  2299. if (big_sparse_p(y)) return bigmul1_normal(y, x);
  2300. /* balance multiplication by slicing y when x is much smaller than y */
  2301. if (2 * xn <= yn) return bigmul1_balance(x, y);
  2302. if (xn < TOOM3_MUL_DIGITS) {
  2303. /* multiplication by karatsuba method */
  2304. return bigmul1_karatsuba(x, y);
  2305. }
  2306. else if (3*xn <= 2*(yn + 2))
  2307. return bigmul1_balance(x, y);
  2308. return bigmul1_toom3(x, y);
  2309. }
  2310. /*
  2311. * call-seq:
  2312. * big * other -> Numeric
  2313. *
  2314. * Multiplies big and other, returning the result.
  2315. */
  2316. VALUE
  2317. rb_big_mul(VALUE x, VALUE y)
  2318. {
  2319. switch (TYPE(y)) {
  2320. case T_FIXNUM:
  2321. y = rb_int2big(FIX2LONG(y));
  2322. break;
  2323. case T_BIGNUM:
  2324. break;
  2325. case T_FLOAT:
  2326. return DBL2NUM(rb_big2dbl(x) * RFLOAT_VALUE(y));
  2327. default:
  2328. return rb_num_coerce_bin(x, y, '*');
  2329. }
  2330. return bignorm(bigmul0(x, y));
  2331. }
  2332. struct big_div_struct {
  2333. long nx, ny, j, nyzero;
  2334. BDIGIT *yds, *zds;
  2335. volatile VALUE stop;
  2336. };
  2337. static void *
  2338. bigdivrem1(void *ptr)
  2339. {
  2340. struct big_div_struct *bds = (struct big_div_struct*)ptr;
  2341. long ny = bds->ny;
  2342. long i, j;
  2343. BDIGIT *yds = bds->yds, *zds = bds->zds;
  2344. BDIGIT_DBL t2;
  2345. BDIGIT_DBL_SIGNED num;
  2346. BDIGIT q;
  2347. j = bds->j;
  2348. do {
  2349. if (bds->stop) {
  2350. bds->j = j;
  2351. return 0;
  2352. }
  2353. if (zds[j] == yds[ny-1]) q = (BDIGIT)BIGRAD-1;
  2354. else q = (BDIGIT)((BIGUP(zds[j]) + zds[j-1])/yds[ny-1]);
  2355. if (q) {
  2356. i = bds->nyzero; num = 0; t2 = 0;
  2357. do { /* multiply and subtract */
  2358. BDIGIT_DBL ee;
  2359. t2 += (BDIGIT_DBL)yds[i] * q;
  2360. ee = num - BIGLO(t2);
  2361. num = (BDIGIT_DBL)zds[j - ny + i] + ee;
  2362. if (ee) zds[j - ny + i] = BIGLO(num);
  2363. num = BIGDN(num);
  2364. t2 = BIGDN(t2);
  2365. } while (++i < ny);
  2366. num += zds[j - ny + i] - t2;/* borrow from high digit; don't update */
  2367. while (num) { /* "add back" required */
  2368. i = 0; num = 0; q--;
  2369. do {
  2370. BDIGIT_DBL ee = num + yds[i];
  2371. num = (BDIGIT_DBL)zds[j - ny + i] + ee;
  2372. if (ee) zds[j - ny + i] = BIGLO(num);
  2373. num = BIGDN(num);
  2374. } while (++i < ny);
  2375. num--;
  2376. }
  2377. }
  2378. zds[j] = q;
  2379. } while (--j >= ny);
  2380. return 0;
  2381. }
  2382. static void
  2383. rb_big_stop(void *ptr)
  2384. {
  2385. struct big_div_struct *bds = ptr;
  2386. bds->stop = Qtrue;
  2387. }
  2388. static VALUE
  2389. bigdivrem(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp)
  2390. {
  2391. struct big_div_struct bds;
  2392. long nx = RBIGNUM_LEN(x), ny = RBIGNUM_LEN(y);
  2393. long i, j;
  2394. VALUE z, yy, zz;
  2395. BDIGIT *xds, *yds, *zds, *tds;
  2396. BDIGIT_DBL t2;
  2397. BDIGIT dd, q;
  2398. if (BIGZEROP(y)) rb_num_zerodiv();
  2399. xds = BDIGITS(x);
  2400. yds = BDIGITS(y);
  2401. if (nx < ny || (nx == ny && xds[nx - 1] < yds[ny - 1])) {
  2402. if (divp) *divp = rb_int2big(0);
  2403. if (modp) *modp = x;
  2404. return Qnil;
  2405. }
  2406. if (ny == 1) {
  2407. dd = yds[0];
  2408. z = rb_big_clone(x);
  2409. zds = BDIGITS(z);
  2410. t2 = 0; i = nx;
  2411. while (i--) {
  2412. t2 = BIGUP(t2) + zds[i];
  2413. zds[i] = (BDIGIT)(t2 / dd);
  2414. t2 %= dd;
  2415. }
  2416. RBIGNUM_SET_SIGN(z, RBIGNUM_SIGN(x)==RBIGNUM_SIGN(y));
  2417. if (modp) {
  2418. *modp = rb_uint2big((VALUE)t2);
  2419. RBIGNUM_SET_SIGN(*modp, RBIGNUM_SIGN(x));
  2420. }
  2421. if (divp) *divp = z;
  2422. return Qnil;
  2423. }
  2424. z = bignew(nx==ny?nx+2:nx+1, RBIGNUM_SIGN(x)==RBIGNUM_SIGN(y));
  2425. zds = BDIGITS(z);
  2426. if (nx==ny) zds[nx+1] = 0;
  2427. while (!yds[ny-1]) ny--;
  2428. dd = 0;
  2429. q = yds[ny-1];
  2430. while ((q & (BDIGIT)(1UL<<(BITSPERDIG-1))) == 0) {
  2431. q <<= 1UL;
  2432. dd++;
  2433. }
  2434. if (dd) {
  2435. yy = rb_big_clone(y);
  2436. tds = BDIGITS(yy);
  2437. j = 0;
  2438. t2 = 0;
  2439. while (j<ny) {
  2440. t2 += (BDIGIT_DBL)yds[j]<<dd;
  2441. tds[j++] = BIGLO(t2);
  2442. t2 = BIGDN(t2);
  2443. }
  2444. yds = tds;
  2445. RB_GC_GUARD(y) = yy;
  2446. j = 0;
  2447. t2 = 0;
  2448. while (j<nx) {
  2449. t2 += (BDIGIT_DBL)xds[j]<<dd;
  2450. zds[j++] = BIGLO(t2);
  2451. t2 = BIGDN(t2);
  2452. }
  2453. zds[j] = (BDIGIT)t2;
  2454. }
  2455. else {
  2456. zds[nx] = 0;
  2457. j = nx;
  2458. while (j--) zds[j] = xds[j];
  2459. }
  2460. bds.nx = nx;
  2461. bds.ny = ny;
  2462. bds.zds = zds;
  2463. bds.yds = yds;
  2464. bds.stop = Qfalse;
  2465. bds.j = nx==ny?nx+1:nx;
  2466. for (bds.nyzero = 0; !yds[bds.nyzero]; bds.nyzero++);
  2467. if (nx > 10000 || ny > 10000) {
  2468. retry:
  2469. bds.stop = Qfalse;
  2470. rb_thread_call_without_gvl(bigdivrem1, &bds, rb_big_stop, &bds);
  2471. if (bds.stop == Qtrue) {
  2472. /* execute trap handler, but exception was not raised. */
  2473. goto retry;
  2474. }
  2475. }
  2476. else {
  2477. bigdivrem1(&bds);
  2478. }
  2479. if (divp) { /* move quotient down in z */
  2480. *divp = zz = rb_big_clone(z);
  2481. zds = BDIGITS(zz);
  2482. j = (nx==ny ? nx+2 : nx+1) - ny;
  2483. for (i = 0;i < j;i++) zds[i] = zds[i+ny];
  2484. if (!zds[i-1]) i--;
  2485. RBIGNUM_SET_LEN(zz, i);
  2486. }
  2487. if (modp) { /* normalize remainder */
  2488. *modp = zz = rb_big_clone(z);
  2489. zds = BDIGITS(zz);
  2490. while (ny > 1 && !zds[ny-1]) --ny;
  2491. if (dd) {
  2492. t2 = 0; i = ny;
  2493. while (i--) {
  2494. t2 = (t2 | zds[i]) >> dd;
  2495. q = zds[i];
  2496. zds[i] = BIGLO(t2);
  2497. t2 = BIGUP(q);
  2498. }
  2499. }
  2500. if (!zds[ny-1]) ny--;
  2501. RBIGNUM_SET_LEN(zz, ny);
  2502. RBIGNUM_SET_SIGN(zz, RBIGNUM_SIGN(x));
  2503. }
  2504. return z;
  2505. }
  2506. static void
  2507. bigdivmod(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp)
  2508. {
  2509. VALUE mod;
  2510. bigdivrem(x, y, divp, &mod);
  2511. if (RBIGNUM_SIGN(x) != RBIGNUM_SIGN(y) && !BIGZEROP(mod)) {
  2512. if (divp) *divp = bigadd(*divp, rb_int2big(1), 0);
  2513. if (modp) *modp = bigadd(mod, y, 1);
  2514. }
  2515. else if (modp) {
  2516. *modp = mod;
  2517. }
  2518. }
  2519. static VALUE
  2520. rb_big_divide(VALUE x, VALUE y, ID op)
  2521. {
  2522. VALUE z;
  2523. switch (TYPE(y)) {
  2524. case T_FIXNUM:
  2525. y = rb_int2big(FIX2LONG(y));
  2526. break;
  2527. case T_BIGNUM:
  2528. break;
  2529. case T_FLOAT:
  2530. {
  2531. if (op == '/') {
  2532. return DBL2NUM(rb_big2dbl(x) / RFLOAT_VALUE(y));
  2533. }
  2534. else {
  2535. double dy = RFLOAT_VALUE(y);
  2536. if (dy == 0.0) rb_num_zerodiv();
  2537. return rb_dbl2big(rb_big2dbl(x) / dy);
  2538. }
  2539. }
  2540. default:
  2541. return rb_num_coerce_bin(x, y, op);
  2542. }
  2543. bigdivmod(x, y, &z, 0);
  2544. return bignorm(z);
  2545. }
  2546. /*
  2547. * call-seq:
  2548. * big / other -> Numeric
  2549. *
  2550. * Performs division: the class of the resulting object depends on
  2551. * the class of <code>numeric</code> and on the magnitude of the
  2552. * result.
  2553. */
  2554. VALUE
  2555. rb_big_div(VALUE x, VALUE y)
  2556. {
  2557. return rb_big_divide(x, y, '/');
  2558. }
  2559. /*
  2560. * call-seq:
  2561. * big.div(other) -> integer
  2562. *
  2563. * Performs integer division: returns integer value.
  2564. */
  2565. VALUE
  2566. rb_big_idiv(VALUE x, VALUE y)
  2567. {
  2568. return rb_big_divide(x, y, rb_intern("div"));
  2569. }
  2570. /*
  2571. * call-seq:
  2572. * big % other -> Numeric
  2573. * big.modulo(other) -> Numeric
  2574. *
  2575. * Returns big modulo other. See Numeric.divmod for more
  2576. * information.
  2577. */
  2578. VALUE
  2579. rb_big_modulo(VALUE x, VALUE y)
  2580. {
  2581. VALUE z;
  2582. switch (TYPE(y)) {
  2583. case T_FIXNUM:
  2584. y = rb_int2big(FIX2LONG(y));
  2585. break;
  2586. case T_BIGNUM:
  2587. break;
  2588. default:
  2589. return rb_num_coerce_bin(x, y, '%');
  2590. }
  2591. bigdivmod(x, y, 0, &z);
  2592. return bignorm(z);
  2593. }
  2594. /*
  2595. * call-seq:
  2596. * big.remainder(numeric) -> number
  2597. *
  2598. * Returns the remainder after dividing <i>big</i> by <i>numeric</i>.
  2599. *
  2600. * -1234567890987654321.remainder(13731) #=> -6966
  2601. * -1234567890987654321.remainder(13731.24) #=> -9906.22531493148
  2602. */
  2603. static VALUE
  2604. rb_big_remainder(VALUE x, VALUE y)
  2605. {
  2606. VALUE z;
  2607. switch (TYPE(y)) {
  2608. case T_FIXNUM:
  2609. y = rb_int2big(FIX2LONG(y));
  2610. break;
  2611. case T_BIGNUM:
  2612. break;
  2613. default:
  2614. return rb_num_coerce_bin(x, y, rb_intern("remainder"));
  2615. }
  2616. bigdivrem(x, y, 0, &z);
  2617. return bignorm(z);
  2618. }
  2619. /*
  2620. * call-seq:
  2621. * big.divmod(numeric) -> array
  2622. *
  2623. * See <code>Numeric#divmod</code>.
  2624. *
  2625. */
  2626. VALUE
  2627. rb_big_divmod(VALUE x, VALUE y)
  2628. {
  2629. VALUE div, mod;
  2630. switch (TYPE(y)) {
  2631. case T_FIXNUM:
  2632. y = rb_int2big(FIX2LONG(y));
  2633. break;
  2634. case T_BIGNUM:
  2635. break;
  2636. default:
  2637. return rb_num_coerce_bin(x, y, rb_intern("divmod"));
  2638. }
  2639. bigdivmod(x, y, &div, &mod);
  2640. return rb_assoc_new(bignorm(div), bignorm(mod));
  2641. }
  2642. static int
  2643. bdigbitsize(BDIGIT x)
  2644. {
  2645. int size = 1;
  2646. int nb = BITSPERDIG / 2;
  2647. BDIGIT bits = (~0 << nb);
  2648. if (!x) return 0;
  2649. while (x > 1) {
  2650. if (x & bits) {
  2651. size += nb;
  2652. x >>= nb;
  2653. }
  2654. x &= ~bits;
  2655. nb /= 2;
  2656. bits >>= nb;
  2657. }
  2658. return size;
  2659. }
  2660. static VALUE big_lshift(VALUE, unsigned long);
  2661. static VALUE big_rshift(VALUE, unsigned long);
  2662. static VALUE
  2663. big_shift(VALUE x, long n)
  2664. {
  2665. if (n < 0)
  2666. return big_lshift(x, (unsigned long)-n);
  2667. else if (n > 0)
  2668. return big_rshift(x, (unsigned long)n);
  2669. return x;
  2670. }
  2671. static VALUE
  2672. big_fdiv(VALUE x, VALUE y)
  2673. {
  2674. #define DBL_BIGDIG ((DBL_MANT_DIG + BITSPERDIG) / BITSPERDIG)
  2675. VALUE z;
  2676. long l, ex, ey;
  2677. int i;
  2678. bigtrunc(x);
  2679. l = RBIGNUM_LEN(x) - 1;
  2680. ex = l * BITSPERDIG;
  2681. ex += bdigbitsize(BDIGITS(x)[l]);
  2682. ex -= 2 * DBL_BIGDIG * BITSPERDIG;
  2683. if (ex) x = big_shift(x, ex);
  2684. switch (TYPE(y)) {
  2685. case T_FIXNUM:
  2686. y = rb_int2big(FIX2LONG(y));
  2687. case T_BIGNUM:
  2688. bigtrunc(y);
  2689. l = RBIGNUM_LEN(y) - 1;
  2690. ey = l * BITSPERDIG;
  2691. ey += bdigbitsize(BDIGITS(y)[l]);
  2692. ey -= DBL_BIGDIG * BITSPERDIG;
  2693. if (ey) y = big_shift(y, ey);
  2694. break;
  2695. case T_FLOAT:
  2696. y = dbl2big(ldexp(frexp(RFLOAT_VALUE(y), &i), DBL_MANT_DIG));
  2697. ey = i - DBL_MANT_DIG;
  2698. break;
  2699. default:
  2700. rb_bug("big_fdiv");
  2701. }
  2702. bigdivrem(x, y, &z, 0);
  2703. l = ex - ey;
  2704. #if SIZEOF_LONG > SIZEOF_INT
  2705. {
  2706. /* Visual C++ can't be here */
  2707. if (l > INT_MAX) return DBL2NUM(INFINITY);
  2708. if (l < INT_MIN) return DBL2NUM(0.0);
  2709. }
  2710. #endif
  2711. return DBL2NUM(ldexp(big2dbl(z), (int)l));
  2712. }
  2713. /*
  2714. * call-seq:
  2715. * big.fdiv(numeric) -> float
  2716. *
  2717. * Returns the floating point result of dividing <i>big</i> by
  2718. * <i>numeric</i>.
  2719. *
  2720. * -1234567890987654321.fdiv(13731) #=> -89910996357705.5
  2721. * -1234567890987654321.fdiv(13731.24) #=> -89909424858035.7
  2722. *
  2723. */
  2724. VALUE
  2725. rb_big_fdiv(VALUE x, VALUE y)
  2726. {
  2727. double dx, dy;
  2728. dx = big2dbl(x);
  2729. switch (TYPE(y)) {
  2730. case T_FIXNUM:
  2731. dy = (double)FIX2LONG(y);
  2732. if (isinf(dx))
  2733. return big_fdiv(x, y);
  2734. break;
  2735. case T_BIGNUM:
  2736. dy = rb_big2dbl(y);
  2737. if (isinf(dx) || isinf(dy))
  2738. return big_fdiv(x, y);
  2739. break;
  2740. case T_FLOAT:
  2741. dy = RFLOAT_VALUE(y);
  2742. if (isnan(dy))
  2743. return y;
  2744. if (isinf(dx))
  2745. return big_fdiv(x, y);
  2746. break;
  2747. default:
  2748. return rb_num_coerce_bin(x, y, rb_intern("fdiv"));
  2749. }
  2750. return DBL2NUM(dx / dy);
  2751. }
  2752. static VALUE
  2753. bigsqr(VALUE x)
  2754. {
  2755. return bigtrunc(bigmul0(x, x));
  2756. }
  2757. /*
  2758. * call-seq:
  2759. * big ** exponent -> numeric
  2760. *
  2761. * Raises _big_ to the _exponent_ power (which may be an integer, float,
  2762. * or anything that will coerce to a number). The result may be
  2763. * a Fixnum, Bignum, or Float
  2764. *
  2765. * 123456789 ** 2 #=> 15241578750190521
  2766. * 123456789 ** 1.2 #=> 5126464716.09932
  2767. * 123456789 ** -2 #=> 6.5610001194102e-17
  2768. */
  2769. VALUE
  2770. rb_big_pow(VALUE x, VALUE y)
  2771. {
  2772. double d;
  2773. SIGNED_VALUE yy;
  2774. if (y == INT2FIX(0)) return INT2FIX(1);
  2775. switch (TYPE(y)) {
  2776. case T_FLOAT:
  2777. d = RFLOAT_VALUE(y);
  2778. if ((!RBIGNUM_SIGN(x) && !BIGZEROP(x)) && d != round(d))
  2779. return rb_funcall(rb_complex_raw1(x), rb_intern("**"), 1, y);
  2780. break;
  2781. case T_BIGNUM:
  2782. rb_warn("in a**b, b may be too big");
  2783. d = rb_big2dbl(y);
  2784. break;
  2785. case T_FIXNUM:
  2786. yy = FIX2LONG(y);
  2787. if (yy < 0)
  2788. return rb_funcall(rb_rational_raw1(x), rb_intern("**"), 1, y);
  2789. else {
  2790. VALUE z = 0;
  2791. SIGNED_VALUE mask;
  2792. const long xlen = RBIGNUM_LEN(x) - 1;
  2793. const long xbits = ffs(RBIGNUM_DIGITS(x)[xlen]) + SIZEOF_BDIGITS*BITSPERDIG*xlen;
  2794. const long BIGLEN_LIMIT = BITSPERDIG*1024*1024;
  2795. if ((xbits > BIGLEN_LIMIT) || (xbits * yy > BIGLEN_LIMIT)) {
  2796. rb_warn("in a**b, b may be too big");
  2797. d = (double)yy;
  2798. break;
  2799. }
  2800. for (mask = FIXNUM_MAX + 1; mask; mask >>= 1) {
  2801. if (z) z = bigsqr(z);
  2802. if (yy & mask) {
  2803. z = z ? bigtrunc(bigmul0(z, x)) : x;
  2804. }
  2805. }
  2806. return bignorm(z);
  2807. }
  2808. /* NOTREACHED */
  2809. break;
  2810. default:
  2811. return rb_num_coerce_bin(x, y, rb_intern("**"));
  2812. }
  2813. return DBL2NUM(pow(rb_big2dbl(x), d));
  2814. }
  2815. static VALUE
  2816. bigand_int(VALUE x, long y)
  2817. {
  2818. VALUE z;
  2819. BDIGIT *xds, *zds;
  2820. long xn, zn;
  2821. long i;
  2822. char sign;
  2823. if (y == 0) return INT2FIX(0);
  2824. sign = (y > 0);
  2825. xds = BDIGITS(x);
  2826. zn = xn = RBIGNUM_LEN(x);
  2827. #if SIZEOF_BDIGITS == SIZEOF_LONG
  2828. if (sign) {
  2829. y &= xds[0];
  2830. return LONG2NUM(y);
  2831. }
  2832. #endif
  2833. z = bignew(zn, RBIGNUM_SIGN(x) || sign);
  2834. zds = BDIGITS(z);
  2835. #if SIZEOF_BDIGITS == SIZEOF_LONG
  2836. i = 1;
  2837. zds[0] = xds[0] & y;
  2838. #else
  2839. {
  2840. BDIGIT_DBL num = y;
  2841. for (i=0; i<(int)(sizeof(y)/sizeof(BDIGIT)); i++) {
  2842. zds[i] = xds[i] & BIGLO(num);
  2843. num = BIGDN(num);
  2844. }
  2845. }
  2846. #endif
  2847. while (i < xn) {
  2848. zds[i] = sign?0:xds[i];
  2849. i++;
  2850. }
  2851. if (!RBIGNUM_SIGN(z)) get2comp(z);
  2852. return bignorm(z);
  2853. }
  2854. /*
  2855. * call-seq:
  2856. * big & numeric -> integer
  2857. *
  2858. * Performs bitwise +and+ between _big_ and _numeric_.
  2859. */
  2860. VALUE
  2861. rb_big_and(VALUE xx, VALUE yy)
  2862. {
  2863. volatile VALUE x, y, z;
  2864. BDIGIT *ds1, *ds2, *zds;
  2865. long i, l1, l2;
  2866. char sign;
  2867. if (!FIXNUM_P(yy) && !RB_TYPE_P(yy, T_BIGNUM)) {
  2868. return rb_num_coerce_bit(xx, yy, '&');
  2869. }
  2870. x = xx;
  2871. y = yy;
  2872. if (!RBIGNUM_SIGN(x)) {
  2873. x = rb_big_clone(x);
  2874. get2comp(x);
  2875. }
  2876. if (FIXNUM_P(y)) {
  2877. return bigand_int(x, FIX2LONG(y));
  2878. }
  2879. if (!RBIGNUM_SIGN(y)) {
  2880. y = rb_big_clone(y);
  2881. get2comp(y);
  2882. }
  2883. if (RBIGNUM_LEN(x) > RBIGNUM_LEN(y)) {
  2884. l1 = RBIGNUM_LEN(y);
  2885. l2 = RBIGNUM_LEN(x);
  2886. ds1 = BDIGITS(y);
  2887. ds2 = BDIGITS(x);
  2888. sign = RBIGNUM_SIGN(y);
  2889. }
  2890. else {
  2891. l1 = RBIGNUM_LEN(x);
  2892. l2 = RBIGNUM_LEN(y);
  2893. ds1 = BDIGITS(x);
  2894. ds2 = BDIGITS(y);
  2895. sign = RBIGNUM_SIGN(x);
  2896. }
  2897. z = bignew(l2, RBIGNUM_SIGN(x) || RBIGNUM_SIGN(y));
  2898. zds = BDIGITS(z);
  2899. for (i=0; i<l1; i++) {
  2900. zds[i] = ds1[i] & ds2[i];
  2901. }
  2902. for (; i<l2; i++) {
  2903. zds[i] = sign?0:ds2[i];
  2904. }
  2905. if (!RBIGNUM_SIGN(z)) get2comp(z);
  2906. return bignorm(z);
  2907. }
  2908. static VALUE
  2909. bigor_int(VALUE x, long y)
  2910. {
  2911. VALUE z;
  2912. BDIGIT *xds, *zds;
  2913. long xn, zn;
  2914. long i;
  2915. char sign;
  2916. sign = (y >= 0);
  2917. xds = BDIGITS(x);
  2918. zn = xn = RBIGNUM_LEN(x);
  2919. z = bignew(zn, RBIGNUM_SIGN(x) && sign);
  2920. zds = BDIGITS(z);
  2921. #if SIZEOF_BDIGITS == SIZEOF_LONG
  2922. i = 1;
  2923. zds[0] = xds[0] | y;
  2924. #else
  2925. {
  2926. BDIGIT_DBL num = y;
  2927. for (i=0; i<(int)(sizeof(y)/sizeof(BDIGIT)); i++) {
  2928. zds[i] = xds[i] | BIGLO(num);
  2929. num = BIGDN(num);
  2930. }
  2931. }
  2932. #endif
  2933. while (i < xn) {
  2934. zds[i] = sign?xds[i]:(BDIGIT)(BIGRAD-1);
  2935. i++;
  2936. }
  2937. if (!RBIGNUM_SIGN(z)) get2comp(z);
  2938. return bignorm(z);
  2939. }
  2940. /*
  2941. * call-seq:
  2942. * big | numeric -> integer
  2943. *
  2944. * Performs bitwise +or+ between _big_ and _numeric_.
  2945. */
  2946. VALUE
  2947. rb_big_or(VALUE xx, VALUE yy)
  2948. {
  2949. volatile VALUE x, y, z;
  2950. BDIGIT *ds1, *ds2, *zds;
  2951. long i, l1, l2;
  2952. char sign;
  2953. if (!FIXNUM_P(yy) && !RB_TYPE_P(yy, T_BIGNUM)) {
  2954. return rb_num_coerce_bit(xx, yy, '|');
  2955. }
  2956. x = xx;
  2957. y = yy;
  2958. if (!RBIGNUM_SIGN(x)) {
  2959. x = rb_big_clone(x);
  2960. get2comp(x);
  2961. }
  2962. if (FIXNUM_P(y)) {
  2963. return bigor_int(x, FIX2LONG(y));
  2964. }
  2965. if (!RBIGNUM_SIGN(y)) {
  2966. y = rb_big_clone(y);
  2967. get2comp(y);
  2968. }
  2969. if (RBIGNUM_LEN(x) > RBIGNUM_LEN(y)) {
  2970. l1 = RBIGNUM_LEN(y);
  2971. l2 = RBIGNUM_LEN(x);
  2972. ds1 = BDIGITS(y);
  2973. ds2 = BDIGITS(x);
  2974. sign = RBIGNUM_SIGN(y);
  2975. }
  2976. else {
  2977. l1 = RBIGNUM_LEN(x);
  2978. l2 = RBIGNUM_LEN(y);
  2979. ds1 = BDIGITS(x);
  2980. ds2 = BDIGITS(y);
  2981. sign = RBIGNUM_SIGN(x);
  2982. }
  2983. z = bignew(l2, RBIGNUM_SIGN(x) && RBIGNUM_SIGN(y));
  2984. zds = BDIGITS(z);
  2985. for (i=0; i<l1; i++) {
  2986. zds[i] = ds1[i] | ds2[i];
  2987. }
  2988. for (; i<l2; i++) {
  2989. zds[i] = sign?ds2[i]:(BDIGIT)(BIGRAD-1);
  2990. }
  2991. if (!RBIGNUM_SIGN(z)) get2comp(z);
  2992. return bignorm(z);
  2993. }
  2994. static VALUE
  2995. bigxor_int(VALUE x, long y)
  2996. {
  2997. VALUE z;
  2998. BDIGIT *xds, *zds;
  2999. long xn, zn;
  3000. long i;
  3001. char sign;
  3002. sign = (y >= 0) ? 1 : 0;
  3003. xds = BDIGITS(x);
  3004. zn = xn = RBIGNUM_LEN(x);
  3005. z = bignew(zn, !(RBIGNUM_SIGN(x) ^ sign));
  3006. zds = BDIGITS(z);
  3007. #if SIZEOF_BDIGITS == SIZEOF_LONG
  3008. i = 1;
  3009. zds[0] = xds[0] ^ y;
  3010. #else
  3011. {
  3012. BDIGIT_DBL num = y;
  3013. for (i=0; i<(int)(sizeof(y)/sizeof(BDIGIT)); i++) {
  3014. zds[i] = xds[i] ^ BIGLO(num);
  3015. num = BIGDN(num);
  3016. }
  3017. }
  3018. #endif
  3019. while (i < xn) {
  3020. zds[i] = sign?xds[i]:~xds[i];
  3021. i++;
  3022. }
  3023. if (!RBIGNUM_SIGN(z)) get2comp(z);
  3024. return bignorm(z);
  3025. }
  3026. /*
  3027. * call-seq:
  3028. * big ^ numeric -> integer
  3029. *
  3030. * Performs bitwise +exclusive or+ between _big_ and _numeric_.
  3031. */
  3032. VALUE
  3033. rb_big_xor(VALUE xx, VALUE yy)
  3034. {
  3035. volatile VALUE x, y;
  3036. VALUE z;
  3037. BDIGIT *ds1, *ds2, *zds;
  3038. long i, l1, l2;
  3039. char sign;
  3040. if (!FIXNUM_P(yy) && !RB_TYPE_P(yy, T_BIGNUM)) {
  3041. return rb_num_coerce_bit(xx, yy, '^');
  3042. }
  3043. x = xx;
  3044. y = yy;
  3045. if (!RBIGNUM_SIGN(x)) {
  3046. x = rb_big_clone(x);
  3047. get2comp(x);
  3048. }
  3049. if (FIXNUM_P(y)) {
  3050. return bigxor_int(x, FIX2LONG(y));
  3051. }
  3052. if (!RBIGNUM_SIGN(y)) {
  3053. y = rb_big_clone(y);
  3054. get2comp(y);
  3055. }
  3056. if (RBIGNUM_LEN(x) > RBIGNUM_LEN(y)) {
  3057. l1 = RBIGNUM_LEN(y);
  3058. l2 = RBIGNUM_LEN(x);
  3059. ds1 = BDIGITS(y);
  3060. ds2 = BDIGITS(x);
  3061. sign = RBIGNUM_SIGN(y);
  3062. }
  3063. else {
  3064. l1 = RBIGNUM_LEN(x);
  3065. l2 = RBIGNUM_LEN(y);
  3066. ds1 = BDIGITS(x);
  3067. ds2 = BDIGITS(y);
  3068. sign = RBIGNUM_SIGN(x);
  3069. }
  3070. RBIGNUM_SET_SIGN(x, RBIGNUM_SIGN(x)?1:0);
  3071. RBIGNUM_SET_SIGN(y, RBIGNUM_SIGN(y)?1:0);
  3072. z = bignew(l2, !(RBIGNUM_SIGN(x) ^ RBIGNUM_SIGN(y)));
  3073. zds = BDIGITS(z);
  3074. for (i=0; i<l1; i++) {
  3075. zds[i] = ds1[i] ^ ds2[i];
  3076. }
  3077. for (; i<l2; i++) {
  3078. zds[i] = sign?ds2[i]:~ds2[i];
  3079. }
  3080. if (!RBIGNUM_SIGN(z)) get2comp(z);
  3081. return bignorm(z);
  3082. }
  3083. static VALUE
  3084. check_shiftdown(VALUE y, VALUE x)
  3085. {
  3086. if (!RBIGNUM_LEN(x)) return INT2FIX(0);
  3087. if (RBIGNUM_LEN(y) > SIZEOF_LONG / SIZEOF_BDIGITS) {
  3088. return RBIGNUM_SIGN(x) ? INT2FIX(0) : INT2FIX(-1);
  3089. }
  3090. return Qnil;
  3091. }
  3092. /*
  3093. * call-seq:
  3094. * big << numeric -> integer
  3095. *
  3096. * Shifts big left _numeric_ positions (right if _numeric_ is negative).
  3097. */
  3098. VALUE
  3099. rb_big_lshift(VALUE x, VALUE y)
  3100. {
  3101. long shift;
  3102. int neg = 0;
  3103. for (;;) {
  3104. if (FIXNUM_P(y)) {
  3105. shift = FIX2LONG(y);
  3106. if (shift < 0) {
  3107. neg = 1;
  3108. shift = -shift;
  3109. }
  3110. break;
  3111. }
  3112. else if (RB_TYPE_P(y, T_BIGNUM)) {
  3113. if (!RBIGNUM_SIGN(y)) {
  3114. VALUE t = check_shiftdown(y, x);
  3115. if (!NIL_P(t)) return t;
  3116. neg = 1;
  3117. }
  3118. shift = big2ulong(y, "long", TRUE);
  3119. break;
  3120. }
  3121. y = rb_to_int(y);
  3122. }
  3123. x = neg ? big_rshift(x, shift) : big_lshift(x, shift);
  3124. return bignorm(x);
  3125. }
  3126. static VALUE
  3127. big_lshift(VALUE x, unsigned long shift)
  3128. {
  3129. BDIGIT *xds, *zds;
  3130. long s1 = shift/BITSPERDIG;
  3131. int s2 = (int)(shift%BITSPERDIG);
  3132. VALUE z;
  3133. BDIGIT_DBL num = 0;
  3134. long len, i;
  3135. len = RBIGNUM_LEN(x);
  3136. z = bignew(len+s1+1, RBIGNUM_SIGN(x));
  3137. zds = BDIGITS(z);
  3138. for (i=0; i<s1; i++) {
  3139. *zds++ = 0;
  3140. }
  3141. xds = BDIGITS(x);
  3142. for (i=0; i<len; i++) {
  3143. num = num | (BDIGIT_DBL)*xds++<<s2;
  3144. *zds++ = BIGLO(num);
  3145. num = BIGDN(num);
  3146. }
  3147. *zds = BIGLO(num);
  3148. return z;
  3149. }
  3150. /*
  3151. * call-seq:
  3152. * big >> numeric -> integer
  3153. *
  3154. * Shifts big right _numeric_ positions (left if _numeric_ is negative).
  3155. */
  3156. VALUE
  3157. rb_big_rshift(VALUE x, VALUE y)
  3158. {
  3159. long shift;
  3160. int neg = 0;
  3161. for (;;) {
  3162. if (FIXNUM_P(y)) {
  3163. shift = FIX2LONG(y);
  3164. if (shift < 0) {
  3165. neg = 1;
  3166. shift = -shift;
  3167. }
  3168. break;
  3169. }
  3170. else if (RB_TYPE_P(y, T_BIGNUM)) {
  3171. if (RBIGNUM_SIGN(y)) {
  3172. VALUE t = check_shiftdown(y, x);
  3173. if (!NIL_P(t)) return t;
  3174. }
  3175. else {
  3176. neg = 1;
  3177. }
  3178. shift = big2ulong(y, "long", TRUE);
  3179. break;
  3180. }
  3181. y = rb_to_int(y);
  3182. }
  3183. x = neg ? big_lshift(x, shift) : big_rshift(x, shift);
  3184. return bignorm(x);
  3185. }
  3186. static VALUE
  3187. big_rshift(VALUE x, unsigned long shift)
  3188. {
  3189. BDIGIT *xds, *zds;
  3190. long s1 = shift/BITSPERDIG;
  3191. int s2 = (int)(shift%BITSPERDIG);
  3192. VALUE z;
  3193. BDIGIT_DBL num = 0;
  3194. long i, j;
  3195. volatile VALUE save_x;
  3196. if (s1 > RBIGNUM_LEN(x)) {
  3197. if (RBIGNUM_SIGN(x))
  3198. return INT2FIX(0);
  3199. else
  3200. return INT2FIX(-1);
  3201. }
  3202. if (!RBIGNUM_SIGN(x)) {
  3203. x = rb_big_clone(x);
  3204. get2comp(x);
  3205. }
  3206. save_x = x;
  3207. xds = BDIGITS(x);
  3208. i = RBIGNUM_LEN(x); j = i - s1;
  3209. if (j == 0) {
  3210. if (RBIGNUM_SIGN(x)) return INT2FIX(0);
  3211. else return INT2FIX(-1);
  3212. }
  3213. z = bignew(j, RBIGNUM_SIGN(x));
  3214. if (!RBIGNUM_SIGN(x)) {
  3215. num = ((BDIGIT_DBL)~0) << BITSPERDIG;
  3216. }
  3217. zds = BDIGITS(z);
  3218. while (i--, j--) {
  3219. num = (num | xds[i]) >> s2;
  3220. zds[j] = BIGLO(num);
  3221. num = BIGUP(xds[i]);
  3222. }
  3223. if (!RBIGNUM_SIGN(x)) {
  3224. get2comp(z);
  3225. }
  3226. RB_GC_GUARD(save_x);
  3227. return z;
  3228. }
  3229. /*
  3230. * call-seq:
  3231. * big[n] -> 0, 1
  3232. *
  3233. * Bit Reference---Returns the <em>n</em>th bit in the (assumed) binary
  3234. * representation of <i>big</i>, where <i>big</i>[0] is the least
  3235. * significant bit.
  3236. *
  3237. * a = 9**15
  3238. * 50.downto(0) do |n|
  3239. * print a[n]
  3240. * end
  3241. *
  3242. * <em>produces:</em>
  3243. *
  3244. * 000101110110100000111000011110010100111100010111001
  3245. *
  3246. */
  3247. static VALUE
  3248. rb_big_aref(VALUE x, VALUE y)
  3249. {
  3250. BDIGIT *xds;
  3251. BDIGIT_DBL num;
  3252. VALUE shift;
  3253. long i, s1, s2;
  3254. if (RB_TYPE_P(y, T_BIGNUM)) {
  3255. if (!RBIGNUM_SIGN(y))
  3256. return INT2FIX(0);
  3257. bigtrunc(y);
  3258. if (RBIGNUM_LEN(y) > DIGSPERLONG) {
  3259. out_of_range:
  3260. return RBIGNUM_SIGN(x) ? INT2FIX(0) : INT2FIX(1);
  3261. }
  3262. shift = big2ulong(y, "long", FALSE);
  3263. }
  3264. else {
  3265. i = NUM2LONG(y);
  3266. if (i < 0) return INT2FIX(0);
  3267. shift = (VALUE)i;
  3268. }
  3269. s1 = shift/BITSPERDIG;
  3270. s2 = shift%BITSPERDIG;
  3271. if (s1 >= RBIGNUM_LEN(x)) goto out_of_range;
  3272. if (!RBIGNUM_SIGN(x)) {
  3273. xds = BDIGITS(x);
  3274. i = 0; num = 1;
  3275. while (num += ~xds[i], ++i <= s1) {
  3276. num = BIGDN(num);
  3277. }
  3278. }
  3279. else {
  3280. num = BDIGITS(x)[s1];
  3281. }
  3282. if (num & ((BDIGIT_DBL)1<<s2))
  3283. return INT2FIX(1);
  3284. return INT2FIX(0);
  3285. }
  3286. /*
  3287. * call-seq:
  3288. * big.hash -> fixnum
  3289. *
  3290. * Compute a hash based on the value of _big_.
  3291. */
  3292. static VALUE
  3293. rb_big_hash(VALUE x)
  3294. {
  3295. st_index_t hash;
  3296. hash = rb_memhash(BDIGITS(x), sizeof(BDIGIT)*RBIGNUM_LEN(x)) ^ RBIGNUM_SIGN(x);
  3297. return INT2FIX(hash);
  3298. }
  3299. /*
  3300. * MISSING: documentation
  3301. */
  3302. static VALUE
  3303. rb_big_coerce(VALUE x, VALUE y)
  3304. {
  3305. if (FIXNUM_P(y)) {
  3306. y = rb_int2big(FIX2LONG(y));
  3307. }
  3308. else if (!RB_TYPE_P(y, T_BIGNUM)) {
  3309. rb_raise(rb_eTypeError, "can't coerce %s to Bignum",
  3310. rb_obj_classname(y));
  3311. }
  3312. return rb_assoc_new(y, x);
  3313. }
  3314. /*
  3315. * call-seq:
  3316. * big.abs -> aBignum
  3317. *
  3318. * Returns the absolute value of <i>big</i>.
  3319. *
  3320. * -1234567890987654321.abs #=> 1234567890987654321
  3321. */
  3322. static VALUE
  3323. rb_big_abs(VALUE x)
  3324. {
  3325. if (!RBIGNUM_SIGN(x)) {
  3326. x = rb_big_clone(x);
  3327. RBIGNUM_SET_SIGN(x, 1);
  3328. }
  3329. return x;
  3330. }
  3331. /*
  3332. * call-seq:
  3333. * big.size -> integer
  3334. *
  3335. * Returns the number of bytes in the machine representation of
  3336. * <i>big</i>.
  3337. *
  3338. * (256**10 - 1).size #=> 12
  3339. * (256**20 - 1).size #=> 20
  3340. * (256**40 - 1).size #=> 40
  3341. */
  3342. static VALUE
  3343. rb_big_size(VALUE big)
  3344. {
  3345. return LONG2FIX(RBIGNUM_LEN(big)*SIZEOF_BDIGITS);
  3346. }
  3347. /*
  3348. * call-seq:
  3349. * big.odd? -> true or false
  3350. *
  3351. * Returns <code>true</code> if <i>big</i> is an odd number.
  3352. */
  3353. static VALUE
  3354. rb_big_odd_p(VALUE num)
  3355. {
  3356. if (BDIGITS(num)[0] & 1) {
  3357. return Qtrue;
  3358. }
  3359. return Qfalse;
  3360. }
  3361. /*
  3362. * call-seq:
  3363. * big.even? -> true or false
  3364. *
  3365. * Returns <code>true</code> if <i>big</i> is an even number.
  3366. */
  3367. static VALUE
  3368. rb_big_even_p(VALUE num)
  3369. {
  3370. if (BDIGITS(num)[0] & 1) {
  3371. return Qfalse;
  3372. }
  3373. return Qtrue;
  3374. }
  3375. /*
  3376. * Bignum objects hold integers outside the range of
  3377. * Fixnum. Bignum objects are created
  3378. * automatically when integer calculations would otherwise overflow a
  3379. * Fixnum. When a calculation involving
  3380. * Bignum objects returns a result that will fit in a
  3381. * Fixnum, the result is automatically converted.
  3382. *
  3383. * For the purposes of the bitwise operations and <code>[]</code>, a
  3384. * Bignum is treated as if it were an infinite-length
  3385. * bitstring with 2's complement representation.
  3386. *
  3387. * While Fixnum values are immediate, Bignum
  3388. * objects are not---assignment and parameter passing work with
  3389. * references to objects, not the objects themselves.
  3390. *
  3391. */
  3392. void
  3393. Init_Bignum(void)
  3394. {
  3395. rb_cBignum = rb_define_class("Bignum", rb_cInteger);
  3396. rb_define_method(rb_cBignum, "to_s", rb_big_to_s, -1);
  3397. rb_define_alias(rb_cBignum, "inspect", "to_s");
  3398. rb_define_method(rb_cBignum, "coerce", rb_big_coerce, 1);
  3399. rb_define_method(rb_cBignum, "-@", rb_big_uminus, 0);
  3400. rb_define_method(rb_cBignum, "+", rb_big_plus, 1);
  3401. rb_define_method(rb_cBignum, "-", rb_big_minus, 1);
  3402. rb_define_method(rb_cBignum, "*", rb_big_mul, 1);
  3403. rb_define_method(rb_cBignum, "/", rb_big_div, 1);
  3404. rb_define_method(rb_cBignum, "%", rb_big_modulo, 1);
  3405. rb_define_method(rb_cBignum, "div", rb_big_idiv, 1);
  3406. rb_define_method(rb_cBignum, "divmod", rb_big_divmod, 1);
  3407. rb_define_method(rb_cBignum, "modulo", rb_big_modulo, 1);
  3408. rb_define_method(rb_cBignum, "remainder", rb_big_remainder, 1);
  3409. rb_define_method(rb_cBignum, "fdiv", rb_big_fdiv, 1);
  3410. rb_define_method(rb_cBignum, "**", rb_big_pow, 1);
  3411. rb_define_method(rb_cBignum, "&", rb_big_and, 1);
  3412. rb_define_method(rb_cBignum, "|", rb_big_or, 1);
  3413. rb_define_method(rb_cBignum, "^", rb_big_xor, 1);
  3414. rb_define_method(rb_cBignum, "~", rb_big_neg, 0);
  3415. rb_define_method(rb_cBignum, "<<", rb_big_lshift, 1);
  3416. rb_define_method(rb_cBignum, ">>", rb_big_rshift, 1);
  3417. rb_define_method(rb_cBignum, "[]", rb_big_aref, 1);
  3418. rb_define_method(rb_cBignum, "<=>", rb_big_cmp, 1);
  3419. rb_define_method(rb_cBignum, "==", rb_big_eq, 1);
  3420. rb_define_method(rb_cBignum, ">", big_gt, 1);
  3421. rb_define_method(rb_cBignum, ">=", big_ge, 1);
  3422. rb_define_method(rb_cBignum, "<", big_lt, 1);
  3423. rb_define_method(rb_cBignum, "<=", big_le, 1);
  3424. rb_define_method(rb_cBignum, "===", rb_big_eq, 1);
  3425. rb_define_method(rb_cBignum, "eql?", rb_big_eql, 1);
  3426. rb_define_method(rb_cBignum, "hash", rb_big_hash, 0);
  3427. rb_define_method(rb_cBignum, "to_f", rb_big_to_f, 0);
  3428. rb_define_method(rb_cBignum, "abs", rb_big_abs, 0);
  3429. rb_define_method(rb_cBignum, "magnitude", rb_big_abs, 0);
  3430. rb_define_method(rb_cBignum, "size", rb_big_size, 0);
  3431. rb_define_method(rb_cBignum, "odd?", rb_big_odd_p, 0);
  3432. rb_define_method(rb_cBignum, "even?", rb_big_even_p, 0);
  3433. power_cache_init();
  3434. big_three = rb_uint2big(3);
  3435. rb_gc_register_mark_object(big_three);
  3436. }