PageRenderTime 33ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/bignum.c

https://github.com/isaac/MacRuby
C | 3671 lines | 2882 code | 423 blank | 366 comment | 673 complexity | f19243715966d2979a1b5e60b3efd5ed MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1
  1. /*
  2. * This file is covered by the Ruby license. See COPYING for more details.
  3. *
  4. * Copyright (C) 2007-2011, Apple Inc. All rights reserved.
  5. * Copyright (C) 1993-2007 Yukihiro Matsumoto
  6. */
  7. #include "macruby_internal.h"
  8. #include "objc.h"
  9. #include "encoding.h"
  10. #include <math.h>
  11. #include <float.h>
  12. #include <ctype.h>
  13. #ifdef HAVE_IEEEFP_H
  14. #include <ieeefp.h>
  15. #endif
  16. #include <assert.h>
  17. VALUE rb_cBignum;
  18. #if defined __MINGW32__
  19. #define USHORT _USHORT
  20. #endif
  21. #define BDIGITS(x) (RBIGNUM_DIGITS(x))
  22. #define BITSPERDIG (SIZEOF_BDIGITS*CHAR_BIT)
  23. #define BIGRAD ((BDIGIT_DBL)1 << BITSPERDIG)
  24. #define DIGSPERLONG (SIZEOF_LONG/SIZEOF_BDIGITS)
  25. #if HAVE_LONG_LONG
  26. # define DIGSPERLL (SIZEOF_LONG_LONG/SIZEOF_BDIGITS)
  27. #endif
  28. #define BIGUP(x) ((BDIGIT_DBL)(x) << BITSPERDIG)
  29. #define BIGDN(x) RSHIFT(x,BITSPERDIG)
  30. #define BIGLO(x) ((BDIGIT)((x) & (BIGRAD-1)))
  31. #define BDIGMAX ((BDIGIT)-1)
  32. #define BIGZEROP(x) (RBIGNUM_LEN(x) == 0 || \
  33. (BDIGITS(x)[0] == 0 && \
  34. (RBIGNUM_LEN(x) == 1 || bigzero_p(x))))
  35. static int
  36. bigzero_p(VALUE x)
  37. {
  38. long i;
  39. BDIGIT *ds = BDIGITS(x);
  40. for (i = RBIGNUM_LEN(x) - 1; 0 <= i; i--) {
  41. if (ds[i]) return 0;
  42. }
  43. return 1;
  44. }
  45. int
  46. rb_bigzero_p(VALUE x)
  47. {
  48. return BIGZEROP(x);
  49. }
  50. int
  51. rb_cmpint(VALUE val, VALUE a, VALUE b)
  52. {
  53. if (NIL_P(val)) {
  54. rb_cmperr(a, b);
  55. }
  56. if (FIXNUM_P(val)) {
  57. long l = FIX2LONG(val);
  58. if (l > 0) return 1;
  59. if (l < 0) return -1;
  60. return 0;
  61. }
  62. if (TYPE(val) == T_BIGNUM) {
  63. if (BIGZEROP(val)) return 0;
  64. if (RBIGNUM_SIGN(val)) return 1;
  65. return -1;
  66. }
  67. if (RTEST(rb_funcall(val, '>', 1, INT2FIX(0)))) return 1;
  68. if (RTEST(rb_funcall(val, '<', 1, INT2FIX(0)))) return -1;
  69. return 0;
  70. }
  71. #define RBIGNUM_SET_LEN(b,l) \
  72. ((RBASIC(b)->flags & RBIGNUM_EMBED_FLAG) ? \
  73. (RBASIC(b)->flags = (RBASIC(b)->flags & ~RBIGNUM_EMBED_LEN_MASK) | \
  74. ((l) << RBIGNUM_EMBED_LEN_SHIFT)) : \
  75. (RBIGNUM(b)->as.heap.len = (l)))
  76. static void
  77. rb_big_realloc(VALUE big, long len)
  78. {
  79. BDIGIT *ds;
  80. if (RBASIC(big)->flags & RBIGNUM_EMBED_FLAG) {
  81. if (RBIGNUM_EMBED_LEN_MAX < len) {
  82. ds = ALLOC_N(BDIGIT, len);
  83. MEMCPY(ds, RBIGNUM(big)->as.ary, BDIGIT, RBIGNUM_EMBED_LEN_MAX);
  84. RBIGNUM(big)->as.heap.len = RBIGNUM_LEN(big);
  85. GC_WB(&RBIGNUM(big)->as.heap.digits, ds);
  86. RBASIC(big)->flags &= ~RBIGNUM_EMBED_FLAG;
  87. }
  88. }
  89. else {
  90. if (len <= RBIGNUM_EMBED_LEN_MAX) {
  91. ds = RBIGNUM(big)->as.heap.digits;
  92. RBASIC(big)->flags |= RBIGNUM_EMBED_FLAG;
  93. RBIGNUM_SET_LEN(big, len);
  94. if (ds) {
  95. MEMCPY(RBIGNUM(big)->as.ary, ds, BDIGIT, len);
  96. xfree(ds);
  97. }
  98. }
  99. else {
  100. if (RBIGNUM_LEN(big) == 0) {
  101. GC_WB(&RBIGNUM(big)->as.heap.digits, ALLOC_N(BDIGIT, len));
  102. }
  103. else {
  104. void *tmp = ruby_xrealloc(RBIGNUM(big)->as.heap.digits, sizeof(BDIGIT) * len);
  105. if (tmp != RBIGNUM(big)->as.heap.digits) {
  106. GC_WB(&RBIGNUM(big)->as.heap.digits, tmp);
  107. }
  108. }
  109. }
  110. }
  111. }
  112. void
  113. rb_big_resize(VALUE big, long len)
  114. {
  115. rb_big_realloc(big, len);
  116. RBIGNUM_SET_LEN(big, len);
  117. }
  118. static VALUE
  119. bignew_1(VALUE klass, long len, int sign)
  120. {
  121. NEWOBJ(big, struct RBignum);
  122. OBJSETUP(big, klass, T_BIGNUM);
  123. RBIGNUM_SET_SIGN(big, sign?1:0);
  124. if (len <= RBIGNUM_EMBED_LEN_MAX) {
  125. RBASIC(big)->flags |= RBIGNUM_EMBED_FLAG;
  126. RBIGNUM_SET_LEN(big, len);
  127. }
  128. else {
  129. rb_big_resize((VALUE)big, len);
  130. }
  131. return (VALUE)big;
  132. }
  133. #define bignew(len,sign) bignew_1(rb_cBignum,len,sign)
  134. VALUE
  135. rb_bignum_new_retained(const char *str)
  136. {
  137. VALUE v = rb_cstr2inum(str, 10);
  138. GC_RETAIN(v);
  139. return v;
  140. }
  141. VALUE
  142. rb_big_new(long len, int sign)
  143. {
  144. return bignew(len, sign != 0);
  145. }
  146. VALUE
  147. rb_big_clone(VALUE x)
  148. {
  149. long len = RBIGNUM_LEN(x);
  150. VALUE z = bignew_1(CLASS_OF(x), len, RBIGNUM_SIGN(x));
  151. MEMCPY(BDIGITS(z), BDIGITS(x), BDIGIT, len);
  152. return z;
  153. }
  154. /* modify a bignum by 2's complement */
  155. static void
  156. get2comp(VALUE x)
  157. {
  158. long i = RBIGNUM_LEN(x);
  159. BDIGIT *ds = BDIGITS(x);
  160. BDIGIT_DBL num;
  161. if (!i) return;
  162. while (i--) ds[i] = ~ds[i];
  163. i = 0; num = 1;
  164. do {
  165. num += ds[i];
  166. ds[i++] = BIGLO(num);
  167. num = BIGDN(num);
  168. } while (i < RBIGNUM_LEN(x));
  169. if (num != 0) {
  170. rb_big_resize(x, RBIGNUM_LEN(x)+1);
  171. ds = BDIGITS(x);
  172. ds[RBIGNUM_LEN(x)-1] = 1;
  173. }
  174. }
  175. void
  176. rb_big_2comp(VALUE x) /* get 2's complement */
  177. {
  178. get2comp(x);
  179. }
  180. static inline VALUE
  181. bigtrunc(VALUE x)
  182. {
  183. long len = RBIGNUM_LEN(x);
  184. BDIGIT *ds = BDIGITS(x);
  185. if (len == 0) return x;
  186. while (--len && !ds[len]);
  187. if (RBIGNUM_LEN(x) > len+1) {
  188. rb_big_resize(x, len+1);
  189. }
  190. return x;
  191. }
  192. static inline VALUE
  193. bigfixize(VALUE x)
  194. {
  195. long len = RBIGNUM_LEN(x);
  196. BDIGIT *ds = BDIGITS(x);
  197. if (len == 0) return INT2FIX(0);
  198. if ((size_t)(len*SIZEOF_BDIGITS) <= sizeof(long)) {
  199. long num = 0;
  200. #if 2*SIZEOF_BDIGITS > SIZEOF_LONG
  201. num = (long)ds[0];
  202. #else
  203. while (len--) {
  204. num = (long)(BIGUP(num) + ds[len]);
  205. }
  206. #endif
  207. if (num >= 0) {
  208. if (RBIGNUM_SIGN(x)) {
  209. if (POSFIXABLE(num)) return LONG2FIX(num);
  210. }
  211. else {
  212. if (NEGFIXABLE(-num)) return LONG2FIX(-num);
  213. }
  214. }
  215. }
  216. return x;
  217. }
  218. static VALUE
  219. bignorm(VALUE x)
  220. {
  221. if (!FIXNUM_P(x) && TYPE(x) == T_BIGNUM) {
  222. x = bigfixize(bigtrunc(x));
  223. }
  224. return x;
  225. }
  226. VALUE
  227. rb_big_norm(VALUE x)
  228. {
  229. return bignorm(x);
  230. }
  231. VALUE
  232. rb_uint2big(VALUE n)
  233. {
  234. BDIGIT_DBL num = n;
  235. long i = 0;
  236. BDIGIT *digits;
  237. VALUE big;
  238. big = bignew(DIGSPERLONG, 1);
  239. digits = BDIGITS(big);
  240. while (i < DIGSPERLONG) {
  241. digits[i++] = BIGLO(num);
  242. num = BIGDN(num);
  243. }
  244. i = DIGSPERLONG;
  245. while (--i && !digits[i]) ;
  246. RBIGNUM_SET_LEN(big, i+1);
  247. return big;
  248. }
  249. VALUE
  250. rb_int2big(SIGNED_VALUE n)
  251. {
  252. long neg = 0;
  253. VALUE big;
  254. if (n < 0) {
  255. n = -n;
  256. neg = 1;
  257. }
  258. big = rb_uint2big(n);
  259. if (neg) {
  260. RBIGNUM_SET_SIGN(big, 0);
  261. }
  262. return big;
  263. }
  264. #if SIZEOF_LONG % SIZEOF_BDIGITS != 0
  265. # error unexpected SIZEOF_LONG : SIZEOF_BDIGITS ratio
  266. #endif
  267. /*
  268. * buf is an array of long integers.
  269. * buf is ordered from least significant word to most significant word.
  270. * buf[0] is the least significant word and
  271. * buf[num_longs-1] is the most significant word.
  272. * This means words in buf is little endian.
  273. * However each word in buf is native endian.
  274. * (buf[i]&1) is the least significant bit and
  275. * (buf[i]&(1<<(SIZEOF_LONG*CHAR_BIT-1))) is the most significant bit
  276. * for each 0 <= i < num_longs.
  277. * So buf is little endian at whole on a little endian machine.
  278. * But buf is mixed endian on a big endian machine.
  279. */
  280. void
  281. rb_big_pack(VALUE val, unsigned long *buf, long num_longs)
  282. {
  283. val = rb_to_int(val);
  284. if (num_longs == 0)
  285. return;
  286. if (FIXNUM_P(val)) {
  287. long i;
  288. long tmp = FIX2LONG(val);
  289. buf[0] = (unsigned long)tmp;
  290. tmp = tmp < 0 ? ~0L : 0;
  291. for (i = 1; i < num_longs; i++)
  292. buf[i] = (unsigned long)tmp;
  293. return;
  294. }
  295. else {
  296. long len = RBIGNUM_LEN(val);
  297. BDIGIT *ds = BDIGITS(val), *dend = ds + len;
  298. long i, j;
  299. for (i = 0; i < num_longs && ds < dend; i++) {
  300. unsigned long l = 0;
  301. for (j = 0; j < DIGSPERLONG && ds < dend; j++, ds++) {
  302. l |= ((unsigned long)*ds << (j * BITSPERDIG));
  303. }
  304. buf[i] = l;
  305. }
  306. for (; i < num_longs; i++)
  307. buf[i] = 0;
  308. if (RBIGNUM_NEGATIVE_P(val)) {
  309. for (i = 0; i < num_longs; i++) {
  310. buf[i] = ~buf[i];
  311. }
  312. for (i = 0; i < num_longs; i++) {
  313. buf[i]++;
  314. if (buf[i] != 0)
  315. return;
  316. }
  317. }
  318. }
  319. }
  320. /* See rb_big_pack comment for endianness of buf. */
  321. VALUE
  322. rb_big_unpack(unsigned long *buf, long num_longs)
  323. {
  324. while (2 <= num_longs) {
  325. if (buf[num_longs-1] == 0 && (long)buf[num_longs-2] >= 0)
  326. num_longs--;
  327. else if (buf[num_longs-1] == ~0UL && (long)buf[num_longs-2] < 0)
  328. num_longs--;
  329. else
  330. break;
  331. }
  332. if (num_longs == 0)
  333. return INT2FIX(0);
  334. else if (num_longs == 1)
  335. return LONG2NUM((long)buf[0]);
  336. else {
  337. VALUE big;
  338. BDIGIT *ds;
  339. long len = num_longs * DIGSPERLONG;
  340. long i;
  341. big = bignew(len, 1);
  342. ds = BDIGITS(big);
  343. for (i = 0; i < num_longs; i++) {
  344. unsigned long d = buf[i];
  345. #if SIZEOF_LONG == SIZEOF_BDIGITS
  346. *ds++ = d;
  347. #else
  348. int j;
  349. for (j = 0; j < DIGSPERLONG; j++) {
  350. *ds++ = BIGLO(d);
  351. d = BIGDN(d);
  352. }
  353. #endif
  354. }
  355. if ((long)buf[num_longs-1] < 0) {
  356. get2comp(big);
  357. RBIGNUM_SET_SIGN(big, 0);
  358. }
  359. return bignorm(big);
  360. }
  361. }
  362. #define QUAD_SIZE 8
  363. #ifdef HAVE_LONG_LONG
  364. void
  365. rb_quad_pack(char *buf, VALUE val)
  366. {
  367. LONG_LONG q;
  368. val = rb_to_int(val);
  369. if (FIXNUM_P(val)) {
  370. q = FIX2LONG(val);
  371. }
  372. else {
  373. long len = RBIGNUM_LEN(val);
  374. BDIGIT *ds;
  375. if (len > SIZEOF_LONG_LONG/SIZEOF_BDIGITS) {
  376. len = SIZEOF_LONG_LONG/SIZEOF_BDIGITS;
  377. }
  378. ds = BDIGITS(val);
  379. q = 0;
  380. while (len--) {
  381. q = BIGUP(q);
  382. q += ds[len];
  383. }
  384. if (!RBIGNUM_SIGN(val)) q = -q;
  385. }
  386. memcpy(buf, (char*)&q, SIZEOF_LONG_LONG);
  387. }
  388. VALUE
  389. rb_quad_unpack(const char *buf, int sign)
  390. {
  391. BDIGIT_DBL q;
  392. long neg = 0;
  393. long i;
  394. BDIGIT *digits;
  395. VALUE big;
  396. memcpy(&q, buf, SIZEOF_LONG_LONG);
  397. if (sign) {
  398. if (FIXABLE((LONG_LONG)q)) return LONG2FIX((LONG_LONG)q);
  399. if ((LONG_LONG)q < 0) {
  400. q = -(LONG_LONG)q;
  401. neg = 1;
  402. }
  403. }
  404. else {
  405. if (POSFIXABLE(q)) return LONG2FIX(q);
  406. }
  407. i = 0;
  408. big = bignew(DIGSPERLL, 1);
  409. digits = BDIGITS(big);
  410. while (i < DIGSPERLL) {
  411. digits[i++] = BIGLO(q);
  412. q = BIGDN(q);
  413. }
  414. i = DIGSPERLL;
  415. while (i-- && !digits[i]) ;
  416. RBIGNUM_SET_LEN(big, i+1);
  417. if (neg) {
  418. RBIGNUM_SET_SIGN(big, 0);
  419. }
  420. return bignorm(big);
  421. }
  422. #else
  423. static int
  424. quad_buf_complement(char *buf, size_t len)
  425. {
  426. size_t i;
  427. for (i = 0; i < len; i++)
  428. buf[i] = ~buf[i];
  429. for (i = 0; i < len; i++) {
  430. buf[i]++;
  431. if (buf[i] != 0)
  432. return 0;
  433. }
  434. return 1;
  435. }
  436. void
  437. rb_quad_pack(char *buf, VALUE val)
  438. {
  439. long len;
  440. memset(buf, 0, QUAD_SIZE);
  441. val = rb_to_int(val);
  442. if (FIXNUM_P(val)) {
  443. val = rb_int2big(FIX2LONG(val));
  444. }
  445. len = RBIGNUM_LEN(val) * SIZEOF_BDIGITS;
  446. if (len > QUAD_SIZE) {
  447. len = QUAD_SIZE;
  448. }
  449. memcpy(buf, (char*)BDIGITS(val), len);
  450. if (RBIGNUM_NEGATIVE_P(val)) {
  451. quad_buf_complement(buf, QUAD_SIZE);
  452. }
  453. }
  454. #define BNEG(b) (RSHIFT(((BDIGIT*)b)[QUAD_SIZE/SIZEOF_BDIGITS-1],BITSPERDIG-1) != 0)
  455. VALUE
  456. rb_quad_unpack(const char *buf, int sign)
  457. {
  458. VALUE big = bignew(QUAD_SIZE/SIZEOF_BDIGITS, 1);
  459. memcpy((char*)BDIGITS(big), buf, QUAD_SIZE);
  460. if (sign && BNEG(buf)) {
  461. char *tmp = (char*)BDIGITS(big);
  462. RBIGNUM_SET_SIGN(big, 0);
  463. quad_buf_complement(tmp, QUAD_SIZE);
  464. }
  465. return bignorm(big);
  466. }
  467. #endif
  468. VALUE
  469. rb_cstr_to_inum(const char *str, int base, int badcheck)
  470. {
  471. const char *s = str;
  472. char *end;
  473. char sign = 1, nondigit = 0;
  474. int c;
  475. BDIGIT_DBL num;
  476. long len, blen = 1;
  477. long i;
  478. VALUE z;
  479. BDIGIT *zds;
  480. #undef ISDIGIT
  481. #define ISDIGIT(c) ('0' <= (c) && (c) <= '9')
  482. #define conv_digit(c) \
  483. (!ISASCII(c) ? -1 : \
  484. ISDIGIT(c) ? ((c) - '0') : \
  485. ISLOWER(c) ? ((c) - 'a' + 10) : \
  486. ISUPPER(c) ? ((c) - 'A' + 10) : \
  487. -1)
  488. if (!str) {
  489. if (badcheck) goto bad;
  490. return INT2FIX(0);
  491. }
  492. while (ISSPACE(*str)) str++;
  493. if (str[0] == '+') {
  494. str++;
  495. }
  496. else if (str[0] == '-') {
  497. str++;
  498. sign = 0;
  499. }
  500. if (str[0] == '+' || str[0] == '-') {
  501. if (badcheck) goto bad;
  502. return INT2FIX(0);
  503. }
  504. if (base <= 0) {
  505. if (str[0] == '0') {
  506. switch (str[1]) {
  507. case 'x': case 'X':
  508. base = 16;
  509. break;
  510. case 'b': case 'B':
  511. base = 2;
  512. break;
  513. case 'o': case 'O':
  514. base = 8;
  515. break;
  516. case 'd': case 'D':
  517. base = 10;
  518. break;
  519. default:
  520. base = 8;
  521. }
  522. }
  523. else if (base < -1) {
  524. base = -base;
  525. }
  526. else {
  527. base = 10;
  528. }
  529. }
  530. switch (base) {
  531. case 2:
  532. len = 1;
  533. if (str[0] == '0' && (str[1] == 'b'||str[1] == 'B')) {
  534. str += 2;
  535. }
  536. break;
  537. case 3:
  538. len = 2;
  539. break;
  540. case 8:
  541. if (str[0] == '0' && (str[1] == 'o'||str[1] == 'O')) {
  542. str += 2;
  543. }
  544. case 4: case 5: case 6: case 7:
  545. len = 3;
  546. break;
  547. case 10:
  548. if (str[0] == '0' && (str[1] == 'd'||str[1] == 'D')) {
  549. str += 2;
  550. }
  551. case 9: case 11: case 12: case 13: case 14: case 15:
  552. len = 4;
  553. break;
  554. case 16:
  555. len = 4;
  556. if (str[0] == '0' && (str[1] == 'x'||str[1] == 'X')) {
  557. str += 2;
  558. }
  559. break;
  560. default:
  561. if (base < 2 || 36 < base) {
  562. rb_raise(rb_eArgError, "invalid radix %d", base);
  563. }
  564. if (base <= 32) {
  565. len = 5;
  566. }
  567. else {
  568. len = 6;
  569. }
  570. break;
  571. }
  572. if (*str == '0') { /* squeeze preceding 0s */
  573. int us = 0;
  574. while ((c = *++str) == '0' || c == '_') {
  575. if (c == '_') {
  576. if (++us >= 2)
  577. break;
  578. } else
  579. us = 0;
  580. }
  581. if (!(c = *str) || ISSPACE(c)) --str;
  582. }
  583. c = *str;
  584. c = conv_digit(c);
  585. if (c < 0 || c >= base) {
  586. if (badcheck) goto bad;
  587. return INT2FIX(0);
  588. }
  589. len *= strlen(str)*sizeof(char);
  590. if ((size_t)len <= (sizeof(long)*CHAR_BIT)) {
  591. unsigned long val = STRTOUL(str, &end, base);
  592. if (str < end && *end == '_') goto bigparse;
  593. if (badcheck) {
  594. if (end == str) goto bad; /* no number */
  595. while (*end && ISSPACE(*end)) end++;
  596. if (*end) goto bad; /* trailing garbage */
  597. }
  598. if (POSFIXABLE(val)) {
  599. if (sign) return LONG2FIX(val);
  600. else {
  601. long result = -(long)val;
  602. return LONG2FIX(result);
  603. }
  604. }
  605. else {
  606. VALUE big = rb_uint2big(val);
  607. RBIGNUM_SET_SIGN(big, sign);
  608. return bignorm(big);
  609. }
  610. }
  611. bigparse:
  612. len = (len/BITSPERDIG)+1;
  613. if (badcheck && *str == '_') goto bad;
  614. z = bignew(len, sign);
  615. zds = BDIGITS(z);
  616. for (i=len;i--;) zds[i]=0;
  617. while ((c = *str++) != 0) {
  618. if (c == '_') {
  619. if (nondigit) {
  620. if (badcheck) goto bad;
  621. break;
  622. }
  623. nondigit = c;
  624. continue;
  625. }
  626. else if ((c = conv_digit(c)) < 0) {
  627. break;
  628. }
  629. if (c >= base) break;
  630. nondigit = 0;
  631. i = 0;
  632. num = c;
  633. for (;;) {
  634. while (i<blen) {
  635. num += (BDIGIT_DBL)zds[i]*base;
  636. zds[i++] = BIGLO(num);
  637. num = BIGDN(num);
  638. }
  639. if (num) {
  640. blen++;
  641. continue;
  642. }
  643. break;
  644. }
  645. }
  646. if (badcheck) {
  647. str--;
  648. if (s+1 < str && str[-1] == '_') goto bad;
  649. while (*str && ISSPACE(*str)) str++;
  650. if (*str) {
  651. bad:
  652. rb_invalid_str(s, "Integer");
  653. }
  654. }
  655. return bignorm(z);
  656. }
  657. VALUE
  658. rb_str_to_inum(VALUE str, int base, int badcheck)
  659. {
  660. const char *s;
  661. long len;
  662. StringValue(str);
  663. str_check_ascii_compatible(str);
  664. if (badcheck) {
  665. s = StringValueCStr(str);
  666. }
  667. else {
  668. s = RSTRING_PTR(str);
  669. }
  670. if (s) {
  671. len = RSTRING_LEN(str);
  672. if (s[len]) { /* no sentinel somehow */
  673. char *p = ALLOCA_N(char, len+1);
  674. MEMCPY(p, s, char, len);
  675. p[len] = '\0';
  676. s = p;
  677. }
  678. }
  679. return rb_cstr_to_inum(s, base, badcheck);
  680. }
  681. #if HAVE_LONG_LONG
  682. VALUE
  683. rb_ull2big(unsigned long long n)
  684. {
  685. BDIGIT_DBL num = n;
  686. long i = 0;
  687. BDIGIT *digits;
  688. VALUE big;
  689. big = bignew(DIGSPERLL, 1);
  690. digits = BDIGITS(big);
  691. while (i < DIGSPERLL) {
  692. digits[i++] = BIGLO(num);
  693. num = BIGDN(num);
  694. }
  695. i = DIGSPERLL;
  696. while (i-- && !digits[i]) ;
  697. RBIGNUM_SET_LEN(big, i+1);
  698. return big;
  699. }
  700. VALUE
  701. rb_ll2big(long long n)
  702. {
  703. long neg = 0;
  704. VALUE big;
  705. if (n < 0) {
  706. n = -n;
  707. neg = 1;
  708. }
  709. big = rb_ull2big(n);
  710. if (neg) {
  711. RBIGNUM_SET_SIGN(big, 0);
  712. }
  713. return big;
  714. }
  715. #endif /* HAVE_LONG_LONG */
  716. VALUE
  717. rb_cstr2inum(const char *str, int base)
  718. {
  719. return rb_cstr_to_inum(str, base, base==0);
  720. }
  721. VALUE
  722. rb_str2inum(VALUE str, int base)
  723. {
  724. return rb_str_to_inum(str, base, base==0);
  725. }
  726. const char ruby_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz";
  727. static VALUE bigsqr(VALUE x);
  728. static void bigdivmod(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp);
  729. #define POW2_P(x) (((x)&((x)-1))==0)
  730. static inline int
  731. ones(register unsigned long x)
  732. {
  733. #if SIZEOF_LONG == 8
  734. # define MASK_55 0x5555555555555555UL
  735. # define MASK_33 0x3333333333333333UL
  736. # define MASK_0f 0x0f0f0f0f0f0f0f0fUL
  737. #else
  738. # define MASK_55 0x55555555UL
  739. # define MASK_33 0x33333333UL
  740. # define MASK_0f 0x0f0f0f0fUL
  741. #endif
  742. x -= (x >> 1) & MASK_55;
  743. x = ((x >> 2) & MASK_33) + (x & MASK_33);
  744. x = ((x >> 4) + x) & MASK_0f;
  745. x += (x >> 8);
  746. x += (x >> 16);
  747. #if SIZEOF_LONG == 8
  748. x += (x >> 32);
  749. #endif
  750. return (int)(x & 0x7f);
  751. #undef MASK_0f
  752. #undef MASK_33
  753. #undef MASK_55
  754. }
  755. static inline unsigned long
  756. next_pow2(register unsigned long x)
  757. {
  758. x |= x >> 1;
  759. x |= x >> 2;
  760. x |= x >> 4;
  761. x |= x >> 8;
  762. x |= x >> 16;
  763. #if SIZEOF_LONG == 8
  764. x |= x >> 32;
  765. #endif
  766. return x + 1;
  767. }
  768. static inline int
  769. floor_log2(register unsigned long x)
  770. {
  771. x |= x >> 1;
  772. x |= x >> 2;
  773. x |= x >> 4;
  774. x |= x >> 8;
  775. x |= x >> 16;
  776. #if SIZEOF_LONG == 8
  777. x |= x >> 32;
  778. #endif
  779. return (int)ones(x) - 1;
  780. }
  781. static inline int
  782. ceil_log2(register unsigned long x)
  783. {
  784. return floor_log2(x) + !POW2_P(x);
  785. }
  786. #define LOG2_KARATSUBA_DIGITS 7
  787. #define KARATSUBA_DIGITS (1L<<LOG2_KARATSUBA_DIGITS)
  788. #define MAX_BIG2STR_TABLE_ENTRIES 64
  789. static VALUE big2str_power_cache[35][MAX_BIG2STR_TABLE_ENTRIES];
  790. static void
  791. power_cache_init(void)
  792. {
  793. int i, j;
  794. for (i = 0; i < 35; ++i) {
  795. for (j = 0; j < MAX_BIG2STR_TABLE_ENTRIES; ++j) {
  796. big2str_power_cache[i][j] = Qnil;
  797. }
  798. }
  799. }
  800. static inline VALUE
  801. power_cache_get_power0(int base, int i)
  802. {
  803. if (NIL_P(big2str_power_cache[base - 2][i])) {
  804. big2str_power_cache[base - 2][i] =
  805. i == 0 ? rb_big_pow(rb_int2big(base), INT2FIX(KARATSUBA_DIGITS))
  806. : bigsqr(power_cache_get_power0(base, i - 1));
  807. GC_RETAIN(big2str_power_cache[base - 2][i]);
  808. }
  809. return big2str_power_cache[base - 2][i];
  810. }
  811. static VALUE
  812. power_cache_get_power(int base, long n1, long* m1)
  813. {
  814. int i, m;
  815. long j;
  816. VALUE t;
  817. if (n1 <= KARATSUBA_DIGITS)
  818. rb_bug("n1 > KARATSUBA_DIGITS");
  819. m = ceil_log2(n1);
  820. if (m1) *m1 = 1 << m;
  821. i = m - LOG2_KARATSUBA_DIGITS;
  822. if (i >= MAX_BIG2STR_TABLE_ENTRIES)
  823. i = MAX_BIG2STR_TABLE_ENTRIES - 1;
  824. t = power_cache_get_power0(base, i);
  825. j = KARATSUBA_DIGITS*(1 << i);
  826. while (n1 > j) {
  827. t = bigsqr(t);
  828. j *= 2;
  829. }
  830. return t;
  831. }
  832. /* big2str_muraken_find_n1
  833. *
  834. * Let a natural number x is given by:
  835. * x = 2^0 * x_0 + 2^1 * x_1 + ... + 2^(B*n_0 - 1) * x_{B*n_0 - 1},
  836. * where B is BITSPERDIG (i.e. BDIGITS*CHAR_BIT) and n_0 is
  837. * RBIGNUM_LEN(x).
  838. *
  839. * Now, we assume n_1 = min_n \{ n | 2^(B*n_0/2) <= b_1^(n_1) \}, so
  840. * it is realized that 2^(B*n_0) <= {b_1}^{2*n_1}, where b_1 is a
  841. * given radix number. And then, we have n_1 <= (B*n_0) /
  842. * (2*log_2(b_1)), therefore n_1 is given by ceil((B*n_0) /
  843. * (2*log_2(b_1))).
  844. */
  845. static long
  846. big2str_find_n1(VALUE x, int base)
  847. {
  848. static const double log_2[] = {
  849. 1.0, 1.58496250072116, 2.0,
  850. 2.32192809488736, 2.58496250072116, 2.8073549220576,
  851. 3.0, 3.16992500144231, 3.32192809488736,
  852. 3.4594316186373, 3.58496250072116, 3.70043971814109,
  853. 3.8073549220576, 3.90689059560852, 4.0,
  854. 4.08746284125034, 4.16992500144231, 4.24792751344359,
  855. 4.32192809488736, 4.39231742277876, 4.4594316186373,
  856. 4.52356195605701, 4.58496250072116, 4.64385618977472,
  857. 4.70043971814109, 4.75488750216347, 4.8073549220576,
  858. 4.85798099512757, 4.90689059560852, 4.95419631038688,
  859. 5.0, 5.04439411935845, 5.08746284125034,
  860. 5.12928301694497, 5.16992500144231
  861. };
  862. long bits;
  863. if (base < 2 || 36 < base)
  864. rb_bug("invalid radix %d", base);
  865. if (FIXNUM_P(x)) {
  866. bits = (SIZEOF_LONG*CHAR_BIT - 1)/2 + 1;
  867. }
  868. else if (BIGZEROP(x)) {
  869. return 0;
  870. }
  871. else if (RBIGNUM_LEN(x) >= LONG_MAX/BITSPERDIG) {
  872. rb_raise(rb_eRangeError, "bignum too big to convert into `string'");
  873. }
  874. else {
  875. bits = BITSPERDIG*RBIGNUM_LEN(x);
  876. }
  877. return (long)ceil(bits/log_2[base - 2]);
  878. }
  879. static long
  880. big2str_orig(VALUE x, int base, char* ptr, long len, long hbase, int trim)
  881. {
  882. long i = RBIGNUM_LEN(x), j = len;
  883. BDIGIT* ds = BDIGITS(x);
  884. while (i && j > 0) {
  885. long k = i;
  886. BDIGIT_DBL num = 0;
  887. while (k--) { /* x / hbase */
  888. num = BIGUP(num) + ds[k];
  889. ds[k] = (BDIGIT)(num / hbase);
  890. num %= hbase;
  891. }
  892. if (trim && ds[i-1] == 0) i--;
  893. #if defined(__LP64__) && (MAC_OS_X_VERSION_MAX_ALLOWED >= 1060)
  894. k = SIZEOF_BDIGITS/2;
  895. #else
  896. k = SIZEOF_BDIGITS;
  897. #endif
  898. while (k--) {
  899. ptr[--j] = ruby_digitmap[num % base];
  900. num /= base;
  901. if (j <= 0) break;
  902. if (trim && i == 0 && num == 0) break;
  903. }
  904. }
  905. if (trim) {
  906. while (j < len && ptr[j] == '0') j++;
  907. MEMMOVE(ptr, ptr + j, char, len - j);
  908. len -= j;
  909. }
  910. return len;
  911. }
  912. static long
  913. big2str_karatsuba(VALUE x, int base, char* ptr,
  914. long n1, long len, long hbase, int trim)
  915. {
  916. long lh, ll, m1;
  917. VALUE b, q, r;
  918. if (FIXNUM_P(x)) {
  919. VALUE str = rb_fix2str(x, base);
  920. const char* str_ptr = RSTRING_PTR(str);
  921. long str_len = RSTRING_LEN(str);
  922. if (trim) {
  923. if (FIX2INT(x) == 0) return 0;
  924. MEMCPY(ptr, str_ptr, char, str_len);
  925. return str_len;
  926. }
  927. else {
  928. memset(ptr, '0', len - str_len);
  929. MEMCPY(ptr + len - str_len, str_ptr, char, str_len);
  930. return len;
  931. }
  932. }
  933. if (BIGZEROP(x)) {
  934. if (trim) return 0;
  935. else {
  936. memset(ptr, '0', len);
  937. return len;
  938. }
  939. }
  940. if (n1 <= KARATSUBA_DIGITS) {
  941. return big2str_orig(x, base, ptr, len, hbase, trim);
  942. }
  943. b = power_cache_get_power(base, n1, &m1);
  944. bigdivmod(x, b, &q, &r);
  945. lh = big2str_karatsuba(q, base, ptr, (len - m1)/2,
  946. len - m1, hbase, trim);
  947. rb_big_resize(q, 0);
  948. ll = big2str_karatsuba(r, base, ptr + lh, m1/2,
  949. m1, hbase, !lh && trim);
  950. rb_big_resize(r, 0);
  951. return lh + ll;
  952. }
  953. VALUE
  954. rb_big2str0(VALUE x, int base, int trim)
  955. {
  956. int off;
  957. VALUE xx;
  958. long n1, n2, len, hbase;
  959. char* ptr;
  960. if (FIXNUM_P(x)) {
  961. return rb_fix2str(x, base);
  962. }
  963. if (BIGZEROP(x)) {
  964. return rb_usascii_str_new2("0");
  965. }
  966. if (base < 2 || 36 < base)
  967. rb_raise(rb_eArgError, "invalid radix %d", base);
  968. n2 = big2str_find_n1(x, base);
  969. n1 = (n2 + 1) / 2;
  970. ptr = (char *)alloca(n2 + 1); /* plus one for sign */
  971. ptr[0] = RBIGNUM_SIGN(x) ? '+' : '-';
  972. hbase = base*base;
  973. #if SIZEOF_BDIGITS > 2
  974. hbase *= hbase;
  975. #endif
  976. off = !(trim && RBIGNUM_SIGN(x)); /* erase plus sign if trim */
  977. xx = rb_big_clone(x);
  978. RBIGNUM_SET_SIGN(xx, 1);
  979. if (n1 <= KARATSUBA_DIGITS) {
  980. len = off + big2str_orig(xx, base, ptr + off, n2, hbase, trim);
  981. }
  982. else {
  983. len = off + big2str_karatsuba(xx, base, ptr + off, n1,
  984. n2, hbase, trim);
  985. }
  986. rb_big_resize(xx, 0);
  987. ptr[len] = '\0';
  988. return rb_usascii_str_new2(ptr);
  989. }
  990. VALUE
  991. rb_big2str(VALUE x, int base)
  992. {
  993. return rb_big2str0(x, base, 1);
  994. }
  995. /*
  996. * call-seq:
  997. * big.to_s(base=10) -> string
  998. *
  999. * Returns a string containing the representation of <i>big</i> radix
  1000. * <i>base</i> (2 through 36).
  1001. *
  1002. * 12345654321.to_s #=> "12345654321"
  1003. * 12345654321.to_s(2) #=> "1011011111110110111011110000110001"
  1004. * 12345654321.to_s(8) #=> "133766736061"
  1005. * 12345654321.to_s(16) #=> "2dfdbbc31"
  1006. * 78546939656932.to_s(36) #=> "rubyrules"
  1007. */
  1008. static VALUE
  1009. rb_big_to_s(VALUE x, SEL sel, int argc, VALUE *argv)
  1010. {
  1011. int base;
  1012. if (argc == 0) base = 10;
  1013. else {
  1014. VALUE b;
  1015. rb_scan_args(argc, argv, "01", &b);
  1016. base = NUM2INT(b);
  1017. }
  1018. return rb_big2str(x, base);
  1019. }
  1020. static VALUE
  1021. big2ulong(VALUE x, const char *type, int check)
  1022. {
  1023. long len = RBIGNUM_LEN(x);
  1024. BDIGIT_DBL num;
  1025. BDIGIT *ds;
  1026. if (len > DIGSPERLONG) {
  1027. if (check)
  1028. rb_raise(rb_eRangeError, "bignum too big to convert into `%s'", type);
  1029. len = DIGSPERLONG;
  1030. }
  1031. ds = BDIGITS(x);
  1032. num = 0;
  1033. while (len--) {
  1034. num = BIGUP(num);
  1035. num += ds[len];
  1036. }
  1037. return (VALUE)num;
  1038. }
  1039. VALUE
  1040. rb_big2ulong_pack(VALUE x)
  1041. {
  1042. VALUE num = big2ulong(x, "unsigned long", FALSE);
  1043. if (!RBIGNUM_SIGN(x)) {
  1044. return (VALUE)(-(SIGNED_VALUE)num);
  1045. }
  1046. return num;
  1047. }
  1048. VALUE
  1049. rb_big2ulong(VALUE x)
  1050. {
  1051. VALUE num = big2ulong(x, "unsigned long", TRUE);
  1052. if (!RBIGNUM_SIGN(x)) {
  1053. if ((SIGNED_VALUE)num < 0) {
  1054. rb_raise(rb_eRangeError, "bignum out of range of unsigned long");
  1055. }
  1056. return (VALUE)(-(SIGNED_VALUE)num);
  1057. }
  1058. return num;
  1059. }
  1060. SIGNED_VALUE
  1061. rb_big2long(VALUE x)
  1062. {
  1063. VALUE num = big2ulong(x, "long", TRUE);
  1064. if ((SIGNED_VALUE)num < 0 &&
  1065. (RBIGNUM_SIGN(x) || (SIGNED_VALUE)num != LONG_MIN)) {
  1066. rb_raise(rb_eRangeError, "bignum too big to convert into `long'");
  1067. }
  1068. if (!RBIGNUM_SIGN(x)) return -(SIGNED_VALUE)num;
  1069. return num;
  1070. }
  1071. #if HAVE_LONG_LONG
  1072. static unsigned LONG_LONG
  1073. big2ull(VALUE x, const char *type)
  1074. {
  1075. long len = RBIGNUM_LEN(x);
  1076. BDIGIT_DBL num;
  1077. BDIGIT *ds;
  1078. if (len > SIZEOF_LONG_LONG/SIZEOF_BDIGITS)
  1079. rb_raise(rb_eRangeError, "bignum too big to convert into `%s'", type);
  1080. ds = BDIGITS(x);
  1081. num = 0;
  1082. while (len--) {
  1083. num = BIGUP(num);
  1084. num += ds[len];
  1085. }
  1086. return num;
  1087. }
  1088. unsigned LONG_LONG
  1089. rb_big2ull(VALUE x)
  1090. {
  1091. unsigned LONG_LONG num = big2ull(x, "unsigned long long");
  1092. if (!RBIGNUM_SIGN(x)) return -num;
  1093. return num;
  1094. }
  1095. LONG_LONG
  1096. rb_big2ll(VALUE x)
  1097. {
  1098. unsigned LONG_LONG num = big2ull(x, "long long");
  1099. // This check is disabled because this function might be called from
  1100. // compiler stubs which will pass negative values as long long times
  1101. // for certain Cocoa APIs (generally fixed values like -1 or -2).
  1102. #if 0
  1103. if ((LONG_LONG)num < 0 && (RBIGNUM_SIGN(x)
  1104. || (LONG_LONG)num != LLONG_MIN)) {
  1105. rb_raise(rb_eRangeError, "bignum too big to convert into `long long'");
  1106. }
  1107. #endif
  1108. if (!RBIGNUM_SIGN(x)) return -(LONG_LONG)num;
  1109. return num;
  1110. }
  1111. #endif /* HAVE_LONG_LONG */
  1112. static VALUE
  1113. dbl2big(double d)
  1114. {
  1115. long i = 0;
  1116. BDIGIT c;
  1117. BDIGIT *digits;
  1118. VALUE z;
  1119. double u = (d < 0)?-d:d;
  1120. if (isinf(d)) {
  1121. rb_raise(rb_eFloatDomainError, d < 0 ? "-Infinity" : "Infinity");
  1122. }
  1123. if (isnan(d)) {
  1124. rb_raise(rb_eFloatDomainError, "NaN");
  1125. }
  1126. while (!POSFIXABLE(u) || 0 != (long)u) {
  1127. u /= (double)(BIGRAD);
  1128. i++;
  1129. }
  1130. z = bignew(i, d>=0);
  1131. digits = BDIGITS(z);
  1132. while (i--) {
  1133. u *= BIGRAD;
  1134. c = (BDIGIT)u;
  1135. u -= c;
  1136. digits[i] = c;
  1137. }
  1138. return z;
  1139. }
  1140. VALUE
  1141. rb_dbl2big(double d)
  1142. {
  1143. return bignorm(dbl2big(d));
  1144. }
  1145. static int
  1146. nlz(BDIGIT x)
  1147. {
  1148. BDIGIT y;
  1149. int n = BITSPERDIG;
  1150. #if BITSPERDIG > 64
  1151. y = x >> 64; if (y) {n -= 64; x = y;}
  1152. #endif
  1153. #if BITSPERDIG > 32
  1154. y = x >> 32; if (y) {n -= 32; x = y;}
  1155. #endif
  1156. #if BITSPERDIG > 16
  1157. y = x >> 16; if (y) {n -= 16; x = y;}
  1158. #endif
  1159. y = x >> 8; if (y) {n -= 8; x = y;}
  1160. y = x >> 4; if (y) {n -= 4; x = y;}
  1161. y = x >> 2; if (y) {n -= 2; x = y;}
  1162. y = x >> 1; if (y) {return n - 2;}
  1163. return n - x;
  1164. }
  1165. static double
  1166. big2dbl(VALUE x)
  1167. {
  1168. double d = 0.0;
  1169. long i = (bigtrunc(x), RBIGNUM_LEN(x)), lo = 0, bits;
  1170. BDIGIT *ds = BDIGITS(x), dl;
  1171. if (i) {
  1172. bits = i * BITSPERDIG - nlz(ds[i-1]);
  1173. if (bits > DBL_MANT_DIG+DBL_MAX_EXP) {
  1174. d = HUGE_VAL;
  1175. }
  1176. else {
  1177. if (bits > DBL_MANT_DIG+1)
  1178. lo = (bits -= DBL_MANT_DIG+1) / BITSPERDIG;
  1179. else
  1180. bits = 0;
  1181. while (--i > lo) {
  1182. d = ds[i] + BIGRAD*d;
  1183. }
  1184. dl = ds[i];
  1185. if (bits && (dl & (1UL << (bits %= BITSPERDIG)))) {
  1186. int carry = dl & ~(~(BDIGIT)0 << bits);
  1187. if (!carry) {
  1188. while (i-- > 0) {
  1189. if ((carry = ds[i]) != 0) break;
  1190. }
  1191. }
  1192. if (carry) {
  1193. dl &= (BDIGIT)~0 << bits;
  1194. dl += (BDIGIT)1 << bits;
  1195. if (!dl) d += 1;
  1196. }
  1197. }
  1198. d = dl + BIGRAD*d;
  1199. if (lo) {
  1200. if (lo > INT_MAX / BITSPERDIG)
  1201. d = HUGE_VAL;
  1202. else if (lo < INT_MIN / BITSPERDIG)
  1203. d = 0.0;
  1204. else
  1205. d = ldexp(d, (int)(lo * BITSPERDIG));
  1206. }
  1207. }
  1208. }
  1209. if (!RBIGNUM_SIGN(x)) d = -d;
  1210. return d;
  1211. }
  1212. double
  1213. rb_big2dbl(VALUE x)
  1214. {
  1215. double d = big2dbl(x);
  1216. if (isinf(d)) {
  1217. rb_warning("Bignum out of Float range");
  1218. if (d < 0.0)
  1219. d = -HUGE_VAL;
  1220. else
  1221. d = HUGE_VAL;
  1222. }
  1223. return d;
  1224. }
  1225. /*
  1226. * call-seq:
  1227. * big.to_f -> float
  1228. *
  1229. * Converts <i>big</i> to a <code>Float</code>. If <i>big</i> doesn't
  1230. * fit in a <code>Float</code>, the result is infinity.
  1231. *
  1232. */
  1233. static VALUE
  1234. rb_big_to_f(VALUE x, SEL sel)
  1235. {
  1236. return DBL2NUM(rb_big2dbl(x));
  1237. }
  1238. /*
  1239. * call-seq:
  1240. * big <=> numeric -> -1, 0, +1 or nil
  1241. *
  1242. * Comparison---Returns -1, 0, or +1 depending on whether <i>big</i> is
  1243. * less than, equal to, or greater than <i>numeric</i>. This is the
  1244. * basis for the tests in <code>Comparable</code>.
  1245. *
  1246. */
  1247. VALUE
  1248. rb_big_cmp(VALUE x, VALUE y)
  1249. {
  1250. long xlen = RBIGNUM_LEN(x);
  1251. BDIGIT *xds, *yds;
  1252. switch (TYPE(y)) {
  1253. case T_FIXNUM:
  1254. y = rb_int2big(FIX2LONG(y));
  1255. break;
  1256. case T_BIGNUM:
  1257. break;
  1258. case T_FLOAT:
  1259. {
  1260. double a = RFLOAT_VALUE(y);
  1261. if (isinf(a)) {
  1262. if (a > 0.0) return INT2FIX(-1);
  1263. else return INT2FIX(1);
  1264. }
  1265. return rb_dbl_cmp(rb_big2dbl(x), a);
  1266. }
  1267. default:
  1268. return rb_num_coerce_cmp(x, y, rb_intern("<=>"));
  1269. }
  1270. if (RBIGNUM_SIGN(x) > RBIGNUM_SIGN(y)) return INT2FIX(1);
  1271. if (RBIGNUM_SIGN(x) < RBIGNUM_SIGN(y)) return INT2FIX(-1);
  1272. if (xlen < RBIGNUM_LEN(y))
  1273. return (RBIGNUM_SIGN(x)) ? INT2FIX(-1) : INT2FIX(1);
  1274. if (xlen > RBIGNUM_LEN(y))
  1275. return (RBIGNUM_SIGN(x)) ? INT2FIX(1) : INT2FIX(-1);
  1276. xds = BDIGITS(x);
  1277. yds = BDIGITS(y);
  1278. while(xlen-- && (xds[xlen]==yds[xlen]));
  1279. if (-1 == xlen) return INT2FIX(0);
  1280. return (xds[xlen] > yds[xlen]) ?
  1281. (RBIGNUM_SIGN(x) ? INT2FIX(1) : INT2FIX(-1)) :
  1282. (RBIGNUM_SIGN(x) ? INT2FIX(-1) : INT2FIX(1));
  1283. }
  1284. static VALUE
  1285. rb_big_cmp_imp(VALUE x, SEL sel, VALUE y)
  1286. {
  1287. return rb_big_cmp(x, y);
  1288. }
  1289. static VALUE
  1290. big_op(VALUE x, VALUE y, int op)
  1291. {
  1292. VALUE rel;
  1293. int n;
  1294. switch (TYPE(y)) {
  1295. case T_FIXNUM:
  1296. case T_BIGNUM:
  1297. rel = rb_big_cmp(x, y);
  1298. break;
  1299. case T_FLOAT:
  1300. {
  1301. double a = RFLOAT_VALUE(y);
  1302. if (isinf(a)) {
  1303. if (a > 0.0) rel = INT2FIX(-1);
  1304. else rel = INT2FIX(1);
  1305. break;
  1306. }
  1307. rel = rb_dbl_cmp(rb_big2dbl(x), a);
  1308. break;
  1309. }
  1310. default:
  1311. {
  1312. ID id = 0;
  1313. switch (op) {
  1314. case 0: id = '>'; break;
  1315. case 1: id = rb_intern(">="); break;
  1316. case 2: id = '<'; break;
  1317. case 3: id = rb_intern("<="); break;
  1318. }
  1319. return rb_num_coerce_relop(x, y, id);
  1320. }
  1321. }
  1322. if (NIL_P(rel)) return Qfalse;
  1323. n = FIX2INT(rel);
  1324. switch (op) {
  1325. case 0: return n > 0 ? Qtrue : Qfalse;
  1326. case 1: return n >= 0 ? Qtrue : Qfalse;
  1327. case 2: return n < 0 ? Qtrue : Qfalse;
  1328. case 3: return n <= 0 ? Qtrue : Qfalse;
  1329. }
  1330. return Qundef;
  1331. }
  1332. /*
  1333. * call-seq:
  1334. * big > real -> true or false
  1335. *
  1336. * Returns <code>true</code> if the value of <code>big</code> is
  1337. * greater than that of <code>real</code>.
  1338. */
  1339. static VALUE
  1340. big_gt(VALUE x, SEL sel, VALUE y)
  1341. {
  1342. return big_op(x, y, 0);
  1343. }
  1344. /*
  1345. * call-seq:
  1346. * big >= real -> true or false
  1347. *
  1348. * Returns <code>true</code> if the value of <code>big</code> is
  1349. * greater than or equal to that of <code>real</code>.
  1350. */
  1351. static VALUE
  1352. big_ge(VALUE x, SEL sel, VALUE y)
  1353. {
  1354. return big_op(x, y, 1);
  1355. }
  1356. /*
  1357. * call-seq:
  1358. * big < real -> true or false
  1359. *
  1360. * Returns <code>true</code> if the value of <code>big</code> is
  1361. * less than that of <code>real</code>.
  1362. */
  1363. static VALUE
  1364. big_lt(VALUE x, SEL sel, VALUE y)
  1365. {
  1366. return big_op(x, y, 2);
  1367. }
  1368. /*
  1369. * call-seq:
  1370. * big <= real -> true or false
  1371. *
  1372. * Returns <code>true</code> if the value of <code>big</code> is
  1373. * less than or equal to that of <code>real</code>.
  1374. */
  1375. static VALUE
  1376. big_le(VALUE x, SEL sel, VALUE y)
  1377. {
  1378. return big_op(x, y, 3);
  1379. }
  1380. /*
  1381. * call-seq:
  1382. * big == obj -> true or false
  1383. *
  1384. * Returns <code>true</code> only if <i>obj</i> has the same value
  1385. * as <i>big</i>. Contrast this with <code>Bignum#eql?</code>, which
  1386. * requires <i>obj</i> to be a <code>Bignum</code>.
  1387. *
  1388. * 68719476736 == 68719476736.0 #=> true
  1389. */
  1390. VALUE
  1391. rb_big_eq_imp(VALUE x, SEL sel, VALUE y)
  1392. {
  1393. return rb_big_eq(x, y);
  1394. }
  1395. VALUE
  1396. rb_big_eq(VALUE x, VALUE y)
  1397. {
  1398. switch (TYPE(y)) {
  1399. case T_FIXNUM:
  1400. y = rb_int2big(FIX2LONG(y));
  1401. break;
  1402. case T_BIGNUM:
  1403. break;
  1404. case T_FLOAT:
  1405. {
  1406. volatile double a, b;
  1407. a = RFLOAT_VALUE(y);
  1408. if (isnan(a)) return Qfalse;
  1409. b = rb_big2dbl(x);
  1410. return (a == b)?Qtrue:Qfalse;
  1411. }
  1412. default:
  1413. return rb_equal(y, x);
  1414. }
  1415. if (RBIGNUM_SIGN(x) != RBIGNUM_SIGN(y)) return Qfalse;
  1416. if (RBIGNUM_LEN(x) != RBIGNUM_LEN(y)) return Qfalse;
  1417. if (MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,RBIGNUM_LEN(y)) != 0) return Qfalse;
  1418. return Qtrue;
  1419. }
  1420. /*
  1421. * call-seq:
  1422. * big.eql?(obj) -> true or false
  1423. *
  1424. * Returns <code>true</code> only if <i>obj</i> is a
  1425. * <code>Bignum</code> with the same value as <i>big</i>. Contrast this
  1426. * with <code>Bignum#==</code>, which performs type conversions.
  1427. *
  1428. * 68719476736.eql?(68719476736.0) #=> false
  1429. */
  1430. static VALUE
  1431. rb_big_eql(VALUE x, SEL sel, VALUE y)
  1432. {
  1433. if (TYPE(y) != T_BIGNUM) return Qfalse;
  1434. if (RBIGNUM_SIGN(x) != RBIGNUM_SIGN(y)) return Qfalse;
  1435. if (RBIGNUM_LEN(x) != RBIGNUM_LEN(y)) return Qfalse;
  1436. if (MEMCMP(BDIGITS(x),BDIGITS(y),BDIGIT,RBIGNUM_LEN(y)) != 0) return Qfalse;
  1437. return Qtrue;
  1438. }
  1439. /*
  1440. * call-seq:
  1441. * -big -> integer
  1442. *
  1443. * Unary minus (returns an integer whose value is 0-big)
  1444. */
  1445. VALUE
  1446. rb_big_uminus(VALUE x)
  1447. {
  1448. VALUE z = rb_big_clone(x);
  1449. RBIGNUM_SET_SIGN(z, !RBIGNUM_SIGN(x));
  1450. return bignorm(z);
  1451. }
  1452. static VALUE
  1453. rb_big_uminus_imp(VALUE x, SEL sel)
  1454. {
  1455. return rb_big_uminus(x);
  1456. }
  1457. /*
  1458. * call-seq:
  1459. * ~big -> integer
  1460. *
  1461. * Inverts the bits in big. As Bignums are conceptually infinite
  1462. * length, the result acts as if it had an infinite number of one
  1463. * bits to the left. In hex representations, this is displayed
  1464. * as two periods to the left of the digits.
  1465. *
  1466. * sprintf("%X", ~0x1122334455) #=> "..FEEDDCCBBAA"
  1467. */
  1468. static VALUE
  1469. rb_big_neg(VALUE x, SEL sel)
  1470. {
  1471. VALUE z = rb_big_clone(x);
  1472. BDIGIT *ds;
  1473. long i;
  1474. if (!RBIGNUM_SIGN(x)) get2comp(z);
  1475. ds = BDIGITS(z);
  1476. i = RBIGNUM_LEN(x);
  1477. if (!i) return INT2FIX(~(SIGNED_VALUE)0);
  1478. while (i--) {
  1479. ds[i] = ~ds[i];
  1480. }
  1481. RBIGNUM_SET_SIGN(z, !RBIGNUM_SIGN(z));
  1482. if (RBIGNUM_SIGN(x)) get2comp(z);
  1483. return bignorm(z);
  1484. }
  1485. static void
  1486. bigsub_core(BDIGIT *xds, long xn, BDIGIT *yds, long yn, BDIGIT *zds, long zn)
  1487. {
  1488. BDIGIT_DBL_SIGNED num;
  1489. long i;
  1490. for (i = 0, num = 0; i < yn; i++) {
  1491. num += (BDIGIT_DBL_SIGNED)xds[i] - yds[i];
  1492. zds[i] = BIGLO(num);
  1493. num = BIGDN(num);
  1494. }
  1495. while (num && i < xn) {
  1496. num += xds[i];
  1497. zds[i++] = BIGLO(num);
  1498. num = BIGDN(num);
  1499. }
  1500. while (i < xn) {
  1501. zds[i] = xds[i];
  1502. i++;
  1503. }
  1504. assert(i <= zn);
  1505. while (i < zn) {
  1506. zds[i++] = 0;
  1507. }
  1508. }
  1509. static VALUE
  1510. bigsub(VALUE x, VALUE y)
  1511. {
  1512. VALUE z = 0;
  1513. long i = RBIGNUM_LEN(x);
  1514. BDIGIT *xds, *yds;
  1515. /* if x is larger than y, swap */
  1516. if (RBIGNUM_LEN(x) < RBIGNUM_LEN(y)) {
  1517. z = x; x = y; y = z; /* swap x y */
  1518. }
  1519. else if (RBIGNUM_LEN(x) == RBIGNUM_LEN(y)) {
  1520. xds = BDIGITS(x);
  1521. yds = BDIGITS(y);
  1522. while (i > 0) {
  1523. i--;
  1524. if (xds[i] > yds[i]) {
  1525. break;
  1526. }
  1527. if (xds[i] < yds[i]) {
  1528. z = x; x = y; y = z; /* swap x y */
  1529. break;
  1530. }
  1531. }
  1532. }
  1533. z = bignew(RBIGNUM_LEN(x), z==0);
  1534. bigsub_core(BDIGITS(x), RBIGNUM_LEN(x),
  1535. BDIGITS(y), RBIGNUM_LEN(y),
  1536. BDIGITS(z), RBIGNUM_LEN(z));
  1537. return z;
  1538. }
  1539. static VALUE bigadd_int(VALUE x, long y);
  1540. static VALUE
  1541. bigsub_int(VALUE x, long y0)
  1542. {
  1543. VALUE z;
  1544. BDIGIT *xds, *zds;
  1545. long xn;
  1546. BDIGIT_DBL_SIGNED num;
  1547. long i, y;
  1548. y = y0;
  1549. xds = BDIGITS(x);
  1550. xn = RBIGNUM_LEN(x);
  1551. z = bignew(xn, RBIGNUM_SIGN(x));
  1552. zds = BDIGITS(z);
  1553. #if SIZEOF_BDIGITS == SIZEOF_LONG
  1554. num = (BDIGIT_DBL_SIGNED)xds[0] - y;
  1555. if (xn == 1 && num < 0) {
  1556. RBIGNUM_SET_SIGN(z, !RBIGNUM_SIGN(x));
  1557. zds[0] = (BDIGIT)-num;
  1558. return bignorm(z);
  1559. }
  1560. zds[0] = BIGLO(num);
  1561. num = BIGDN(num);
  1562. i = 1;
  1563. #else
  1564. num = 0;
  1565. for (i=0; i<(int)(sizeof(y)/sizeof(BDIGIT)); i++) {
  1566. num += (BDIGIT_DBL_SIGNED)xds[i] - BIGLO(y);
  1567. zds[i] = BIGLO(num);
  1568. num = BIGDN(num);
  1569. y = BIGDN(y);
  1570. }
  1571. #endif
  1572. while (num && i < xn) {
  1573. num += xds[i];
  1574. zds[i++] = BIGLO(num);
  1575. num = BIGDN(num);
  1576. }
  1577. while (i < xn) {
  1578. zds[i] = xds[i];
  1579. i++;
  1580. }
  1581. if (num < 0) {
  1582. z = bigsub(x, rb_int2big(y0));
  1583. }
  1584. return bignorm(z);
  1585. }
  1586. static VALUE
  1587. bigadd_int(VALUE x, long y)
  1588. {
  1589. VALUE z;
  1590. BDIGIT *xds, *zds;
  1591. long xn, zn;
  1592. BDIGIT_DBL num;
  1593. long i;
  1594. xds = BDIGITS(x);
  1595. xn = RBIGNUM_LEN(x);
  1596. if (xn < 2) {
  1597. zn = 3;
  1598. }
  1599. else {
  1600. zn = xn + 1;
  1601. }
  1602. z = bignew(zn, RBIGNUM_SIGN(x));
  1603. zds = BDIGITS(z);
  1604. #if SIZEOF_BDIGITS == SIZEOF_LONG
  1605. num = (BDIGIT_DBL)xds[0] + y;
  1606. zds[0] = BIGLO(num);
  1607. num = BIGDN(num);
  1608. i = 1;
  1609. #else
  1610. num = 0;
  1611. for (i=0; i<(int)(sizeof(y)/sizeof(BDIGIT)); i++) {
  1612. num += (BDIGIT_DBL)xds[i] + BIGLO(y);
  1613. zds[i] = BIGLO(num);
  1614. num = BIGDN(num);
  1615. y = BIGDN(y);
  1616. }
  1617. #endif
  1618. while (num && i < xn) {
  1619. num += xds[i];
  1620. zds[i++] = BIGLO(num);
  1621. num = BIGDN(num);
  1622. }
  1623. if (num) zds[i++] = (BDIGIT)num;
  1624. else while (i < xn) {
  1625. zds[i] = xds[i];
  1626. i++;
  1627. }
  1628. assert(i <= zn);
  1629. while (i < zn) {
  1630. zds[i++] = 0;
  1631. }
  1632. return bignorm(z);
  1633. }
  1634. static void
  1635. bigadd_core(BDIGIT *xds, long xn, BDIGIT *yds, long yn, BDIGIT *zds, long zn)
  1636. {
  1637. BDIGIT_DBL num = 0;
  1638. long i;
  1639. if (xn > yn) {
  1640. BDIGIT *tds;
  1641. tds = xds; xds = yds; yds = tds;
  1642. i = xn; xn = yn; yn = i;
  1643. }
  1644. i = 0;
  1645. while (i < xn) {
  1646. num += (BDIGIT_DBL)xds[i] + yds[i];
  1647. zds[i++] = BIGLO(num);
  1648. num = BIGDN(num);
  1649. }
  1650. while (num && i < yn) {
  1651. num += yds[i];
  1652. zds[i++] = BIGLO(num);
  1653. num = BIGDN(num);
  1654. }
  1655. while (i < yn) {
  1656. zds[i] = yds[i];
  1657. i++;
  1658. }
  1659. if (num) zds[i++] = (BDIGIT)num;
  1660. assert(i <= zn);
  1661. while (i < zn) {
  1662. zds[i++] = 0;
  1663. }
  1664. }
  1665. static VALUE
  1666. bigadd(VALUE x, VALUE y, int sign)
  1667. {
  1668. VALUE z;
  1669. long len;
  1670. sign = (sign == RBIGNUM_SIGN(y));
  1671. if (RBIGNUM_SIGN(x) != sign) {
  1672. if (sign) return bigsub(y, x);
  1673. return bigsub(x, y);
  1674. }
  1675. if (RBIGNUM_LEN(x) > RBIGNUM_LEN(y)) {
  1676. len = RBIGNUM_LEN(x) + 1;
  1677. }
  1678. else {
  1679. len = RBIGNUM_LEN(y) + 1;
  1680. }
  1681. z = bignew(len, sign);
  1682. bigadd_core(BDIGITS(x), RBIGNUM_LEN(x),
  1683. BDIGITS(y), RBIGNUM_LEN(y),
  1684. BDIGITS(z), RBIGNUM_LEN(z));
  1685. return z;
  1686. }
  1687. /*
  1688. * call-seq:
  1689. * big + other -> Numeric
  1690. *
  1691. * Adds big and other, returning the result.
  1692. */
  1693. static VALUE
  1694. rb_big_plus_imp(VALUE x, SEL sel, VALUE y)
  1695. {
  1696. long n;
  1697. switch (TYPE(y)) {
  1698. case T_FIXNUM:
  1699. n = FIX2LONG(y);
  1700. if ((n > 0) != RBIGNUM_SIGN(x)) {
  1701. if (n < 0) {
  1702. n = -n;
  1703. }
  1704. return bigsub_int(x, n);
  1705. }
  1706. if (n < 0) {
  1707. n = -n;
  1708. }
  1709. return bigadd_int(x, n);
  1710. case T_BIGNUM:
  1711. return bignorm(bigadd(x, y, 1));
  1712. case T_FLOAT:
  1713. return DBL2NUM(rb_big2dbl(x) + RFLOAT_VALUE(y));
  1714. default:
  1715. return rb_num_coerce_bin(x, y, '+');
  1716. }
  1717. }
  1718. VALUE
  1719. rb_big_plus(VALUE x, VALUE y)
  1720. {
  1721. return rb_big_plus_imp(x, 0, y);
  1722. }
  1723. /*
  1724. * call-seq:
  1725. * big - other -> Numeric
  1726. *
  1727. * Subtracts other from big, returning the result.
  1728. */
  1729. VALUE
  1730. rb_big_minus(VALUE x, VALUE y)
  1731. {
  1732. long n;
  1733. switch (TYPE(y)) {
  1734. case T_FIXNUM:
  1735. n = FIX2LONG(y);
  1736. if ((n > 0) != RBIGNUM_SIGN(x)) {
  1737. if (n < 0) {
  1738. n = -n;
  1739. }
  1740. return bigadd_int(x, n);
  1741. }
  1742. if (n < 0) {
  1743. n = -n;
  1744. }
  1745. return bigsub_int(x, n);
  1746. case T_BIGNUM:
  1747. return bignorm(bigadd(x, y, 0));
  1748. case T_FLOAT:
  1749. return DBL2NUM(rb_big2dbl(x) - RFLOAT_VALUE(y));
  1750. default:
  1751. return rb_num_coerce_bin(x, y, '-');
  1752. }
  1753. }
  1754. static VALUE
  1755. rb_big_minus_imp(VALUE x, SEL sel, VALUE y)
  1756. {
  1757. return rb_big_minus(x, y);
  1758. }
  1759. static long
  1760. big_real_len(VALUE x)
  1761. {
  1762. long i = RBIGNUM_LEN(x);
  1763. BDIGIT *xds = BDIGITS(x);
  1764. while (--i && !xds[i]);
  1765. return i + 1;
  1766. }
  1767. static VALUE
  1768. bigmul1_single(VALUE x, VALUE y)
  1769. {
  1770. BDIGIT_DBL n;
  1771. VALUE z = bignew(2, RBIGNUM_SIGN(x)==RBIGNUM_SIGN(y));
  1772. BDIGIT *xds, *yds, *zds;
  1773. xds = BDIGITS(x);
  1774. yds = BDIGITS(y);
  1775. zds = BDIGITS(z);
  1776. n = (BDIGIT_DBL)xds[0] * yds[0];
  1777. zds[0] = BIGLO(n);
  1778. zds[1] = (BDIGIT)BIGDN(n);
  1779. return z;
  1780. }
  1781. static VALUE
  1782. bigmul1_normal(VALUE x, VALUE y)
  1783. {
  1784. long xl = RBIGNUM_LEN(x), yl = RBIGNUM_LEN(y), i, j = xl + yl + 1;
  1785. BDIGIT_DBL n = 0;
  1786. VALUE z = bignew(j, RBIGNUM_SIGN(x)==RBIGNUM_SIGN(y));
  1787. BDIGIT *xds, *yds, *zds;
  1788. xds = BDIGITS(x);
  1789. yds = BDIGITS(y);
  1790. zds = BDIGITS(z);
  1791. while (j--) zds[j] = 0;
  1792. for (i = 0; i < xl; i++) {
  1793. BDIGIT_DBL dd;
  1794. dd = xds[i];
  1795. if (dd == 0) continue;
  1796. n = 0;
  1797. for (j = 0; j < yl; j++) {
  1798. BDIGIT_DBL ee = n + (BDIGIT_DBL)dd * yds[j];
  1799. n = zds[i + j] + ee;
  1800. if (ee) zds[i + j] = BIGLO(n);
  1801. n = BIGDN(n);
  1802. }
  1803. if (n) {
  1804. zds[i + j] = (BDIGIT)n;
  1805. }
  1806. }
  1807. //rb_thread_check_ints();
  1808. return z;
  1809. }
  1810. static VALUE bigmul0(VALUE x, VALUE y);
  1811. /* balancing multiplication by slicing larger argument */
  1812. static VALUE
  1813. bigmul1_balance(VALUE x, VALUE y)
  1814. {
  1815. VALUE z, t1, t2;
  1816. long i, xn, yn, r, n;
  1817. BDIGIT *yds, *zds, *t1ds;
  1818. xn = RBIGNUM_LEN(x);
  1819. yn = RBIGNUM_LEN(y);
  1820. assert(2 * xn <= yn);
  1821. z = bignew(xn + yn, RBIGNUM_SIGN(x)==RBIGNUM_SIGN(y));
  1822. t1 = bignew(xn, 1);
  1823. yds = BDIGITS(y);
  1824. zds = BDIGITS(z);
  1825. t1ds = BDIGITS(t1);
  1826. for (i = 0; i < xn + yn; i++) zds[i] = 0;
  1827. n = 0;
  1828. while (yn > 0) {
  1829. r = xn > yn ? yn : xn;
  1830. MEMCPY(t1ds, yds + n, BDIGIT, r);
  1831. RBIGNUM_SET_LEN(t1, r);
  1832. t2 = bigmul0(x, t1);
  1833. bigadd_core(zds + n, RBIGNUM_LEN(z) - n,
  1834. BDIGITS(t2), big_real_len(t2),
  1835. zds + n, RBIGNUM_LEN(z) - n);
  1836. yn -= r;
  1837. n += r;
  1838. }
  1839. return z;
  1840. }
  1841. /* split a bignum into high and low bignums */
  1842. static void
  1843. big_split(VALUE v, long n, volatile VALUE *ph, volatile VALUE *pl)
  1844. {
  1845. long hn = 0, ln = RBIGNUM_LEN(v);
  1846. VALUE h, l;
  1847. BDIGIT *vds = BDIGITS(v);
  1848. if (ln > n) {
  1849. hn = ln - n;
  1850. ln = n;
  1851. }
  1852. while (--hn && !vds[hn + ln]);
  1853. h = bignew(hn += 2, 1);
  1854. MEMCPY(BDIGITS(h), vds + ln, BDIGIT, hn - 1);
  1855. BDIGITS(h)[hn - 1] = 0; /* margin for carry */
  1856. while (--ln && !vds[ln]);
  1857. l = bignew(ln += 2, 1);
  1858. MEMCPY(BDIGITS(l), vds, BDIGIT, ln - 1);
  1859. BDIGITS(l)[ln - 1] = 0; /* margin for carry */
  1860. *pl = l;
  1861. *ph = h;
  1862. }
  1863. /* multiplication by karatsuba method */
  1864. static VALUE
  1865. bigmul1_karatsuba(VALUE x, VALUE y)
  1866. {
  1867. long i, n, xn, yn, t1n, t2n;
  1868. VALUE xh, xl, yh, yl, z, t1, t2, t3;
  1869. BDIGIT *zds;
  1870. xn = RBIGNUM_LEN(x);
  1871. yn = RBIGNUM_LEN(y);
  1872. n = yn / 2;
  1873. big_split(x, n, &xh, &xl);
  1874. if (x == y) {
  1875. yh = xh; yl = xl;
  1876. }
  1877. else big_split(y, n, &yh, &yl);
  1878. /* x = xh * b + xl
  1879. * y = yh * b + yl
  1880. *
  1881. * Karatsuba method:
  1882. * x * y = z2 * b^2 + z1 * b + z0
  1883. * where
  1884. * z2 = xh * yh
  1885. * z0 = xl * yl
  1886. * z1 = (xh + xl) * (yh + yl) - z2 - z0
  1887. *
  1888. * ref: http://en.wikipedia.org/wiki/Karatsuba_algorithm
  1889. */
  1890. /* allocate a result bignum */
  1891. z = bignew(xn + yn, RBIGNUM_SIGN(x)==RBIGNUM_SIGN(y));
  1892. zds = BDIGITS(z);
  1893. /* t1 <- xh * yh */
  1894. t1 = bigmul0(xh, yh);
  1895. t1n = big_real_len(t1);
  1896. /* copy t1 into high bytes of the result (z2) */
  1897. MEMCPY(zds + 2 * n, BDIGITS(t1), BDIGIT, t1n);
  1898. for (i = 2 * n + t1n; i < xn + yn; i++) zds[i] = 0;
  1899. if (!BIGZEROP(xl) && !BIGZEROP(yl)) {
  1900. /* t2 <- xl * yl */
  1901. t2 = bigmul0(xl, yl);
  1902. t2n = big_real_len(t2);
  1903. /* copy t2 into low bytes of the result (z0) */
  1904. MEMCPY(zds, BDIGITS(t2), BDIGIT, t2n);
  1905. for (i = t2n; i < 2 * n; i++) zds[i] = 0;
  1906. }
  1907. else {
  1908. t2 = Qundef;
  1909. t2n = 0;
  1910. /* copy 0 into low bytes of the result (z0) */
  1911. for (i = 0; i < 2 * n; i++) zds[i] = 0;
  1912. }
  1913. /* xh <- xh + xl */
  1914. if (RBIGNUM_LEN(xl) > RBIGNUM_LEN(xh)) {
  1915. t3 = xl; xl = xh; xh = t3;
  1916. }
  1917. /* xh has a margin for carry */
  1918. bigadd_core(BDIGITS(xh), RBIGNUM_LEN(xh),
  1919. BDIGITS(xl), RBIGNUM_LEN(xl),
  1920. BDIGITS(xh), RBIGNUM_LEN(xh));
  1921. /* yh <- yh + yl */
  1922. if (x != y) {
  1923. if (RBIGNUM_LEN(yl) > RBIGNUM_LEN(yh)) {
  1924. t3 = yl; yl = yh; yh = t3;
  1925. }
  1926. /* yh has a margin for carry */
  1927. bigadd_core(BDIGITS(yh), RBIGNUM_LEN(yh),
  1928. BDIGITS(yl), RBIGNUM_LEN(yl),
  1929. BDIGITS(yh), RBIGNUM_LEN(yh));
  1930. }
  1931. else yh = xh;
  1932. /* t3 <- xh * yh */
  1933. t3 = bigmul0(xh, yh);
  1934. i = xn + yn - n;
  1935. /* subtract t1 from t3 */
  1936. bigsub_core(BDIGITS(t3), big_real_len(t3), BDIGITS(t1), t1n, BDIGITS(t3), big_real_len(t3));
  1937. /* subtract t2 from t3; t3 is now the middle term of the product */
  1938. if (t2 != Qundef) bigsub_core(BDIGITS(t3), big_real_len(t3), BDIGITS(t2), t2n, BDIGITS(t3), big_real_len(t3));
  1939. /* add t3 to middle bytes of the result (z1) */
  1940. bigadd_core(zds + n, i, BDIGITS(t3), big_real_len(t3), zds + n, i);
  1941. return z;
  1942. }
  1943. /* efficient squaring (2 times faster than normal multiplication)
  1944. * ref: Handbook of Applied Cryptography, Algorithm 14.16
  1945. * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
  1946. */
  1947. static VALUE
  1948. bigsqr_fast(VALUE x)
  1949. {
  1950. long len = RBIGNUM_LEN(x), i, j;
  1951. VALUE z = bignew(2 * len + 1, 1);
  1952. BDIGIT *xds = BDIGITS(x), *zds = BDIGITS(z);
  1953. BDIGIT_DBL c, v, w;
  1954. for (i = 2 * len + 1; i--; ) zds[i] = 0;
  1955. for (i = 0; i < len; i++) {
  1956. v = (BDIGIT_DBL)xds[i];
  1957. if (!v) continue;
  1958. c = (BDIGIT_DBL)zds[i + i] + v * v;
  1959. zds[i + i] = BIGLO(c);
  1960. c = BIGDN(c);
  1961. v *= 2;
  1962. for (j = i + 1; j < len; j++) {
  1963. w = (BDIGIT_DBL)xds[j];
  1964. c += (BDIGIT_DBL)zds[i + j] + BIGLO(v) * w;
  1965. zds[i + j] = BIGLO(c);
  1966. c = BIGDN(c);
  1967. if (BIGDN(v)) c += w;
  1968. }
  1969. if (c) {
  1970. c += (BDIGIT_DBL)zds[i + len];
  1971. zds[i + len] = BIGLO(c);
  1972. c = BIGDN(c);
  1973. }
  1974. if (c) zds[i + len + 1] += (BDIGIT)c;
  1975. }
  1976. return z;
  1977. }
  1978. #define KARATSUBA_MUL_DIGITS 70
  1979. /* determine whether a bignum is sparse or not by random sampling */
  1980. static inline VALUE
  1981. big_sparse_p(VALUE x)
  1982. {
  1983. long c = 0, n = RBIGNUM_LEN(x);
  1984. unsigned long rb_rand_internal(unsigned long i);
  1985. if ( BDIGITS(x)[rb_rand_internal(n / 2) + n / 4]) c++;
  1986. if (c <= 1 && BDIGITS(x)[rb_rand_internal(n / 2) + n / 4]) c++;
  1987. if (c <= 1 && BDIGITS(x)[rb_rand_internal(n / 2) + n / 4]) c++;
  1988. return (c <= 1) ? Qtrue : Qfalse;
  1989. }
  1990. #if 0
  1991. static void
  1992. dump_bignum(VALUE x)
  1993. {
  1994. long i;
  1995. printf("0x0");
  1996. for (i = RBIGNUM_LEN(x); i--; ) {
  1997. printf("_%08x", BDIGITS(x)[i]);
  1998. }
  1999. puts("");
  2000. }
  2001. #endif
  2002. static VALUE
  2003. bigmul0(VALUE x, VALUE y)
  2004. {
  2005. long xn, yn;
  2006. xn = RBIGNUM_LEN(x);
  2007. yn = RBIGNUM_LEN(y);
  2008. /* make sure that y is longer than x */
  2009. if (xn > yn) {
  2010. VALUE t;
  2011. long tn;
  2012. t = x; x = y; y = t;
  2013. tn = xn; xn = yn; yn = tn;
  2014. }
  2015. assert(xn <= yn);
  2016. /* normal multiplication when x is small */
  2017. if (xn < KARATSUBA_MUL_DIGITS) {
  2018. normal:
  2019. if (x == y) return bigsqr_fast(x);
  2020. if (xn == 1 && yn == 1) return bigmul1_single(x, y);
  2021. return bigmul1_normal(x, y);
  2022. }
  2023. /* normal multiplication when x or y is a sparse bignum */
  2024. if (big_sparse_p(x)) goto normal;
  2025. if (big_sparse_p(y)) return bigmul1_normal(y, x);
  2026. /* balance multiplication by slicing y when x is much smaller than y */
  2027. if (2 * xn <= yn) return bigmul1_balance(x, y);
  2028. /* multiplication by karatsuba method */
  2029. return bigmul1_karatsuba(x, y);
  2030. }
  2031. /*
  2032. * call-seq:
  2033. * big * other -> Numeric
  2034. *
  2035. * Multiplies big and other, returning the result.
  2036. */
  2037. VALUE
  2038. rb_big_mul(VALUE x, VALUE y)
  2039. {
  2040. switch (TYPE(y)) {
  2041. case T_FIXNUM:
  2042. y = rb_int2big(FIX2LONG(y));
  2043. break;
  2044. case T_BIGNUM:
  2045. break;
  2046. case T_FLOAT:
  2047. return DBL2NUM(rb_big2dbl(x) * RFLOAT_VALUE(y));
  2048. default:
  2049. return rb_num_coerce_bin(x, y, '*');
  2050. }
  2051. return bignorm(bigmul0(x, y));
  2052. }
  2053. static VALUE
  2054. rb_big_mul_imp(VALUE x, SEL sel, VALUE y)
  2055. {
  2056. return bignorm(rb_big_mul(x, y));
  2057. }
  2058. struct big_div_struct {
  2059. long nx, ny;
  2060. BDIGIT *yds, *zds;
  2061. VALUE stop;
  2062. };
  2063. static VALUE
  2064. bigdivrem1(void *ptr)
  2065. {
  2066. struct big_div_struct *bds = (struct big_div_struct*)ptr;
  2067. long nx = bds->nx, ny = bds->ny;
  2068. long i, j, nyzero;
  2069. BDIGIT *yds = bds->yds, *zds = bds->zds;
  2070. BDIGIT_DBL t2;
  2071. BDIGIT_DBL_SIGNED num;
  2072. BDIGIT q;
  2073. j = nx==ny?nx+1:nx;
  2074. for (nyzero = 0; !yds[nyzero]; nyzero++);
  2075. do {
  2076. if (bds->stop) return Qnil;
  2077. if (zds[j] == yds[ny-1]) q = (BDIGIT)BIGRAD-1;
  2078. else q = (BDIGIT)((BIGUP(zds[j]) + zds[j-1])/yds[ny-1]);
  2079. if (q) {
  2080. i = nyzero; num = 0; t2 = 0;
  2081. do { /* multiply and subtract */
  2082. BDIGIT_DBL ee;
  2083. t2 += (BDIGIT_DBL)yds[i] * q;
  2084. ee = num - BIGLO(t2);
  2085. num = (BDIGIT_DBL)zds[j - ny + i] + ee;
  2086. if (ee) zds[j - ny + i] = BIGLO(num);
  2087. num = BIGDN(num);
  2088. t2 = BIGDN(t2);
  2089. } while (++i < ny);
  2090. num += zds[j - ny + i] - t2;/* borrow from high digit; don't update */
  2091. while (num) { /* "add back" required */
  2092. i = 0; num = 0; q--;
  2093. do {
  2094. BDIGIT_DBL ee = num + yds[i];
  2095. num = (BDIGIT_DBL)zds[j - ny + i] + ee;
  2096. if (ee) zds[j - ny + i] = BIGLO(num);
  2097. num = BIGDN(num);
  2098. } while (++i < ny);
  2099. num--;
  2100. }
  2101. }
  2102. zds[j] = q;
  2103. } while (--j >= ny);
  2104. return Qnil;
  2105. }
  2106. #if 0
  2107. static void
  2108. rb_big_stop(void *ptr)
  2109. {
  2110. VALUE *stop = (VALUE*)ptr;
  2111. *stop = Qtrue;
  2112. }
  2113. #endif
  2114. static VALUE
  2115. bigdivrem(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp)
  2116. {
  2117. struct big_div_struct bds;
  2118. long nx = RBIGNUM_LEN(x), ny = RBIGNUM_LEN(y);
  2119. long i, j;
  2120. VALUE z, yy, zz;
  2121. BDIGIT *xds, *yds, *zds, *tds;
  2122. BDIGIT_DBL t2;
  2123. BDIGIT dd, q;
  2124. if (BIGZEROP(y)) rb_num_zerodiv();
  2125. xds = BDIGITS(x);
  2126. yds = BDIGITS(y);
  2127. if (nx < ny || (nx == ny && xds[nx - 1] < yds[ny - 1])) {
  2128. if (divp) *divp = rb_int2big(0);
  2129. if (modp) *modp = x;
  2130. return Qnil;
  2131. }
  2132. if (ny == 1) {
  2133. dd = yds[0];
  2134. z = rb_big_clone(x);
  2135. zds = BDIGITS(z);
  2136. t2 = 0; i = nx;
  2137. while (i--) {
  2138. t2 = BIGUP(t2) + zds[i];
  2139. zds[i] = (BDIGIT)(t2 / dd);
  2140. t2 %= dd;
  2141. }
  2142. RBIGNUM_SET_SIGN(z, RBIGNUM_SIGN(x)==RBIGNUM_SIGN(y));
  2143. if (modp) {
  2144. *modp = rb_uint2big((VALUE)t2);
  2145. RBIGNUM_SET_SIGN(*modp, RBIGNUM_SIGN(x));
  2146. }
  2147. if (divp) *divp = z;
  2148. return Qnil;
  2149. }
  2150. z = bignew(nx==ny?nx+2:nx+1, RBIGNUM_SIGN(x)==RBIGNUM_SIGN(y));
  2151. zds = BDIGITS(z);
  2152. if (nx==ny) zds[nx+1] = 0;
  2153. while (!yds[ny-1]) ny--;
  2154. dd = 0;
  2155. q = yds[ny-1];
  2156. while ((q & (BDIGIT)(1UL<<(BITSPERDIG-1))) == 0) {
  2157. q <<= 1UL;
  2158. dd++;
  2159. }
  2160. if (dd) {
  2161. yy = rb_big_clone(y);
  2162. tds = BDIGITS(yy);
  2163. j = 0;
  2164. t2 = 0;
  2165. while (j<ny) {
  2166. t2 += (BDIGIT_DBL)yds[j]<<dd;
  2167. tds[j++] = BIGLO(t2);
  2168. t2 = BIGDN(t2);
  2169. }
  2170. yds = tds;
  2171. j = 0;
  2172. t2 = 0;
  2173. while (j<nx) {
  2174. t2 += (BDIGIT_DBL)xds[j]<<dd;
  2175. zds[j++] = BIGLO(t2);
  2176. t2 = BIGDN(t2);
  2177. }
  2178. zds[j] = (BDIGIT)t2;
  2179. }
  2180. else {
  2181. zds[nx] = 0;
  2182. j = nx;
  2183. while (j--) zds[j] = xds[j];
  2184. }
  2185. bds.nx = nx;
  2186. bds.ny = ny;
  2187. bds.zds = zds;
  2188. bds.yds = yds;
  2189. bds.stop = Qfalse;
  2190. // if (nx > 10000 || ny > 10000) {
  2191. // rb_thread_blocking_region(bigdivrem1, &bds, rb_big_stop, &bds.stop);
  2192. // }
  2193. // else {
  2194. bigdivrem1(&bds);
  2195. // }
  2196. if (divp) { /* move quotient down in z */
  2197. *divp = zz = rb_big_clone(z);
  2198. zds = BDIGITS(zz);
  2199. j = (nx==ny ? nx+2 : nx+1) - ny;
  2200. for (i = 0;i < j;i++) zds[i] = zds[i+ny];
  2201. if (!zds[i-1]) i--;
  2202. RBIGNUM_SET_LEN(zz, i);
  2203. }
  2204. if (modp) { /* normalize remainder */
  2205. *modp = zz = rb_big_clone(z);
  2206. zds = BDIGITS(zz);
  2207. while (--ny && !zds[ny]); ++ny;
  2208. if (dd) {
  2209. t2 = 0; i = ny;
  2210. while(i--) {
  2211. t2 = (t2 | zds[i]) >> dd;
  2212. q = zds[i];
  2213. zds[i] = BIGLO(t2);
  2214. t2 = BIGUP(q);
  2215. }
  2216. }
  2217. if (!zds[ny-1]) ny--;
  2218. RBIGNUM_SET_LEN(zz, ny);
  2219. RBIGNUM_SET_SIGN(zz, RBIGNUM_SIGN(x));
  2220. }
  2221. return z;
  2222. }
  2223. static void
  2224. bigdivmod(VALUE x, VALUE y, volatile VALUE *divp, volatile VALUE *modp)
  2225. {
  2226. VALUE mod;
  2227. bigdivrem(x, y, divp, &mod);
  2228. if (RBIGNUM_SIGN(x) != RBIGNUM_SIGN(y) && !BIGZEROP(mod)) {
  2229. if (divp) *divp = bigadd(*divp, rb_int2big(1), 0);
  2230. if (modp) *modp = bigadd(mod, y, 1);
  2231. }
  2232. else {
  2233. if (divp) *divp = *divp;
  2234. if (modp) *modp = mod;
  2235. }
  2236. }
  2237. static VALUE
  2238. rb_big_divide(VALUE x, VALUE y, ID op)
  2239. {
  2240. VALUE z;
  2241. switch (TYPE(y)) {
  2242. case T_FIXNUM:
  2243. y = rb_int2big(FIX2LONG(y));
  2244. break;
  2245. case T_BIGNUM:
  2246. break;
  2247. case T_FLOAT:
  2248. {
  2249. double div = rb_big2dbl(x) / RFLOAT_VALUE(y);
  2250. if (op == '/') {
  2251. return DBL2NUM(div);
  2252. }
  2253. else {
  2254. return rb_dbl2big(div);
  2255. }
  2256. }
  2257. default:
  2258. return rb_num_coerce_bin(x, y, op);
  2259. }
  2260. bigdivmod(x, y, &z, 0);
  2261. return bignorm(z);
  2262. }
  2263. /*
  2264. * call-seq:
  2265. * big / other -> Numeric
  2266. *
  2267. * Performs division: the class of the resulting object depends on
  2268. * the class of <code>numeric</code> and on the magnitude of the
  2269. * result.
  2270. */
  2271. VALUE
  2272. rb_big_div_imp(VALUE x, SEL sel, VALUE y)
  2273. {
  2274. return rb_big_divide(x, y, '/');
  2275. }
  2276. VALUE
  2277. rb_big_div(VALUE x, VALUE y)
  2278. {
  2279. return rb_big_divide(x, y, '/');
  2280. }
  2281. /*
  2282. * call-seq:
  2283. * big.div(other) -> integer
  2284. *
  2285. * Performs integer division: returns integer value.
  2286. */
  2287. VALUE
  2288. rb_big_idiv_imp(VALUE x, SEL sel, VALUE y)
  2289. {
  2290. return rb_big_divide(x, y, rb_intern("div"));
  2291. }
  2292. VALUE
  2293. rb_big_idiv(VALUE x, VALUE y)
  2294. {
  2295. return rb_big_divide(x, y, rb_intern("div"));
  2296. }
  2297. /*
  2298. * call-seq:
  2299. * big % other -> Numeric
  2300. * big.modulo(other) -> Numeric
  2301. *
  2302. * Returns big modulo other. See Numeric.divmod for more
  2303. * information.
  2304. */
  2305. VALUE
  2306. rb_big_modulo(VALUE x, VALUE y)
  2307. {
  2308. VALUE z;
  2309. switch (TYPE(y)) {
  2310. case T_FIXNUM:
  2311. y = rb_int2big(FIX2LONG(y));
  2312. break;
  2313. case T_BIGNUM:
  2314. break;
  2315. default:
  2316. return rb_num_coerce_bin(x, y, '%');
  2317. }
  2318. bigdivmod(x, y, 0, &z);
  2319. return bignorm(z);
  2320. }
  2321. static VALUE
  2322. rb_big_modulo_imp(VALUE x, SEL sel, VALUE y)
  2323. {
  2324. return rb_big_modulo(x, y);
  2325. }
  2326. /*
  2327. * call-seq:
  2328. * big.remainder(numeric) -> number
  2329. *
  2330. * Returns the remainder after dividing <i>big</i> by <i>numeric</i>.
  2331. *
  2332. * -1234567890987654321.remainder(13731) #=> -6966
  2333. * -1234567890987654321.remainder(13731.24) #=> -9906.22531493148
  2334. */
  2335. static VALUE
  2336. rb_big_remainder(VALUE x, SEL sel, VALUE y)
  2337. {
  2338. VALUE z;
  2339. switch (TYPE(y)) {
  2340. case T_FIXNUM:
  2341. y = rb_int2big(FIX2LONG(y));
  2342. break;
  2343. case T_BIGNUM:
  2344. break;
  2345. default:
  2346. return rb_num_coerce_bin(x, y, rb_intern("remainder"));
  2347. }
  2348. bigdivrem(x, y, 0, &z);
  2349. return bignorm(z);
  2350. }
  2351. /*
  2352. * call-seq:
  2353. * big.divmod(numeric) -> array
  2354. *
  2355. * See <code>Numeric#divmod</code>.
  2356. *
  2357. */
  2358. VALUE
  2359. rb_big_divmod(VALUE x, VALUE y)
  2360. {
  2361. VALUE div, mod;
  2362. switch (TYPE(y)) {
  2363. case T_FIXNUM:
  2364. y = rb_int2big(FIX2LONG(y));
  2365. break;
  2366. case T_BIGNUM:
  2367. break;
  2368. default:
  2369. return rb_num_coerce_bin(x, y, rb_intern("divmod"));
  2370. }
  2371. bigdivmod(x, y, &div, &mod);
  2372. return rb_assoc_new(bignorm(div), bignorm(mod));
  2373. }
  2374. static VALUE
  2375. rb_big_divmod_imp(VALUE x, SEL sel, VALUE y)
  2376. {
  2377. return rb_big_divmod(x, y);
  2378. }
  2379. static int
  2380. bdigbitsize(BDIGIT x)
  2381. {
  2382. int size = 1;
  2383. int nb = BITSPERDIG / 2;
  2384. BDIGIT bits = (~0 << nb);
  2385. if (!x) return 0;
  2386. while (x > 1) {
  2387. if (x & bits) {
  2388. size += nb;
  2389. x >>= nb;
  2390. }
  2391. x &= ~bits;
  2392. nb /= 2;
  2393. bits >>= nb;
  2394. }
  2395. return size;
  2396. }
  2397. static VALUE big_lshift(VALUE, unsigned long);
  2398. static VALUE big_rshift(VALUE, unsigned long);
  2399. static VALUE
  2400. big_shift(VALUE x, long n)
  2401. {
  2402. if (n < 0)
  2403. return big_lshift(x, (unsigned long)-n);
  2404. else if (n > 0)
  2405. return big_rshift(x, (unsigned long)n);
  2406. return x;
  2407. }
  2408. static VALUE
  2409. big_fdiv(VALUE x, VALUE y)
  2410. {
  2411. #define DBL_BIGDIG ((DBL_MANT_DIG + BITSPERDIG) / BITSPERDIG)
  2412. VALUE z;
  2413. long l, ex, ey;
  2414. int i;
  2415. bigtrunc(x);
  2416. l = RBIGNUM_LEN(x) - 1;
  2417. ex = l * BITSPERDIG;
  2418. ex += bdigbitsize(BDIGITS(x)[l]);
  2419. ex -= 2 * DBL_BIGDIG * BITSPERDIG;
  2420. if (ex) x = big_shift(x, ex);
  2421. switch (TYPE(y)) {
  2422. case T_FIXNUM:
  2423. y = rb_int2big(FIX2LONG(y));
  2424. case T_BIGNUM: {
  2425. bigtrunc(y);
  2426. l = RBIGNUM_LEN(y) - 1;
  2427. ey = l * BITSPERDIG;
  2428. ey += bdigbitsize(BDIGITS(y)[l]);
  2429. ey -= DBL_BIGDIG * BITSPERDIG;
  2430. if (ey) y = big_shift(y, ey);
  2431. bignum:
  2432. bigdivrem(x, y, &z, 0);
  2433. l = ex - ey;
  2434. #if SIZEOF_LONG > SIZEOF_INT
  2435. {
  2436. /* Visual C++ can't be here */
  2437. if (l > INT_MAX) return DBL2NUM(INFINITY);
  2438. if (l < INT_MIN) return DBL2NUM(0.0);
  2439. }
  2440. #endif
  2441. return DBL2NUM(ldexp(big2dbl(z), (int)l));
  2442. }
  2443. case T_FLOAT:
  2444. y = dbl2big(ldexp(frexp(RFLOAT_VALUE(y), &i), DBL_MANT_DIG));
  2445. ey = i - DBL_MANT_DIG;
  2446. goto bignum;
  2447. }
  2448. rb_bug("big_fdiv");
  2449. /* NOTREACHED */
  2450. }
  2451. /*
  2452. * call-seq:
  2453. * big.fdiv(numeric) -> float
  2454. *
  2455. * Returns the floating point result of dividing <i>big</i> by
  2456. * <i>numeric</i>.
  2457. *
  2458. * -1234567890987654321.fdiv(13731) #=> -89910996357705.5
  2459. * -1234567890987654321.fdiv(13731.24) #=> -89909424858035.7
  2460. *
  2461. */
  2462. VALUE
  2463. rb_big_fdiv(VALUE x, SEL sel, VALUE y)
  2464. {
  2465. double dx, dy;
  2466. dx = big2dbl(x);
  2467. switch (TYPE(y)) {
  2468. case T_FIXNUM:
  2469. dy = (double)FIX2LONG(y);
  2470. if (isinf(dx))
  2471. return big_fdiv(x, y);
  2472. break;
  2473. case T_BIGNUM:
  2474. dy = rb_big2dbl(y);
  2475. if (isinf(dx) || isinf(dy))
  2476. return big_fdiv(x, y);
  2477. break;
  2478. case T_FLOAT:
  2479. dy = RFLOAT_VALUE(y);
  2480. if (isnan(dy))
  2481. return y;
  2482. if (isinf(dx))
  2483. return big_fdiv(x, y);
  2484. break;
  2485. default:
  2486. return rb_num_coerce_bin(x, y, rb_intern("fdiv"));
  2487. }
  2488. return DBL2NUM(dx / dy);
  2489. }
  2490. static VALUE
  2491. bigsqr(VALUE x)
  2492. {
  2493. return bigtrunc(bigmul0(x, x));
  2494. }
  2495. /*
  2496. * call-seq:
  2497. * big ** exponent -> numeric
  2498. *
  2499. * Raises _big_ to the _exponent_ power (which may be an integer, float,
  2500. * or anything that will coerce to a number). The result may be
  2501. * a Fixnum, Bignum, or Float
  2502. *
  2503. * 123456789 ** 2 #=> 15241578750190521
  2504. * 123456789 ** 1.2 #=> 5126464716.09932
  2505. * 123456789 ** -2 #=> 6.5610001194102e-17
  2506. */
  2507. VALUE
  2508. rb_big_pow(VALUE x, VALUE y)
  2509. {
  2510. double d;
  2511. SIGNED_VALUE yy;
  2512. if (y == INT2FIX(0)) return INT2FIX(1);
  2513. switch (TYPE(y)) {
  2514. case T_FLOAT:
  2515. d = RFLOAT_VALUE(y);
  2516. if ((!RBIGNUM_SIGN(x) && !BIGZEROP(x)) && d != round(d))
  2517. return rb_funcall(rb_complex_raw1(x), rb_intern("**"), 1, y);
  2518. break;
  2519. case T_BIGNUM:
  2520. if (rb_funcall(y, '<', 1, INT2FIX(0)))
  2521. return rb_funcall(rb_rational_raw1(x), rb_intern("**"), 1, y);
  2522. rb_warn("in a**b, b may be too big");
  2523. d = rb_big2dbl(y);
  2524. break;
  2525. case T_FIXNUM:
  2526. yy = FIX2LONG(y);
  2527. if (yy < 0)
  2528. return rb_funcall(rb_rational_raw1(x), rb_intern("**"), 1, y);
  2529. else {
  2530. VALUE z = 0;
  2531. SIGNED_VALUE mask;
  2532. const long BIGLEN_LIMIT = 1024*1024 / SIZEOF_BDIGITS;
  2533. if ((RBIGNUM_LEN(x) > BIGLEN_LIMIT) ||
  2534. (RBIGNUM_LEN(x) > BIGLEN_LIMIT / yy)) {
  2535. rb_warn("in a**b, b may be too big");
  2536. d = (double)yy;
  2537. break;
  2538. }
  2539. for (mask = FIXNUM_MAX + 1; mask; mask >>= 1) {
  2540. if (z) z = bigsqr(z);
  2541. if (yy & mask) {
  2542. z = z ? bigtrunc(bigmul0(z, x)) : x;
  2543. }
  2544. }
  2545. return bignorm(z);
  2546. }
  2547. /* NOTREACHED */
  2548. break;
  2549. default:
  2550. return rb_num_coerce_bin(x, y, rb_intern("**"));
  2551. }
  2552. return DBL2NUM(pow(rb_big2dbl(x), d));
  2553. }
  2554. static VALUE
  2555. rb_big_pow_imp(VALUE x, SEL sel, VALUE y)
  2556. {
  2557. return rb_big_pow(x, y);
  2558. }
  2559. static inline VALUE
  2560. bit_coerce(VALUE x)
  2561. {
  2562. while (!FIXNUM_P(x) && TYPE(x) != T_BIGNUM) {
  2563. if (TYPE(x) == T_FLOAT) {
  2564. rb_raise(rb_eTypeError, "can't convert Float into Integer");
  2565. }
  2566. x = rb_to_int(x);
  2567. }
  2568. return x;
  2569. }
  2570. static VALUE
  2571. bigand_int(VALUE x, long y)
  2572. {
  2573. VALUE z;
  2574. BDIGIT *xds, *zds;
  2575. long xn, zn;
  2576. long i;
  2577. char sign;
  2578. if (y == 0) return INT2FIX(0);
  2579. sign = (y > 0);
  2580. xds = BDIGITS(x);
  2581. zn = xn = RBIGNUM_LEN(x);
  2582. #if SIZEOF_BDIGITS == SIZEOF_LONG
  2583. if (sign) {
  2584. y &= xds[0];
  2585. return LONG2NUM(y);
  2586. }
  2587. #endif
  2588. z = bignew(zn, RBIGNUM_SIGN(x) || sign);
  2589. zds = BDIGITS(z);
  2590. #if SIZEOF_BDIGITS == SIZEOF_LONG
  2591. i = 1;
  2592. zds[0] = xds[0] & y;
  2593. #else
  2594. {
  2595. BDIGIT_DBL num = y;
  2596. for (i=0; i<(int)(sizeof(y)/sizeof(BDIGIT)); i++) {
  2597. zds[i] = xds[i] & BIGLO(num);
  2598. num = BIGDN(num);
  2599. }
  2600. }
  2601. #endif
  2602. while (i < xn) {
  2603. zds[i] = sign?0:xds[i];
  2604. i++;
  2605. }
  2606. if (!RBIGNUM_SIGN(z)) get2comp(z);
  2607. return bignorm(z);
  2608. }
  2609. /*
  2610. * call-seq:
  2611. * big & numeric -> integer
  2612. *
  2613. * Performs bitwise +and+ between _big_ and _numeric_.
  2614. */
  2615. VALUE
  2616. rb_big_and(VALUE xx, VALUE yy)
  2617. {
  2618. volatile VALUE x, y, z;
  2619. BDIGIT *ds1, *ds2, *zds;
  2620. long i, l1, l2;
  2621. char sign;
  2622. x = xx;
  2623. y = bit_coerce(yy);
  2624. if (!RBIGNUM_SIGN(x)) {
  2625. x = rb_big_clone(x);
  2626. get2comp(x);
  2627. }
  2628. if (FIXNUM_P(y)) {
  2629. return bigand_int(x, FIX2LONG(y));
  2630. }
  2631. if (!RBIGNUM_SIGN(y)) {
  2632. y = rb_big_clone(y);
  2633. get2comp(y);
  2634. }
  2635. if (RBIGNUM_LEN(x) > RBIGNUM_LEN(y)) {
  2636. l1 = RBIGNUM_LEN(y);
  2637. l2 = RBIGNUM_LEN(x);
  2638. ds1 = BDIGITS(y);
  2639. ds2 = BDIGITS(x);
  2640. sign = RBIGNUM_SIGN(y);
  2641. }
  2642. else {
  2643. l1 = RBIGNUM_LEN(x);
  2644. l2 = RBIGNUM_LEN(y);
  2645. ds1 = BDIGITS(x);
  2646. ds2 = BDIGITS(y);
  2647. sign = RBIGNUM_SIGN(x);
  2648. }
  2649. z = bignew(l2, RBIGNUM_SIGN(x) || RBIGNUM_SIGN(y));
  2650. zds = BDIGITS(z);
  2651. for (i=0; i<l1; i++) {
  2652. zds[i] = ds1[i] & ds2[i];
  2653. }
  2654. for (; i<l2; i++) {
  2655. zds[i] = sign?0:ds2[i];
  2656. }
  2657. if (!RBIGNUM_SIGN(z)) get2comp(z);
  2658. return bignorm(z);
  2659. }
  2660. static VALUE
  2661. rb_big_and_imp(VALUE x, SEL sel, VALUE y)
  2662. {
  2663. return rb_big_and(x, y);
  2664. }
  2665. static VALUE
  2666. bigor_int(VALUE x, long y)
  2667. {
  2668. VALUE z;
  2669. BDIGIT *xds, *zds;
  2670. long xn, zn;
  2671. long i;
  2672. char sign;
  2673. sign = (y >= 0);
  2674. xds = BDIGITS(x);
  2675. zn = xn = RBIGNUM_LEN(x);
  2676. z = bignew(zn, RBIGNUM_SIGN(x) && sign);
  2677. zds = BDIGITS(z);
  2678. #if SIZEOF_BDIGITS == SIZEOF_LONG
  2679. i = 1;
  2680. zds[0] = xds[0] | y;
  2681. #else
  2682. {
  2683. BDIGIT_DBL num = y;
  2684. for (i=0; i<(int)(sizeof(y)/sizeof(BDIGIT)); i++) {
  2685. zds[i] = xds[i] | BIGLO(num);
  2686. num = BIGDN(num);
  2687. }
  2688. }
  2689. #endif
  2690. while (i < xn) {
  2691. zds[i] = sign?xds[i]:(BDIGIT)(BIGRAD-1);
  2692. i++;
  2693. }
  2694. if (!RBIGNUM_SIGN(z)) get2comp(z);
  2695. return bignorm(z);
  2696. }
  2697. /*
  2698. * call-seq:
  2699. * big | numeric -> integer
  2700. *
  2701. * Performs bitwise +or+ between _big_ and _numeric_.
  2702. */
  2703. VALUE
  2704. rb_big_or(VALUE xx, VALUE yy)
  2705. {
  2706. volatile VALUE x, y, z;
  2707. BDIGIT *ds1, *ds2, *zds;
  2708. long i, l1, l2;
  2709. char sign;
  2710. x = xx;
  2711. y = bit_coerce(yy);
  2712. if (!RBIGNUM_SIGN(x)) {
  2713. x = rb_big_clone(x);
  2714. get2comp(x);
  2715. }
  2716. if (FIXNUM_P(y)) {
  2717. return bigor_int(x, FIX2LONG(y));
  2718. }
  2719. if (!RBIGNUM_SIGN(y)) {
  2720. y = rb_big_clone(y);
  2721. get2comp(y);
  2722. }
  2723. if (RBIGNUM_LEN(x) > RBIGNUM_LEN(y)) {
  2724. l1 = RBIGNUM_LEN(y);
  2725. l2 = RBIGNUM_LEN(x);
  2726. ds1 = BDIGITS(y);
  2727. ds2 = BDIGITS(x);
  2728. sign = RBIGNUM_SIGN(y);
  2729. }
  2730. else {
  2731. l1 = RBIGNUM_LEN(x);
  2732. l2 = RBIGNUM_LEN(y);
  2733. ds1 = BDIGITS(x);
  2734. ds2 = BDIGITS(y);
  2735. sign = RBIGNUM_SIGN(x);
  2736. }
  2737. z = bignew(l2, RBIGNUM_SIGN(x) && RBIGNUM_SIGN(y));
  2738. zds = BDIGITS(z);
  2739. for (i=0; i<l1; i++) {
  2740. zds[i] = ds1[i] | ds2[i];
  2741. }
  2742. for (; i<l2; i++) {
  2743. zds[i] = sign?ds2[i]:(BDIGIT)(BIGRAD-1);
  2744. }
  2745. if (!RBIGNUM_SIGN(z)) get2comp(z);
  2746. return bignorm(z);
  2747. }
  2748. static VALUE
  2749. rb_big_or_imp(VALUE x, SEL sel, VALUE y)
  2750. {
  2751. return rb_big_or(x, y);
  2752. }
  2753. static VALUE
  2754. bigxor_int(VALUE x, long y)
  2755. {
  2756. VALUE z;
  2757. BDIGIT *xds, *zds;
  2758. long xn, zn;
  2759. long i;
  2760. char sign;
  2761. sign = (y >= 0) ? 1 : 0;
  2762. xds = BDIGITS(x);
  2763. zn = xn = RBIGNUM_LEN(x);
  2764. z = bignew(zn, !(RBIGNUM_SIGN(x) ^ sign));
  2765. zds = BDIGITS(z);
  2766. #if SIZEOF_BDIGITS == SIZEOF_LONG
  2767. i = 1;
  2768. zds[0] = xds[0] ^ y;
  2769. #else
  2770. {
  2771. BDIGIT_DBL num = y;
  2772. for (i=0; i<(int)(sizeof(y)/sizeof(BDIGIT)); i++) {
  2773. zds[i] = xds[i] ^ BIGLO(num);
  2774. num = BIGDN(num);
  2775. }
  2776. }
  2777. #endif
  2778. while (i < xn) {
  2779. zds[i] = sign?xds[i]:~xds[i];
  2780. i++;
  2781. }
  2782. if (!RBIGNUM_SIGN(z)) get2comp(z);
  2783. return bignorm(z);
  2784. }
  2785. /*
  2786. * call-seq:
  2787. * big ^ numeric -> integer
  2788. *
  2789. * Performs bitwise +exclusive or+ between _big_ and _numeric_.
  2790. */
  2791. VALUE
  2792. rb_big_xor(VALUE xx, VALUE yy)
  2793. {
  2794. volatile VALUE x, y;
  2795. VALUE z;
  2796. BDIGIT *ds1, *ds2, *zds;
  2797. long i, l1, l2;
  2798. char sign;
  2799. x = xx;
  2800. y = bit_coerce(yy);
  2801. if (!RBIGNUM_SIGN(x)) {
  2802. x = rb_big_clone(x);
  2803. get2comp(x);
  2804. }
  2805. if (FIXNUM_P(y)) {
  2806. return bigxor_int(x, FIX2LONG(y));
  2807. }
  2808. if (!RBIGNUM_SIGN(y)) {
  2809. y = rb_big_clone(y);
  2810. get2comp(y);
  2811. }
  2812. if (RBIGNUM_LEN(x) > RBIGNUM_LEN(y)) {
  2813. l1 = RBIGNUM_LEN(y);
  2814. l2 = RBIGNUM_LEN(x);
  2815. ds1 = BDIGITS(y);
  2816. ds2 = BDIGITS(x);
  2817. sign = RBIGNUM_SIGN(y);
  2818. }
  2819. else {
  2820. l1 = RBIGNUM_LEN(x);
  2821. l2 = RBIGNUM_LEN(y);
  2822. ds1 = BDIGITS(x);
  2823. ds2 = BDIGITS(y);
  2824. sign = RBIGNUM_SIGN(x);
  2825. }
  2826. RBIGNUM_SET_SIGN(x, RBIGNUM_SIGN(x)?1:0);
  2827. RBIGNUM_SET_SIGN(y, RBIGNUM_SIGN(y)?1:0);
  2828. z = bignew(l2, !(RBIGNUM_SIGN(x) ^ RBIGNUM_SIGN(y)));
  2829. zds = BDIGITS(z);
  2830. for (i=0; i<l1; i++) {
  2831. zds[i] = ds1[i] ^ ds2[i];
  2832. }
  2833. for (; i<l2; i++) {
  2834. zds[i] = sign?ds2[i]:~ds2[i];
  2835. }
  2836. if (!RBIGNUM_SIGN(z)) get2comp(z);
  2837. return bignorm(z);
  2838. }
  2839. static VALUE
  2840. rb_big_xor_imp(VALUE x, SEL sel, VALUE y)
  2841. {
  2842. return rb_big_xor(x, y);
  2843. }
  2844. static VALUE
  2845. check_shiftdown(VALUE y, VALUE x)
  2846. {
  2847. if (!RBIGNUM_LEN(x)) return INT2FIX(0);
  2848. if (RBIGNUM_LEN(y) > SIZEOF_LONG / SIZEOF_BDIGITS) {
  2849. return RBIGNUM_SIGN(x) ? INT2FIX(0) : INT2FIX(-1);
  2850. }
  2851. return Qnil;
  2852. }
  2853. /*
  2854. * call-seq:
  2855. * big << numeric -> integer
  2856. *
  2857. * Shifts big left _numeric_ positions (right if _numeric_ is negative).
  2858. */
  2859. VALUE
  2860. rb_big_lshift(VALUE x, VALUE y)
  2861. {
  2862. long shift;
  2863. int neg = 0;
  2864. for (;;) {
  2865. if (FIXNUM_P(y)) {
  2866. shift = FIX2LONG(y);
  2867. if (shift < 0) {
  2868. neg = 1;
  2869. shift = -shift;
  2870. }
  2871. break;
  2872. }
  2873. else if (TYPE(y) == T_BIGNUM) {
  2874. if (!RBIGNUM_SIGN(y)) {
  2875. VALUE t = check_shiftdown(y, x);
  2876. if (!NIL_P(t)) return t;
  2877. neg = 1;
  2878. }
  2879. shift = big2ulong(y, "long", TRUE);
  2880. break;
  2881. }
  2882. y = rb_to_int(y);
  2883. }
  2884. x = neg ? big_rshift(x, shift) : big_lshift(x, shift);
  2885. return bignorm(x);
  2886. }
  2887. static VALUE
  2888. rb_big_lshift_imp(VALUE x, SEL sel, VALUE y)
  2889. {
  2890. return rb_big_lshift(x, y);
  2891. }
  2892. static VALUE
  2893. big_lshift(VALUE x, unsigned long shift)
  2894. {
  2895. BDIGIT *xds, *zds;
  2896. long s1 = shift/BITSPERDIG;
  2897. int s2 = (int)(shift%BITSPERDIG);
  2898. VALUE z;
  2899. BDIGIT_DBL num = 0;
  2900. long len, i;
  2901. len = RBIGNUM_LEN(x);
  2902. z = bignew(len+s1+1, RBIGNUM_SIGN(x));
  2903. zds = BDIGITS(z);
  2904. for (i=0; i<s1; i++) {
  2905. *zds++ = 0;
  2906. }
  2907. xds = BDIGITS(x);
  2908. for (i=0; i<len; i++) {
  2909. num = num | (BDIGIT_DBL)*xds++<<s2;
  2910. *zds++ = BIGLO(num);
  2911. num = BIGDN(num);
  2912. }
  2913. *zds = BIGLO(num);
  2914. return z;
  2915. }
  2916. /*
  2917. * call-seq:
  2918. * big >> numeric -> integer
  2919. *
  2920. * Shifts big right _numeric_ positions (left if _numeric_ is negative).
  2921. */
  2922. VALUE
  2923. rb_big_rshift(VALUE x, VALUE y)
  2924. {
  2925. long shift;
  2926. int neg = 0;
  2927. for (;;) {
  2928. if (FIXNUM_P(y)) {
  2929. shift = FIX2LONG(y);
  2930. if (shift < 0) {
  2931. neg = 1;
  2932. shift = -shift;
  2933. }
  2934. break;
  2935. }
  2936. else if (TYPE(y) == T_BIGNUM) {
  2937. if (RBIGNUM_SIGN(y)) {
  2938. VALUE t = check_shiftdown(y, x);
  2939. if (!NIL_P(t)) return t;
  2940. }
  2941. else {
  2942. neg = 1;
  2943. }
  2944. shift = big2ulong(y, "long", TRUE);
  2945. break;
  2946. }
  2947. y = rb_to_int(y);
  2948. }
  2949. x = neg ? big_lshift(x, shift) : big_rshift(x, shift);
  2950. return bignorm(x);
  2951. }
  2952. static VALUE
  2953. rb_big_rshift_imp(VALUE x, SEL sel, VALUE y)
  2954. {
  2955. return rb_big_rshift(x, y);
  2956. }
  2957. static VALUE
  2958. big_rshift(VALUE x, unsigned long shift)
  2959. {
  2960. BDIGIT *xds, *zds;
  2961. long s1 = shift/BITSPERDIG;
  2962. int s2 = (int)(shift%BITSPERDIG);
  2963. VALUE z;
  2964. BDIGIT_DBL num = 0;
  2965. long i, j;
  2966. volatile VALUE save_x;
  2967. if (s1 > RBIGNUM_LEN(x)) {
  2968. if (RBIGNUM_SIGN(x))
  2969. return INT2FIX(0);
  2970. else
  2971. return INT2FIX(-1);
  2972. }
  2973. if (!RBIGNUM_SIGN(x)) {
  2974. save_x = x = rb_big_clone(x);
  2975. get2comp(x);
  2976. }
  2977. xds = BDIGITS(x);
  2978. i = RBIGNUM_LEN(x); j = i - s1;
  2979. if (j == 0) {
  2980. if (RBIGNUM_SIGN(x)) return INT2FIX(0);
  2981. else return INT2FIX(-1);
  2982. }
  2983. z = bignew(j, RBIGNUM_SIGN(x));
  2984. if (!RBIGNUM_SIGN(x)) {
  2985. num = ((BDIGIT_DBL)~0) << BITSPERDIG;
  2986. }
  2987. zds = BDIGITS(z);
  2988. while (i--, j--) {
  2989. num = (num | xds[i]) >> s2;
  2990. zds[j] = BIGLO(num);
  2991. num = BIGUP(xds[i]);
  2992. }
  2993. if (!RBIGNUM_SIGN(x)) {
  2994. get2comp(z);
  2995. }
  2996. return z;
  2997. }
  2998. /*
  2999. * call-seq:
  3000. * big[n] -> 0, 1
  3001. *
  3002. * Bit Reference---Returns the <em>n</em>th bit in the (assumed) binary
  3003. * representation of <i>big</i>, where <i>big</i>[0] is the least
  3004. * significant bit.
  3005. *
  3006. * a = 9**15
  3007. * 50.downto(0) do |n|
  3008. * print a[n]
  3009. * end
  3010. *
  3011. * <em>produces:</em>
  3012. *
  3013. * 000101110110100000111000011110010100111100010111001
  3014. *
  3015. */
  3016. static VALUE
  3017. rb_big_aref(VALUE x, SEL sel, VALUE y)
  3018. {
  3019. BDIGIT *xds;
  3020. BDIGIT_DBL num;
  3021. VALUE shift;
  3022. long i, s1, s2;
  3023. if (TYPE(y) == T_BIGNUM) {
  3024. if (!RBIGNUM_SIGN(y))
  3025. return INT2FIX(0);
  3026. if (RBIGNUM_LEN(bigtrunc(y)) > DIGSPERLONG) {
  3027. out_of_range:
  3028. return RBIGNUM_SIGN(x) ? INT2FIX(0) : INT2FIX(1);
  3029. }
  3030. shift = big2ulong(y, "long", FALSE);
  3031. }
  3032. else {
  3033. i = NUM2LONG(y);
  3034. if (i < 0) return INT2FIX(0);
  3035. shift = (VALUE)i;
  3036. }
  3037. s1 = shift/BITSPERDIG;
  3038. s2 = shift%BITSPERDIG;
  3039. if (s1 >= RBIGNUM_LEN(x)) goto out_of_range;
  3040. if (!RBIGNUM_SIGN(x)) {
  3041. xds = BDIGITS(x);
  3042. i = 0; num = 1;
  3043. while (num += ~xds[i], ++i <= s1) {
  3044. num = BIGDN(num);
  3045. }
  3046. }
  3047. else {
  3048. num = BDIGITS(x)[s1];
  3049. }
  3050. if (num & ((BDIGIT_DBL)1<<s2))
  3051. return INT2FIX(1);
  3052. return INT2FIX(0);
  3053. }
  3054. /*
  3055. * call-seq:
  3056. * big.hash -> fixnum
  3057. *
  3058. * Compute a hash based on the value of _big_.
  3059. */
  3060. static VALUE
  3061. rb_big_hash(VALUE x, SEL sel)
  3062. {
  3063. int hash;
  3064. hash = rb_memhash(BDIGITS(x), sizeof(BDIGIT)*RBIGNUM_LEN(x)) ^ RBIGNUM_SIGN(x);
  3065. return INT2FIX(hash);
  3066. }
  3067. /*
  3068. * MISSING: documentation
  3069. */
  3070. static VALUE
  3071. rb_big_coerce(VALUE x, SEL sel, VALUE y)
  3072. {
  3073. if (FIXNUM_P(y)) {
  3074. return rb_assoc_new(rb_int2big(FIX2LONG(y)), x);
  3075. }
  3076. else if (TYPE(y) == T_BIGNUM) {
  3077. return rb_assoc_new(y, x);
  3078. }
  3079. else {
  3080. rb_raise(rb_eTypeError, "can't coerce %s to Bignum",
  3081. rb_obj_classname(y));
  3082. }
  3083. /* not reached */
  3084. return Qnil;
  3085. }
  3086. /*
  3087. * call-seq:
  3088. * big.abs -> aBignum
  3089. *
  3090. * Returns the absolute value of <i>big</i>.
  3091. *
  3092. * -1234567890987654321.abs #=> 1234567890987654321
  3093. */
  3094. static VALUE
  3095. rb_big_abs(VALUE x, SEL sel)
  3096. {
  3097. if (!RBIGNUM_SIGN(x)) {
  3098. x = rb_big_clone(x);
  3099. RBIGNUM_SET_SIGN(x, 1);
  3100. }
  3101. return x;
  3102. }
  3103. /*
  3104. * call-seq:
  3105. * big.size -> integer
  3106. *
  3107. * Returns the number of bytes in the machine representation of
  3108. * <i>big</i>.
  3109. *
  3110. * (256**10 - 1).size #=> 12
  3111. * (256**20 - 1).size #=> 20
  3112. * (256**40 - 1).size #=> 40
  3113. */
  3114. static VALUE
  3115. rb_big_size(VALUE big, SEL sel)
  3116. {
  3117. return LONG2FIX(RBIGNUM_LEN(big)*SIZEOF_BDIGITS);
  3118. }
  3119. /*
  3120. * call-seq:
  3121. * big.odd? -> true or false
  3122. *
  3123. * Returns <code>true</code> if <i>big</i> is an odd number.
  3124. */
  3125. static VALUE
  3126. rb_big_odd_p(VALUE num, SEL sel)
  3127. {
  3128. if (BDIGITS(num)[0] & 1) {
  3129. return Qtrue;
  3130. }
  3131. return Qfalse;
  3132. }
  3133. /*
  3134. * call-seq:
  3135. * big.even? -> true or false
  3136. *
  3137. * Returns <code>true</code> if <i>big</i> is an even number.
  3138. */
  3139. static VALUE
  3140. rb_big_even_p(VALUE num, SEL sel)
  3141. {
  3142. if (BDIGITS(num)[0] & 1) {
  3143. return Qfalse;
  3144. }
  3145. return Qtrue;
  3146. }
  3147. #if WITH_OBJC
  3148. static const char *
  3149. imp_rb_bignum_objCType(void *rcv, SEL sel)
  3150. {
  3151. return "q";
  3152. }
  3153. static void
  3154. imp_rb_bignum_getValue(void *rcv, SEL sel, void *buffer)
  3155. {
  3156. long long v = NUM2LL(rcv);
  3157. *(long long *)buffer = v;
  3158. }
  3159. static long long
  3160. imp_rb_bignum_longLongValue(void *rcv, SEL sel)
  3161. {
  3162. return NUM2LL(rcv);
  3163. }
  3164. static bool
  3165. imp_rb_bignum_isEqual(void *rcv, SEL sel, void *other)
  3166. {
  3167. if (other == NULL)
  3168. return false;
  3169. if (*(Class *)other != (Class)rb_cBignum)
  3170. return false;
  3171. return rb_big_eq((VALUE)rcv, (VALUE)other) == Qtrue;
  3172. }
  3173. static void
  3174. rb_install_nsnumber_primitives(void)
  3175. {
  3176. Class klass = (Class)rb_cBignum;
  3177. rb_objc_install_method2(klass, "objCType",
  3178. (IMP)imp_rb_bignum_objCType);
  3179. rb_objc_install_method2(klass, "getValue:",
  3180. (IMP)imp_rb_bignum_getValue);
  3181. rb_objc_install_method2(klass, "longLongValue",
  3182. (IMP)imp_rb_bignum_longLongValue);
  3183. rb_objc_install_method2(klass, "isEqual:",
  3184. (IMP)imp_rb_bignum_isEqual);
  3185. }
  3186. #endif
  3187. /*
  3188. * Bignum objects hold integers outside the range of
  3189. * Fixnum. Bignum objects are created
  3190. * automatically when integer calculations would otherwise overflow a
  3191. * Fixnum. When a calculation involving
  3192. * Bignum objects returns a result that will fit in a
  3193. * Fixnum, the result is automatically converted.
  3194. *
  3195. * For the purposes of the bitwise operations and <code>[]</code>, a
  3196. * Bignum is treated as if it were an infinite-length
  3197. * bitstring with 2's complement representation.
  3198. *
  3199. * While Fixnum values are immediate, Bignum
  3200. * objects are not---assignment and parameter passing work with
  3201. * references to objects, not the objects themselves.
  3202. *
  3203. */
  3204. void
  3205. Init_Bignum(void)
  3206. {
  3207. rb_cBignum = rb_define_class("Bignum", rb_cInteger);
  3208. rb_objc_define_method(rb_cBignum, "to_s", rb_big_to_s, -1);
  3209. rb_objc_define_method(rb_cBignum, "coerce", rb_big_coerce, 1);
  3210. rb_objc_define_method(rb_cBignum, "-@", rb_big_uminus_imp, 0);
  3211. rb_objc_define_method(rb_cBignum, "+", rb_big_plus_imp, 1);
  3212. rb_objc_define_method(rb_cBignum, "-", rb_big_minus_imp, 1);
  3213. rb_objc_define_method(rb_cBignum, "*", rb_big_mul_imp, 1);
  3214. rb_objc_define_method(rb_cBignum, "/", rb_big_div_imp, 1);
  3215. rb_objc_define_method(rb_cBignum, "%", rb_big_modulo_imp, 1);
  3216. rb_objc_define_method(rb_cBignum, "div", rb_big_idiv_imp, 1);
  3217. rb_objc_define_method(rb_cBignum, "divmod", rb_big_divmod_imp, 1);
  3218. rb_objc_define_method(rb_cBignum, "modulo", rb_big_modulo_imp, 1);
  3219. rb_objc_define_method(rb_cBignum, "remainder", rb_big_remainder, 1);
  3220. rb_objc_define_method(rb_cBignum, "fdiv", rb_big_fdiv, 1);
  3221. rb_objc_define_method(rb_cBignum, "**", rb_big_pow_imp, 1);
  3222. rb_objc_define_method(rb_cBignum, "&", rb_big_and_imp, 1);
  3223. rb_objc_define_method(rb_cBignum, "|", rb_big_or_imp, 1);
  3224. rb_objc_define_method(rb_cBignum, "^", rb_big_xor_imp, 1);
  3225. rb_objc_define_method(rb_cBignum, "~", rb_big_neg, 0);
  3226. rb_objc_define_method(rb_cBignum, "<<", rb_big_lshift_imp, 1);
  3227. rb_objc_define_method(rb_cBignum, ">>", rb_big_rshift_imp, 1);
  3228. rb_objc_define_method(rb_cBignum, "[]", rb_big_aref, 1);
  3229. rb_objc_define_method(rb_cBignum, "<=>", rb_big_cmp_imp, 1);
  3230. rb_objc_define_method(rb_cBignum, "==", rb_big_eq_imp, 1);
  3231. rb_objc_define_method(rb_cBignum, ">", big_gt, 1);
  3232. rb_objc_define_method(rb_cBignum, ">=", big_ge, 1);
  3233. rb_objc_define_method(rb_cBignum, "<", big_lt, 1);
  3234. rb_objc_define_method(rb_cBignum, "<=", big_le, 1);
  3235. rb_objc_define_method(rb_cBignum, "===", rb_big_eq, 1);
  3236. rb_objc_define_method(rb_cBignum, "eql?", rb_big_eql, 1);
  3237. rb_objc_define_method(rb_cBignum, "hash", rb_big_hash, 0);
  3238. rb_objc_define_method(rb_cBignum, "to_f", rb_big_to_f, 0);
  3239. rb_objc_define_method(rb_cBignum, "abs", rb_big_abs, 0);
  3240. rb_objc_define_method(rb_cBignum, "magnitude", rb_big_abs, 0);
  3241. rb_objc_define_method(rb_cBignum, "size", rb_big_size, 0);
  3242. rb_objc_define_method(rb_cBignum, "odd?", rb_big_odd_p, 0);
  3243. rb_objc_define_method(rb_cBignum, "even?", rb_big_even_p, 0);
  3244. power_cache_init();
  3245. #if WITH_OBJC
  3246. rb_install_nsnumber_primitives();
  3247. #endif
  3248. }