big.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. var bigInt = (function () {
  2. var base = 10000000, logBase = 7;
  3. var sign = {
  4. positive: false,
  5. negative: true
  6. };
  7. var normalize = function (first, second) {
  8. var a = first.value, b = second.value;
  9. var length = a.length > b.length ? a.length : b.length;
  10. for (var i = 0; i < length; i++) {
  11. a[i] = a[i] || 0;
  12. b[i] = b[i] || 0;
  13. }
  14. for (var i = length - 1; i >= 0; i--) {
  15. if (a[i] === 0 && b[i] === 0) {
  16. a.pop();
  17. b.pop();
  18. } else break;
  19. }
  20. if (!a.length) a = [0], b = [0];
  21. first.value = a;
  22. second.value = b;
  23. };
  24. var parse = function (text, first) {
  25. if (typeof text === "object") return text;
  26. text += "";
  27. var s = sign.positive, value = [];
  28. if (text[0] === "-") {
  29. s = sign.negative;
  30. text = text.slice(1);
  31. }
  32. var base = 10;
  33. if (text.slice(0, 2) == "0x") {
  34. base = 16;
  35. text = text.slice(2);
  36. }
  37. else {
  38. var texts = text.split("e");
  39. if (texts.length > 2) throw new Error("Invalid integer");
  40. if (texts[1]) {
  41. var exp = texts[1];
  42. if (exp[0] === "+") exp = exp.slice(1);
  43. exp = parse(exp);
  44. if (exp.lesser(0)) throw new Error("Cannot include negative exponent part for integers");
  45. while (exp.notEquals(0)) {
  46. texts[0] += "0";
  47. exp = exp.prev();
  48. }
  49. }
  50. text = texts[0];
  51. }
  52. if (text === "-0") text = "0";
  53. text = text.toUpperCase();
  54. var isValid = (base == 16 ? /^[0-9A-F]*$/ : /^[0-9]+$/).test(text);
  55. if (!isValid) throw new Error("Invalid integer");
  56. if (base == 16) {
  57. var val = bigInt(0);
  58. while (text.length) {
  59. v = text.charCodeAt(0) - 48;
  60. if (v > 9)
  61. v -= 7;
  62. text = text.slice(1);
  63. val = val.times(16).plus(v);
  64. }
  65. return val;
  66. }
  67. else {
  68. while (text.length) {
  69. var divider = text.length > logBase ? text.length - logBase : 0;
  70. value.push(+text.slice(divider));
  71. text = text.slice(0, divider);
  72. }
  73. var val = bigInt(value, s);
  74. if (first) normalize(first, val);
  75. return val;
  76. }
  77. };
  78. var goesInto = function (a, b) {
  79. var a = bigInt(a, sign.positive), b = bigInt(b, sign.positive);
  80. if (a.equals(0)) throw new Error("Cannot divide by 0");
  81. var n = 0;
  82. do {
  83. var inc = 1;
  84. var c = bigInt(a.value, sign.positive), t = c.times(10);
  85. while (t.lesser(b)) {
  86. c = t;
  87. inc *= 10;
  88. t = t.times(10);
  89. }
  90. while (c.lesserOrEquals(b)) {
  91. b = b.minus(c);
  92. n += inc;
  93. }
  94. } while (a.lesserOrEquals(b));
  95. return {
  96. remainder: b.value,
  97. result: n
  98. };
  99. };
  100. var bigInt = function (value, s) {
  101. var self = {
  102. value: value,
  103. sign: s
  104. };
  105. var o = {
  106. value: value,
  107. sign: s,
  108. negate: function (m) {
  109. var first = m || self;
  110. return bigInt(first.value, !first.sign);
  111. },
  112. abs: function (m) {
  113. var first = m || self;
  114. return bigInt(first.value, sign.positive);
  115. },
  116. add: function (n, m) {
  117. var s, first = self, second;
  118. if (m) (first = parse(n)) && (second = parse(m));
  119. else second = parse(n, first);
  120. s = first.sign;
  121. if (first.sign !== second.sign) {
  122. first = bigInt(first.value, sign.positive);
  123. second = bigInt(second.value, sign.positive);
  124. return s === sign.positive ?
  125. o.subtract(first, second) :
  126. o.subtract(second, first);
  127. }
  128. normalize(first, second);
  129. var a = first.value, b = second.value;
  130. var result = [],
  131. carry = 0;
  132. for (var i = 0; i < a.length || carry > 0; i++) {
  133. var sum = (a[i] || 0) + (b[i] || 0) + carry;
  134. carry = sum >= base ? 1 : 0;
  135. sum -= carry * base;
  136. result.push(sum);
  137. }
  138. return bigInt(result, s);
  139. },
  140. plus: function (n, m) {
  141. return o.add(n, m);
  142. },
  143. subtract: function (n, m) {
  144. var first = self, second;
  145. if (m) (first = parse(n)) && (second = parse(m));
  146. else second = parse(n, first);
  147. if (first.sign !== second.sign) return o.add(first, o.negate(second));
  148. if (first.sign === sign.negative) return o.subtract(o.negate(second), o.negate(first));
  149. if (o.compare(first, second) === -1) return o.negate(o.subtract(second, first));
  150. var a = first.value, b = second.value;
  151. var result = [],
  152. borrow = 0;
  153. for (var i = 0; i < a.length; i++) {
  154. var tmp = a[i] - borrow;
  155. borrow = tmp < b[i] ? 1 : 0;
  156. var minuend = (borrow * base) + tmp - b[i];
  157. result.push(minuend);
  158. }
  159. return bigInt(result, sign.positive);
  160. },
  161. minus: function (n, m) {
  162. return o.subtract(n, m);
  163. },
  164. multiply: function (n, m) {
  165. var s, first = self, second;
  166. if (m) (first = parse(n)) && (second = parse(m));
  167. else second = parse(n, first);
  168. s = first.sign !== second.sign;
  169. var a = first.value, b = second.value;
  170. var resultSum = [];
  171. for (var i = 0; i < a.length; i++) {
  172. resultSum[i] = [];
  173. var j = i;
  174. while (j--) {
  175. resultSum[i].push(0);
  176. }
  177. }
  178. var carry = 0;
  179. for (var i = 0; i < a.length; i++) {
  180. var x = a[i];
  181. for (var j = 0; j < b.length || carry > 0; j++) {
  182. var y = b[j];
  183. var product = y ? (x * y) + carry : carry;
  184. carry = product > base ? Math.floor(product / base) : 0;
  185. product -= carry * base;
  186. resultSum[i].push(product);
  187. }
  188. }
  189. var max = -1;
  190. for (var i = 0; i < resultSum.length; i++) {
  191. var len = resultSum[i].length;
  192. if (len > max) max = len;
  193. }
  194. var result = [], carry = 0;
  195. for (var i = 0; i < max || carry > 0; i++) {
  196. var sum = carry;
  197. for (var j = 0; j < resultSum.length; j++) {
  198. sum += resultSum[j][i] || 0;
  199. }
  200. carry = sum > base ? Math.floor(sum / base) : 0;
  201. sum -= carry * base;
  202. result.push(sum);
  203. }
  204. return bigInt(result, s);
  205. },
  206. times: function (n, m) {
  207. return o.multiply(n, m);
  208. },
  209. divmod: function (n, m) {
  210. var s, first = self, second;
  211. if (m) (first = parse(n)) && (second = parse(m));
  212. else second = parse(n, first);
  213. s = first.sign !== second.sign;
  214. if (bigInt(first.value, first.sign).equals(0)) return {
  215. quotient: bigInt([0], sign.positive),
  216. remainder: bigInt([0], sign.positive)
  217. };
  218. if (second.equals(0)) throw new Error("Cannot divide by zero");
  219. var a = first.value, b = second.value;
  220. var result = [], remainder = [];
  221. for (var i = a.length - 1; i >= 0; i--) {
  222. var n = [a[i]].concat(remainder);
  223. var quotient = goesInto(b, n);
  224. result.push(quotient.result);
  225. remainder = quotient.remainder;
  226. }
  227. result.reverse();
  228. return {
  229. quotient: bigInt(result, s),
  230. remainder: bigInt(remainder, first.sign)
  231. };
  232. },
  233. divide: function (n, m) {
  234. return o.divmod(n, m).quotient;
  235. },
  236. over: function (n, m) {
  237. return o.divide(n, m);
  238. },
  239. mod: function (n, m) {
  240. return o.divmod(n, m).remainder;
  241. },
  242. pow: function (n, m) {
  243. var first = self, second;
  244. if (m) (first = parse(n)) && (second = parse(m));
  245. else second = parse(n, first);
  246. var a = first, b = second;
  247. if (b.lesser(0)) return ZERO;
  248. if (b.equals(0)) return ONE;
  249. var result = bigInt(a.value, a.sign);
  250. if (b.mod(2).equals(0)) {
  251. var c = result.pow(b.over(2));
  252. return c.times(c);
  253. } else {
  254. return result.times(result.pow(b.minus(1)));
  255. }
  256. },
  257. next: function (m) {
  258. var first = m || self;
  259. return o.add(first, 1);
  260. },
  261. prev: function (m) {
  262. var first = m || self;
  263. return o.subtract(first, 1);
  264. },
  265. compare: function (n, m) {
  266. var first = self, second;
  267. if (m) (first = parse(n)) && (second = parse(m, first));
  268. else second = parse(n, first);
  269. normalize(first, second);
  270. if (first.value.length === 1 && second.value.length === 1 && first.value[0] === 0 && second.value[0] === 0) return 0;
  271. if (second.sign !== first.sign) return first.sign === sign.positive ? 1 : -1;
  272. var multiplier = first.sign === sign.positive ? 1 : -1;
  273. var a = first.value, b = second.value;
  274. for (var i = a.length - 1; i >= 0; i--) {
  275. if (a[i] > b[i]) return 1 * multiplier;
  276. if (b[i] > a[i]) return -1 * multiplier;
  277. }
  278. return 0;
  279. },
  280. compareAbs: function (n, m) {
  281. var first = self, second;
  282. if (m) (first = parse(n)) && (second = parse(m, first));
  283. else second = parse(n, first);
  284. first.sign = second.sign = sign.positive;
  285. return o.compare(first, second);
  286. },
  287. equals: function (n, m) {
  288. return o.compare(n, m) === 0;
  289. },
  290. notEquals: function (n, m) {
  291. return !o.equals(n, m);
  292. },
  293. lesser: function (n, m) {
  294. return o.compare(n, m) < 0;
  295. },
  296. greater: function (n, m) {
  297. return o.compare(n, m) > 0;
  298. },
  299. greaterOrEquals: function (n, m) {
  300. return o.compare(n, m) >= 0;
  301. },
  302. lesserOrEquals: function (n, m) {
  303. return o.compare(n, m) <= 0;
  304. },
  305. isPositive: function (m) {
  306. var first = m || self;
  307. return first.sign === sign.positive;
  308. },
  309. isNegative: function (m) {
  310. var first = m || self;
  311. return first.sign === sign.negative;
  312. },
  313. isEven: function (m) {
  314. var first = m || self;
  315. return first.value[0] % 2 === 0;
  316. },
  317. isOdd: function (m) {
  318. var first = m || self;
  319. return first.value[0] % 2 === 1;
  320. },
  321. toString: function (m) {
  322. var first = m || self;
  323. var str = "", len = first.value.length;
  324. while (len--) {
  325. if (first.value[len].toString().length === 8) str += first.value[len];
  326. else str += (base.toString() + first.value[len]).slice(-logBase);
  327. }
  328. while (str[0] === "0") {
  329. str = str.slice(1);
  330. }
  331. if (!str.length) str = "0";
  332. var s = (first.sign === sign.positive || str == "0") ? "" : "-";
  333. return s + str;
  334. },
  335. toHex: function (m) {
  336. var first = m || self;
  337. var str = "";
  338. var l = this.abs();
  339. while (l > 0) {
  340. var qr = l.divmod(256);
  341. var b = qr.remainder.toJSNumber();
  342. str = (b >> 4).toString(16) + (b & 15).toString(16) + str;
  343. l = qr.quotient;
  344. }
  345. return (this.isNegative() ? "-" : "") + "0x" + str;
  346. },
  347. toJSNumber: function (m) {
  348. return +o.toString(m);
  349. },
  350. valueOf: function (m) {
  351. return o.toJSNumber(m);
  352. }
  353. };
  354. return o;
  355. };
  356. var ZERO = bigInt([0], sign.positive);
  357. var ONE = bigInt([1], sign.positive);
  358. var MINUS_ONE = bigInt([1], sign.negative);
  359. var fnReturn = function (a) {
  360. if (typeof a === "undefined") return ZERO;
  361. return parse(a);
  362. };
  363. fnReturn.zero = ZERO;
  364. fnReturn.one = ONE;
  365. fnReturn.minusOne = MINUS_ONE;
  366. return fnReturn;
  367. })();
  368. if (typeof module !== "undefined") {
  369. module.exports = bigInt;
  370. }