integer.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808
  1. // Copyright 2009 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @fileoverview Defines an Integer class for representing (potentially)
  16. * infinite length two's-complement integer values.
  17. *
  18. * For the specific case of 64-bit integers, use goog.math.Long, which is more
  19. * efficient.
  20. *
  21. */
  22. goog.provide('goog.math.Integer');
  23. /**
  24. * Constructs a two's-complement integer an array containing bits of the
  25. * integer in 32-bit (signed) pieces, given in little-endian order (i.e.,
  26. * lowest-order bits in the first piece), and the sign of -1 or 0.
  27. *
  28. * See the from* functions below for other convenient ways of constructing
  29. * Integers.
  30. *
  31. * The internal representation of an integer is an array of 32-bit signed
  32. * pieces, along with a sign (0 or -1) that indicates the contents of all the
  33. * other 32-bit pieces out to infinity. We use 32-bit pieces because these are
  34. * the size of integers on which Javascript performs bit-operations. For
  35. * operations like addition and multiplication, we split each number into 16-bit
  36. * pieces, which can easily be multiplied within Javascript's floating-point
  37. * representation without overflow or change in sign.
  38. *
  39. * @struct
  40. * @constructor
  41. * @param {Array<number>} bits Array containing the bits of the number.
  42. * @param {number} sign The sign of the number: -1 for negative and 0 positive.
  43. * @final
  44. */
  45. goog.math.Integer = function(bits, sign) {
  46. /**
  47. * @type {!Array<number>}
  48. * @private
  49. */
  50. this.bits_ = [];
  51. /**
  52. * @type {number}
  53. * @private
  54. */
  55. this.sign_ = sign;
  56. // Copy the 32-bit signed integer values passed in. We prune out those at the
  57. // top that equal the sign since they are redundant.
  58. var top = true;
  59. for (var i = bits.length - 1; i >= 0; i--) {
  60. var val = bits[i] | 0;
  61. if (!top || val != sign) {
  62. this.bits_[i] = val;
  63. top = false;
  64. }
  65. }
  66. };
  67. // NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the
  68. // from* methods on which they depend.
  69. /**
  70. * A cache of the Integer representations of small integer values.
  71. * @type {!Object}
  72. * @private
  73. */
  74. goog.math.Integer.IntCache_ = {};
  75. /**
  76. * Returns an Integer representing the given (32-bit) integer value.
  77. * @param {number} value A 32-bit integer value.
  78. * @return {!goog.math.Integer} The corresponding Integer value.
  79. */
  80. goog.math.Integer.fromInt = function(value) {
  81. if (-128 <= value && value < 128) {
  82. var cachedObj = goog.math.Integer.IntCache_[value];
  83. if (cachedObj) {
  84. return cachedObj;
  85. }
  86. }
  87. var obj = new goog.math.Integer([value | 0], value < 0 ? -1 : 0);
  88. if (-128 <= value && value < 128) {
  89. goog.math.Integer.IntCache_[value] = obj;
  90. }
  91. return obj;
  92. };
  93. /**
  94. * Returns an Integer representing the given value, provided that it is a finite
  95. * number. Otherwise, zero is returned.
  96. * @param {number} value The value in question.
  97. * @return {!goog.math.Integer} The corresponding Integer value.
  98. */
  99. goog.math.Integer.fromNumber = function(value) {
  100. if (isNaN(value) || !isFinite(value)) {
  101. return goog.math.Integer.ZERO;
  102. } else if (value < 0) {
  103. return goog.math.Integer.fromNumber(-value).negate();
  104. } else {
  105. var bits = [];
  106. var pow = 1;
  107. for (var i = 0; value >= pow; i++) {
  108. bits[i] = (value / pow) | 0;
  109. pow *= goog.math.Integer.TWO_PWR_32_DBL_;
  110. }
  111. return new goog.math.Integer(bits, 0);
  112. }
  113. };
  114. /**
  115. * Returns a Integer representing the value that comes by concatenating the
  116. * given entries, each is assumed to be 32 signed bits, given in little-endian
  117. * order (lowest order bits in the lowest index), and sign-extending the highest
  118. * order 32-bit value.
  119. * @param {Array<number>} bits The bits of the number, in 32-bit signed pieces,
  120. * in little-endian order.
  121. * @return {!goog.math.Integer} The corresponding Integer value.
  122. */
  123. goog.math.Integer.fromBits = function(bits) {
  124. var high = bits[bits.length - 1];
  125. return new goog.math.Integer(bits, high & (1 << 31) ? -1 : 0);
  126. };
  127. /**
  128. * Returns an Integer representation of the given string, written using the
  129. * given radix.
  130. * @param {string} str The textual representation of the Integer.
  131. * @param {number=} opt_radix The radix in which the text is written.
  132. * @return {!goog.math.Integer} The corresponding Integer value.
  133. */
  134. goog.math.Integer.fromString = function(str, opt_radix) {
  135. if (str.length == 0) {
  136. throw Error('number format error: empty string');
  137. }
  138. var radix = opt_radix || 10;
  139. if (radix < 2 || 36 < radix) {
  140. throw Error('radix out of range: ' + radix);
  141. }
  142. if (str.charAt(0) == '-') {
  143. return goog.math.Integer.fromString(str.substring(1), radix).negate();
  144. } else if (str.indexOf('-') >= 0) {
  145. throw Error('number format error: interior "-" character');
  146. }
  147. // Do several (8) digits each time through the loop, so as to
  148. // minimize the calls to the very expensive emulated div.
  149. var radixToPower = goog.math.Integer.fromNumber(Math.pow(radix, 8));
  150. var result = goog.math.Integer.ZERO;
  151. for (var i = 0; i < str.length; i += 8) {
  152. var size = Math.min(8, str.length - i);
  153. var value = parseInt(str.substring(i, i + size), radix);
  154. if (size < 8) {
  155. var power = goog.math.Integer.fromNumber(Math.pow(radix, size));
  156. result = result.multiply(power).add(goog.math.Integer.fromNumber(value));
  157. } else {
  158. result = result.multiply(radixToPower);
  159. result = result.add(goog.math.Integer.fromNumber(value));
  160. }
  161. }
  162. return result;
  163. };
  164. /**
  165. * A number used repeatedly in calculations. This must appear before the first
  166. * call to the from* functions below.
  167. * @type {number}
  168. * @private
  169. */
  170. goog.math.Integer.TWO_PWR_32_DBL_ = (1 << 16) * (1 << 16);
  171. /** @type {!goog.math.Integer} */
  172. goog.math.Integer.ZERO = goog.math.Integer.fromInt(0);
  173. /** @type {!goog.math.Integer} */
  174. goog.math.Integer.ONE = goog.math.Integer.fromInt(1);
  175. /**
  176. * @type {!goog.math.Integer}
  177. * @private
  178. */
  179. goog.math.Integer.TWO_PWR_24_ = goog.math.Integer.fromInt(1 << 24);
  180. /**
  181. * Returns the value, assuming it is a 32-bit integer.
  182. * @return {number} The corresponding int value.
  183. */
  184. goog.math.Integer.prototype.toInt = function() {
  185. return this.bits_.length > 0 ? this.bits_[0] : this.sign_;
  186. };
  187. /** @return {number} The closest floating-point representation to this value. */
  188. goog.math.Integer.prototype.toNumber = function() {
  189. if (this.isNegative()) {
  190. return -this.negate().toNumber();
  191. } else {
  192. var val = 0;
  193. var pow = 1;
  194. for (var i = 0; i < this.bits_.length; i++) {
  195. val += this.getBitsUnsigned(i) * pow;
  196. pow *= goog.math.Integer.TWO_PWR_32_DBL_;
  197. }
  198. return val;
  199. }
  200. };
  201. /**
  202. * @param {number=} opt_radix The radix in which the text should be written.
  203. * @return {string} The textual representation of this value.
  204. * @override
  205. */
  206. goog.math.Integer.prototype.toString = function(opt_radix) {
  207. var radix = opt_radix || 10;
  208. if (radix < 2 || 36 < radix) {
  209. throw Error('radix out of range: ' + radix);
  210. }
  211. if (this.isZero()) {
  212. return '0';
  213. } else if (this.isNegative()) {
  214. return '-' + this.negate().toString(radix);
  215. }
  216. // Do several (6) digits each time through the loop, so as to
  217. // minimize the calls to the very expensive emulated div.
  218. var radixToPower = goog.math.Integer.fromNumber(Math.pow(radix, 6));
  219. var rem = this;
  220. var result = '';
  221. while (true) {
  222. var remDiv = rem.divide(radixToPower);
  223. // The right shifting fixes negative values in the case when
  224. // intval >= 2^31; for more details see
  225. // https://github.com/google/closure-library/pull/498
  226. var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt() >>> 0;
  227. var digits = intval.toString(radix);
  228. rem = remDiv;
  229. if (rem.isZero()) {
  230. return digits + result;
  231. } else {
  232. while (digits.length < 6) {
  233. digits = '0' + digits;
  234. }
  235. result = '' + digits + result;
  236. }
  237. }
  238. };
  239. /**
  240. * Returns the index-th 32-bit (signed) piece of the Integer according to
  241. * little-endian order (i.e., index 0 contains the smallest bits).
  242. * @param {number} index The index in question.
  243. * @return {number} The requested 32-bits as a signed number.
  244. */
  245. goog.math.Integer.prototype.getBits = function(index) {
  246. if (index < 0) {
  247. return 0; // Allowing this simplifies bit shifting operations below...
  248. } else if (index < this.bits_.length) {
  249. return this.bits_[index];
  250. } else {
  251. return this.sign_;
  252. }
  253. };
  254. /**
  255. * Returns the index-th 32-bit piece as an unsigned number.
  256. * @param {number} index The index in question.
  257. * @return {number} The requested 32-bits as an unsigned number.
  258. */
  259. goog.math.Integer.prototype.getBitsUnsigned = function(index) {
  260. var val = this.getBits(index);
  261. return val >= 0 ? val : goog.math.Integer.TWO_PWR_32_DBL_ + val;
  262. };
  263. /** @return {number} The sign bit of this number, -1 or 0. */
  264. goog.math.Integer.prototype.getSign = function() {
  265. return this.sign_;
  266. };
  267. /** @return {boolean} Whether this value is zero. */
  268. goog.math.Integer.prototype.isZero = function() {
  269. if (this.sign_ != 0) {
  270. return false;
  271. }
  272. for (var i = 0; i < this.bits_.length; i++) {
  273. if (this.bits_[i] != 0) {
  274. return false;
  275. }
  276. }
  277. return true;
  278. };
  279. /** @return {boolean} Whether this value is negative. */
  280. goog.math.Integer.prototype.isNegative = function() {
  281. return this.sign_ == -1;
  282. };
  283. /** @return {boolean} Whether this value is odd. */
  284. goog.math.Integer.prototype.isOdd = function() {
  285. return (this.bits_.length == 0) && (this.sign_ == -1) ||
  286. (this.bits_.length > 0) && ((this.bits_[0] & 1) != 0);
  287. };
  288. /**
  289. * @param {goog.math.Integer} other Integer to compare against.
  290. * @return {boolean} Whether this Integer equals the other.
  291. */
  292. goog.math.Integer.prototype.equals = function(other) {
  293. if (this.sign_ != other.sign_) {
  294. return false;
  295. }
  296. var len = Math.max(this.bits_.length, other.bits_.length);
  297. for (var i = 0; i < len; i++) {
  298. if (this.getBits(i) != other.getBits(i)) {
  299. return false;
  300. }
  301. }
  302. return true;
  303. };
  304. /**
  305. * @param {goog.math.Integer} other Integer to compare against.
  306. * @return {boolean} Whether this Integer does not equal the other.
  307. */
  308. goog.math.Integer.prototype.notEquals = function(other) {
  309. return !this.equals(other);
  310. };
  311. /**
  312. * @param {goog.math.Integer} other Integer to compare against.
  313. * @return {boolean} Whether this Integer is greater than the other.
  314. */
  315. goog.math.Integer.prototype.greaterThan = function(other) {
  316. return this.compare(other) > 0;
  317. };
  318. /**
  319. * @param {goog.math.Integer} other Integer to compare against.
  320. * @return {boolean} Whether this Integer is greater than or equal to the other.
  321. */
  322. goog.math.Integer.prototype.greaterThanOrEqual = function(other) {
  323. return this.compare(other) >= 0;
  324. };
  325. /**
  326. * @param {goog.math.Integer} other Integer to compare against.
  327. * @return {boolean} Whether this Integer is less than the other.
  328. */
  329. goog.math.Integer.prototype.lessThan = function(other) {
  330. return this.compare(other) < 0;
  331. };
  332. /**
  333. * @param {goog.math.Integer} other Integer to compare against.
  334. * @return {boolean} Whether this Integer is less than or equal to the other.
  335. */
  336. goog.math.Integer.prototype.lessThanOrEqual = function(other) {
  337. return this.compare(other) <= 0;
  338. };
  339. /**
  340. * Compares this Integer with the given one.
  341. * @param {goog.math.Integer} other Integer to compare against.
  342. * @return {number} 0 if they are the same, 1 if the this is greater, and -1
  343. * if the given one is greater.
  344. */
  345. goog.math.Integer.prototype.compare = function(other) {
  346. var diff = this.subtract(other);
  347. if (diff.isNegative()) {
  348. return -1;
  349. } else if (diff.isZero()) {
  350. return 0;
  351. } else {
  352. return +1;
  353. }
  354. };
  355. /**
  356. * Returns an integer with only the first numBits bits of this value, sign
  357. * extended from the final bit.
  358. * @param {number} numBits The number of bits by which to shift.
  359. * @return {!goog.math.Integer} The shorted integer value.
  360. */
  361. goog.math.Integer.prototype.shorten = function(numBits) {
  362. var arr_index = (numBits - 1) >> 5;
  363. var bit_index = (numBits - 1) % 32;
  364. var bits = [];
  365. for (var i = 0; i < arr_index; i++) {
  366. bits[i] = this.getBits(i);
  367. }
  368. var sigBits = bit_index == 31 ? 0xFFFFFFFF : (1 << (bit_index + 1)) - 1;
  369. var val = this.getBits(arr_index) & sigBits;
  370. if (val & (1 << bit_index)) {
  371. val |= 0xFFFFFFFF - sigBits;
  372. bits[arr_index] = val;
  373. return new goog.math.Integer(bits, -1);
  374. } else {
  375. bits[arr_index] = val;
  376. return new goog.math.Integer(bits, 0);
  377. }
  378. };
  379. /** @return {!goog.math.Integer} The negation of this value. */
  380. goog.math.Integer.prototype.negate = function() {
  381. return this.not().add(goog.math.Integer.ONE);
  382. };
  383. /**
  384. * Returns the sum of this and the given Integer.
  385. * @param {goog.math.Integer} other The Integer to add to this.
  386. * @return {!goog.math.Integer} The Integer result.
  387. */
  388. goog.math.Integer.prototype.add = function(other) {
  389. var len = Math.max(this.bits_.length, other.bits_.length);
  390. var arr = [];
  391. var carry = 0;
  392. for (var i = 0; i <= len; i++) {
  393. var a1 = this.getBits(i) >>> 16;
  394. var a0 = this.getBits(i) & 0xFFFF;
  395. var b1 = other.getBits(i) >>> 16;
  396. var b0 = other.getBits(i) & 0xFFFF;
  397. var c0 = carry + a0 + b0;
  398. var c1 = (c0 >>> 16) + a1 + b1;
  399. carry = c1 >>> 16;
  400. c0 &= 0xFFFF;
  401. c1 &= 0xFFFF;
  402. arr[i] = (c1 << 16) | c0;
  403. }
  404. return goog.math.Integer.fromBits(arr);
  405. };
  406. /**
  407. * Returns the difference of this and the given Integer.
  408. * @param {goog.math.Integer} other The Integer to subtract from this.
  409. * @return {!goog.math.Integer} The Integer result.
  410. */
  411. goog.math.Integer.prototype.subtract = function(other) {
  412. return this.add(other.negate());
  413. };
  414. /**
  415. * Returns the product of this and the given Integer.
  416. * @param {goog.math.Integer} other The Integer to multiply against this.
  417. * @return {!goog.math.Integer} The product of this and the other.
  418. */
  419. goog.math.Integer.prototype.multiply = function(other) {
  420. if (this.isZero()) {
  421. return goog.math.Integer.ZERO;
  422. } else if (other.isZero()) {
  423. return goog.math.Integer.ZERO;
  424. }
  425. if (this.isNegative()) {
  426. if (other.isNegative()) {
  427. return this.negate().multiply(other.negate());
  428. } else {
  429. return this.negate().multiply(other).negate();
  430. }
  431. } else if (other.isNegative()) {
  432. return this.multiply(other.negate()).negate();
  433. }
  434. // If both numbers are small, use float multiplication
  435. if (this.lessThan(goog.math.Integer.TWO_PWR_24_) &&
  436. other.lessThan(goog.math.Integer.TWO_PWR_24_)) {
  437. return goog.math.Integer.fromNumber(this.toNumber() * other.toNumber());
  438. }
  439. // Fill in an array of 16-bit products.
  440. var len = this.bits_.length + other.bits_.length;
  441. var arr = [];
  442. for (var i = 0; i < 2 * len; i++) {
  443. arr[i] = 0;
  444. }
  445. for (var i = 0; i < this.bits_.length; i++) {
  446. for (var j = 0; j < other.bits_.length; j++) {
  447. var a1 = this.getBits(i) >>> 16;
  448. var a0 = this.getBits(i) & 0xFFFF;
  449. var b1 = other.getBits(j) >>> 16;
  450. var b0 = other.getBits(j) & 0xFFFF;
  451. arr[2 * i + 2 * j] += a0 * b0;
  452. goog.math.Integer.carry16_(arr, 2 * i + 2 * j);
  453. arr[2 * i + 2 * j + 1] += a1 * b0;
  454. goog.math.Integer.carry16_(arr, 2 * i + 2 * j + 1);
  455. arr[2 * i + 2 * j + 1] += a0 * b1;
  456. goog.math.Integer.carry16_(arr, 2 * i + 2 * j + 1);
  457. arr[2 * i + 2 * j + 2] += a1 * b1;
  458. goog.math.Integer.carry16_(arr, 2 * i + 2 * j + 2);
  459. }
  460. }
  461. // Combine the 16-bit values into 32-bit values.
  462. for (var i = 0; i < len; i++) {
  463. arr[i] = (arr[2 * i + 1] << 16) | arr[2 * i];
  464. }
  465. for (var i = len; i < 2 * len; i++) {
  466. arr[i] = 0;
  467. }
  468. return new goog.math.Integer(arr, 0);
  469. };
  470. /**
  471. * Carries any overflow from the given index into later entries.
  472. * @param {Array<number>} bits Array of 16-bit values in little-endian order.
  473. * @param {number} index The index in question.
  474. * @private
  475. */
  476. goog.math.Integer.carry16_ = function(bits, index) {
  477. while ((bits[index] & 0xFFFF) != bits[index]) {
  478. bits[index + 1] += bits[index] >>> 16;
  479. bits[index] &= 0xFFFF;
  480. index++;
  481. }
  482. };
  483. /**
  484. * Returns "this" Integer divided by the given one. Both "this" and the given
  485. * Integer MUST be positive.
  486. *
  487. * This method is only needed for very large numbers (>10^308),
  488. * for which the original division algorithm gets into an infinite
  489. * loop (see https://github.com/google/closure-library/issues/500).
  490. *
  491. * The algorithm has some possible performance enhancements (or
  492. * could be rewritten entirely), it's just an initial solution for
  493. * the issue linked above.
  494. *
  495. * @param {!goog.math.Integer} other The Integer to divide "this" by.
  496. * @return {!goog.math.Integer} "this" value divided by the given one.
  497. * @private
  498. */
  499. goog.math.Integer.prototype.slowDivide_ = function(other) {
  500. if (this.isNegative() || other.isNegative()) {
  501. throw Error('slowDivide_ only works with positive integers.');
  502. }
  503. var twoPower = goog.math.Integer.ONE;
  504. var multiple = other;
  505. // First we have to figure out what the highest bit of the result
  506. // is, so we increase "twoPower" and "multiple" until "multiple"
  507. // exceeds "this".
  508. while (multiple.lessThanOrEqual(this)) {
  509. twoPower = twoPower.shiftLeft(1);
  510. multiple = multiple.shiftLeft(1);
  511. }
  512. // Rewind by one power of two, giving us the highest bit of the
  513. // result.
  514. var res = twoPower.shiftRight(1);
  515. var total = multiple.shiftRight(1);
  516. // Now we starting decreasing "multiple" and "twoPower" to find the
  517. // rest of the bits of the result.
  518. var total2;
  519. multiple = multiple.shiftRight(2);
  520. twoPower = twoPower.shiftRight(2);
  521. while (!multiple.isZero()) {
  522. // whenever we can add "multiple" to the total and not exceed
  523. // "this", that means we've found a 1 bit. Else we've found a 0
  524. // and don't need to add to the result.
  525. total2 = total.add(multiple);
  526. if (total2.lessThanOrEqual(this)) {
  527. res = res.add(twoPower);
  528. total = total2;
  529. }
  530. multiple = multiple.shiftRight(1);
  531. twoPower = twoPower.shiftRight(1);
  532. }
  533. return res;
  534. };
  535. /**
  536. * Returns this Integer divided by the given one.
  537. * @param {!goog.math.Integer} other The Integer to divide this by.
  538. * @return {!goog.math.Integer} This value divided by the given one.
  539. */
  540. goog.math.Integer.prototype.divide = function(other) {
  541. if (other.isZero()) {
  542. throw Error('division by zero');
  543. } else if (this.isZero()) {
  544. return goog.math.Integer.ZERO;
  545. }
  546. if (this.isNegative()) {
  547. if (other.isNegative()) {
  548. return this.negate().divide(other.negate());
  549. } else {
  550. return this.negate().divide(other).negate();
  551. }
  552. } else if (other.isNegative()) {
  553. return this.divide(other.negate()).negate();
  554. }
  555. // Have to degrade to slowDivide for Very Large Numbers, because
  556. // they're out of range for the floating-point approximation
  557. // technique used below.
  558. if (this.bits_.length > 30) {
  559. return this.slowDivide_(other);
  560. }
  561. // Repeat the following until the remainder is less than other: find a
  562. // floating-point that approximates remainder / other *from below*, add this
  563. // into the result, and subtract it from the remainder. It is critical that
  564. // the approximate value is less than or equal to the real value so that the
  565. // remainder never becomes negative.
  566. var res = goog.math.Integer.ZERO;
  567. var rem = this;
  568. while (rem.greaterThanOrEqual(other)) {
  569. // Approximate the result of division. This may be a little greater or
  570. // smaller than the actual value.
  571. var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber()));
  572. // We will tweak the approximate result by changing it in the 48-th digit or
  573. // the smallest non-fractional digit, whichever is larger.
  574. var log2 = Math.ceil(Math.log(approx) / Math.LN2);
  575. var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48);
  576. // Decrease the approximation until it is smaller than the remainder. Note
  577. // that if it is too large, the product overflows and is negative.
  578. var approxRes = goog.math.Integer.fromNumber(approx);
  579. var approxRem = approxRes.multiply(other);
  580. while (approxRem.isNegative() || approxRem.greaterThan(rem)) {
  581. approx -= delta;
  582. approxRes = goog.math.Integer.fromNumber(approx);
  583. approxRem = approxRes.multiply(other);
  584. }
  585. // We know the answer can't be zero... and actually, zero would cause
  586. // infinite recursion since we would make no progress.
  587. if (approxRes.isZero()) {
  588. approxRes = goog.math.Integer.ONE;
  589. }
  590. res = res.add(approxRes);
  591. rem = rem.subtract(approxRem);
  592. }
  593. return res;
  594. };
  595. /**
  596. * Returns this Integer modulo the given one.
  597. * @param {!goog.math.Integer} other The Integer by which to mod.
  598. * @return {!goog.math.Integer} This value modulo the given one.
  599. */
  600. goog.math.Integer.prototype.modulo = function(other) {
  601. return this.subtract(this.divide(other).multiply(other));
  602. };
  603. /** @return {!goog.math.Integer} The bitwise-NOT of this value. */
  604. goog.math.Integer.prototype.not = function() {
  605. var len = this.bits_.length;
  606. var arr = [];
  607. for (var i = 0; i < len; i++) {
  608. arr[i] = ~this.bits_[i];
  609. }
  610. return new goog.math.Integer(arr, ~this.sign_);
  611. };
  612. /**
  613. * Returns the bitwise-AND of this Integer and the given one.
  614. * @param {goog.math.Integer} other The Integer to AND with this.
  615. * @return {!goog.math.Integer} The bitwise-AND of this and the other.
  616. */
  617. goog.math.Integer.prototype.and = function(other) {
  618. var len = Math.max(this.bits_.length, other.bits_.length);
  619. var arr = [];
  620. for (var i = 0; i < len; i++) {
  621. arr[i] = this.getBits(i) & other.getBits(i);
  622. }
  623. return new goog.math.Integer(arr, this.sign_ & other.sign_);
  624. };
  625. /**
  626. * Returns the bitwise-OR of this Integer and the given one.
  627. * @param {goog.math.Integer} other The Integer to OR with this.
  628. * @return {!goog.math.Integer} The bitwise-OR of this and the other.
  629. */
  630. goog.math.Integer.prototype.or = function(other) {
  631. var len = Math.max(this.bits_.length, other.bits_.length);
  632. var arr = [];
  633. for (var i = 0; i < len; i++) {
  634. arr[i] = this.getBits(i) | other.getBits(i);
  635. }
  636. return new goog.math.Integer(arr, this.sign_ | other.sign_);
  637. };
  638. /**
  639. * Returns the bitwise-XOR of this Integer and the given one.
  640. * @param {goog.math.Integer} other The Integer to XOR with this.
  641. * @return {!goog.math.Integer} The bitwise-XOR of this and the other.
  642. */
  643. goog.math.Integer.prototype.xor = function(other) {
  644. var len = Math.max(this.bits_.length, other.bits_.length);
  645. var arr = [];
  646. for (var i = 0; i < len; i++) {
  647. arr[i] = this.getBits(i) ^ other.getBits(i);
  648. }
  649. return new goog.math.Integer(arr, this.sign_ ^ other.sign_);
  650. };
  651. /**
  652. * Returns this value with bits shifted to the left by the given amount.
  653. * @param {number} numBits The number of bits by which to shift.
  654. * @return {!goog.math.Integer} This shifted to the left by the given amount.
  655. */
  656. goog.math.Integer.prototype.shiftLeft = function(numBits) {
  657. var arr_delta = numBits >> 5;
  658. var bit_delta = numBits % 32;
  659. var len = this.bits_.length + arr_delta + (bit_delta > 0 ? 1 : 0);
  660. var arr = [];
  661. for (var i = 0; i < len; i++) {
  662. if (bit_delta > 0) {
  663. arr[i] = (this.getBits(i - arr_delta) << bit_delta) |
  664. (this.getBits(i - arr_delta - 1) >>> (32 - bit_delta));
  665. } else {
  666. arr[i] = this.getBits(i - arr_delta);
  667. }
  668. }
  669. return new goog.math.Integer(arr, this.sign_);
  670. };
  671. /**
  672. * Returns this value with bits shifted to the right by the given amount.
  673. * @param {number} numBits The number of bits by which to shift.
  674. * @return {!goog.math.Integer} This shifted to the right by the given amount.
  675. */
  676. goog.math.Integer.prototype.shiftRight = function(numBits) {
  677. var arr_delta = numBits >> 5;
  678. var bit_delta = numBits % 32;
  679. var len = this.bits_.length - arr_delta;
  680. var arr = [];
  681. for (var i = 0; i < len; i++) {
  682. if (bit_delta > 0) {
  683. arr[i] = (this.getBits(i + arr_delta) >>> bit_delta) |
  684. (this.getBits(i + arr_delta + 1) << (32 - bit_delta));
  685. } else {
  686. arr[i] = this.getBits(i + arr_delta);
  687. }
  688. }
  689. return new goog.math.Integer(arr, this.sign_);
  690. };