UNPKG

37 kBJavaScriptView Raw
1/*
2 Copyright 2013 Daniel Wirtz <dcode@dcode.io>
3 Copyright 2009 The Closure Library Authors. All Rights Reserved.
4
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
8
9 http://www.apache.org/licenses/LICENSE-2.0
10
11 Unless required by applicable law or agreed to in writing, software
12 distributed under the License is distributed on an "AS-IS" BASIS,
13 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 See the License for the specific language governing permissions and
15 limitations under the License.
16 */
17
18/**
19 * @license long.js (c) 2013 Daniel Wirtz <dcode@dcode.io>
20 * Released under the Apache License, Version 2.0
21 * see: https://github.com/dcodeIO/long.js for details
22 */
23(function(global, factory) {
24
25 /* AMD */ if (typeof define === 'function' && define["amd"])
26 define([], factory);
27 /* CommonJS */ else if (typeof require === 'function' && typeof module === "object" && module && module["exports"])
28 module["exports"] = factory();
29 /* Global */ else
30 (global["dcodeIO"] = global["dcodeIO"] || {})["Long"] = factory();
31
32})(this, function() {
33 "use strict";
34
35 /**
36 * Constructs a 64 bit two's-complement integer, given its low and high 32 bit values as *signed* integers.
37 * See the from* functions below for more convenient ways of constructing Longs.
38 * @exports Long
39 * @class A Long class for representing a 64 bit two's-complement integer value.
40 * @param {number} low The low (signed) 32 bits of the long
41 * @param {number} high The high (signed) 32 bits of the long
42 * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
43 * @constructor
44 */
45 function Long(low, high, unsigned) {
46
47 /**
48 * The low 32 bits as a signed value.
49 * @type {number}
50 * @expose
51 */
52 this.low = low|0;
53
54 /**
55 * The high 32 bits as a signed value.
56 * @type {number}
57 * @expose
58 */
59 this.high = high|0;
60
61 /**
62 * Whether unsigned or not.
63 * @type {boolean}
64 * @expose
65 */
66 this.unsigned = !!unsigned;
67 }
68
69 // The internal representation of a long is the two given signed, 32-bit values.
70 // We use 32-bit pieces because these are the size of integers on which
71 // Javascript performs bit-operations. For operations like addition and
72 // multiplication, we split each number into 16 bit pieces, which can easily be
73 // multiplied within Javascript's floating-point representation without overflow
74 // or change in sign.
75 //
76 // In the algorithms below, we frequently reduce the negative case to the
77 // positive case by negating the input(s) and then post-processing the result.
78 // Note that we must ALWAYS check specially whether those values are MIN_VALUE
79 // (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as
80 // a positive number, it overflows back into a negative). Not handling this
81 // case would often result in infinite recursion.
82 //
83 // Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the from*
84 // methods on which they depend.
85
86 /**
87 * An indicator used to reliably determine if an object is a Long or not.
88 * @type {boolean}
89 * @const
90 * @expose
91 * @private
92 */
93 Long.__isLong__;
94
95 Object.defineProperty(Long.prototype, "__isLong__", {
96 value: true,
97 enumerable: false,
98 configurable: false
99 });
100
101 /**
102 * Tests if the specified object is a Long.
103 * @param {*} obj Object
104 * @returns {boolean}
105 * @expose
106 */
107 Long.isLong = function isLong(obj) {
108 return (obj && obj["__isLong__"]) === true;
109 };
110
111 /**
112 * A cache of the Long representations of small integer values.
113 * @type {!Object}
114 * @inner
115 */
116 var INT_CACHE = {};
117
118 /**
119 * A cache of the Long representations of small unsigned integer values.
120 * @type {!Object}
121 * @inner
122 */
123 var UINT_CACHE = {};
124
125 /**
126 * Returns a Long representing the given 32 bit integer value.
127 * @param {number} value The 32 bit integer in question
128 * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
129 * @returns {!Long} The corresponding Long value
130 * @expose
131 */
132 Long.fromInt = function fromInt(value, unsigned) {
133 var obj, cachedObj, cache;
134 if (!unsigned) {
135 value = value | 0;
136 if (cache = (-128 <= value && value < 128)) {
137 cachedObj = INT_CACHE[value];
138 if (cachedObj)
139 return cachedObj;
140 }
141 obj = new Long(value, value < 0 ? -1 : 0, false);
142 if (cache)
143 INT_CACHE[value] = obj;
144 return obj;
145 } else {
146 value = value >>> 0;
147 if (cache = (0 <= value && value < 256)) {
148 cachedObj = UINT_CACHE[value];
149 if (cachedObj)
150 return cachedObj;
151 }
152 obj = new Long(value, (value | 0) < 0 ? -1 : 0, true);
153 if (cache)
154 UINT_CACHE[value] = obj;
155 return obj;
156 }
157 };
158
159 /**
160 * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned.
161 * @param {number} value The number in question
162 * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
163 * @returns {!Long} The corresponding Long value
164 * @expose
165 */
166 Long.fromNumber = function fromNumber(value, unsigned) {
167 unsigned = !!unsigned;
168 if (isNaN(value) || !isFinite(value))
169 return Long.ZERO;
170 if (!unsigned && value <= -TWO_PWR_63_DBL)
171 return Long.MIN_VALUE;
172 if (!unsigned && value + 1 >= TWO_PWR_63_DBL)
173 return Long.MAX_VALUE;
174 if (unsigned && value >= TWO_PWR_64_DBL)
175 return Long.MAX_UNSIGNED_VALUE;
176 if (value < 0)
177 return Long.fromNumber(-value, unsigned).neg();
178 return new Long((value % TWO_PWR_32_DBL) | 0, (value / TWO_PWR_32_DBL) | 0, unsigned);
179 };
180
181 /**
182 * Returns a Long representing the 64 bit integer that comes by concatenating the given low and high bits. Each is
183 * assumed to use 32 bits.
184 * @param {number} lowBits The low 32 bits
185 * @param {number} highBits The high 32 bits
186 * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
187 * @returns {!Long} The corresponding Long value
188 * @expose
189 */
190 Long.fromBits = function fromBits(lowBits, highBits, unsigned) {
191 return new Long(lowBits, highBits, unsigned);
192 };
193
194 /**
195 * Returns a Long representation of the given string, written using the specified radix.
196 * @param {string} str The textual representation of the Long
197 * @param {(boolean|number)=} unsigned Whether unsigned or not, defaults to `false` for signed
198 * @param {number=} radix The radix in which the text is written (2-36), defaults to 10
199 * @returns {!Long} The corresponding Long value
200 * @expose
201 */
202 Long.fromString = function fromString(str, unsigned, radix) {
203 if (str.length === 0)
204 throw Error('number format error: empty string');
205 if (str === "NaN" || str === "Infinity" || str === "+Infinity" || str === "-Infinity")
206 return Long.ZERO;
207 if (typeof unsigned === 'number') // For goog.math.long compatibility
208 radix = unsigned,
209 unsigned = false;
210 radix = radix || 10;
211 if (radix < 2 || 36 < radix)
212 throw Error('radix out of range: ' + radix);
213
214 var p;
215 if ((p = str.indexOf('-')) > 0)
216 throw Error('number format error: interior "-" character: ' + str);
217 else if (p === 0)
218 return Long.fromString(str.substring(1), unsigned, radix).neg();
219
220 // Do several (8) digits each time through the loop, so as to
221 // minimize the calls to the very expensive emulated div.
222 var radixToPower = Long.fromNumber(Math.pow(radix, 8));
223
224 var result = Long.ZERO;
225 for (var i = 0; i < str.length; i += 8) {
226 var size = Math.min(8, str.length - i);
227 var value = parseInt(str.substring(i, i + size), radix);
228 if (size < 8) {
229 var power = Long.fromNumber(Math.pow(radix, size));
230 result = result.mul(power).add(Long.fromNumber(value));
231 } else {
232 result = result.mul(radixToPower);
233 result = result.add(Long.fromNumber(value));
234 }
235 }
236 result.unsigned = unsigned;
237 return result;
238 };
239
240 /**
241 * Converts the specified value to a Long.
242 * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val Value
243 * @returns {!Long}
244 * @expose
245 */
246 Long.fromValue = function fromValue(val) {
247 if (val /* is compatible */ instanceof Long)
248 return val;
249 if (typeof val === 'number')
250 return Long.fromNumber(val);
251 if (typeof val === 'string')
252 return Long.fromString(val);
253 // Throws for non-objects, converts non-instanceof Long:
254 return new Long(val.low, val.high, val.unsigned);
255 };
256
257 // NOTE: the compiler should inline these constant values below and then remove these variables, so there should be
258 // no runtime penalty for these.
259
260 /**
261 * @type {number}
262 * @const
263 * @inner
264 */
265 var TWO_PWR_16_DBL = 1 << 16;
266
267 /**
268 * @type {number}
269 * @const
270 * @inner
271 */
272 var TWO_PWR_24_DBL = 1 << 24;
273
274 /**
275 * @type {number}
276 * @const
277 * @inner
278 */
279 var TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL;
280
281 /**
282 * @type {number}
283 * @const
284 * @inner
285 */
286 var TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL;
287
288 /**
289 * @type {number}
290 * @const
291 * @inner
292 */
293 var TWO_PWR_63_DBL = TWO_PWR_64_DBL / 2;
294
295 /**
296 * @type {!Long}
297 * @const
298 * @inner
299 */
300 var TWO_PWR_24 = Long.fromInt(TWO_PWR_24_DBL);
301
302 /**
303 * Signed zero.
304 * @type {!Long}
305 * @expose
306 */
307 Long.ZERO = Long.fromInt(0);
308
309 /**
310 * Unsigned zero.
311 * @type {!Long}
312 * @expose
313 */
314 Long.UZERO = Long.fromInt(0, true);
315
316 /**
317 * Signed one.
318 * @type {!Long}
319 * @expose
320 */
321 Long.ONE = Long.fromInt(1);
322
323 /**
324 * Unsigned one.
325 * @type {!Long}
326 * @expose
327 */
328 Long.UONE = Long.fromInt(1, true);
329
330 /**
331 * Signed negative one.
332 * @type {!Long}
333 * @expose
334 */
335 Long.NEG_ONE = Long.fromInt(-1);
336
337 /**
338 * Maximum signed value.
339 * @type {!Long}
340 * @expose
341 */
342 Long.MAX_VALUE = new Long(0xFFFFFFFF|0, 0x7FFFFFFF|0, false);
343
344 /**
345 * Maximum unsigned value.
346 * @type {!Long}
347 * @expose
348 */
349 Long.MAX_UNSIGNED_VALUE = new Long(0xFFFFFFFF|0, 0xFFFFFFFF|0, true);
350
351 /**
352 * Minimum signed value.
353 * @type {!Long}
354 * @expose
355 */
356 Long.MIN_VALUE = new Long(0, 0x80000000|0, false);
357
358 /**
359 * @alias Long.prototype
360 * @inner
361 */
362 var LongPrototype = Long.prototype;
363
364 /**
365 * Converts the Long to a 32 bit integer, assuming it is a 32 bit integer.
366 * @returns {number}
367 * @expose
368 */
369 LongPrototype.toInt = function toInt() {
370 return this.unsigned ? this.low >>> 0 : this.low;
371 };
372
373 /**
374 * Converts the Long to a the nearest floating-point representation of this value (double, 53 bit mantissa).
375 * @returns {number}
376 * @expose
377 */
378 LongPrototype.toNumber = function toNumber() {
379 if (this.unsigned) {
380 return ((this.high >>> 0) * TWO_PWR_32_DBL) + (this.low >>> 0);
381 }
382 return this.high * TWO_PWR_32_DBL + (this.low >>> 0);
383 };
384
385 /**
386 * Converts the Long to a string written in the specified radix.
387 * @param {number=} radix Radix (2-36), defaults to 10
388 * @returns {string}
389 * @override
390 * @throws {RangeError} If `radix` is out of range
391 * @expose
392 */
393 LongPrototype.toString = function toString(radix) {
394 radix = radix || 10;
395 if (radix < 2 || 36 < radix)
396 throw RangeError('radix out of range: ' + radix);
397 if (this.isZero())
398 return '0';
399 var rem;
400 if (this.isNegative()) { // Unsigned Longs are never negative
401 if (this.eq(Long.MIN_VALUE)) {
402 // We need to change the Long value before it can be negated, so we remove
403 // the bottom-most digit in this base and then recurse to do the rest.
404 var radixLong = Long.fromNumber(radix);
405 var div = this.div(radixLong);
406 rem = div.mul(radixLong).sub(this);
407 return div.toString(radix) + rem.toInt().toString(radix);
408 } else
409 return '-' + this.neg().toString(radix);
410 }
411
412 // Do several (6) digits each time through the loop, so as to
413 // minimize the calls to the very expensive emulated div.
414 var radixToPower = Long.fromNumber(Math.pow(radix, 6), this.unsigned);
415 rem = this;
416 var result = '';
417 while (true) {
418 var remDiv = rem.div(radixToPower),
419 intval = rem.sub(remDiv.mul(radixToPower)).toInt() >>> 0,
420 digits = intval.toString(radix);
421 rem = remDiv;
422 if (rem.isZero())
423 return digits + result;
424 else {
425 while (digits.length < 6)
426 digits = '0' + digits;
427 result = '' + digits + result;
428 }
429 }
430 };
431
432 /**
433 * Gets the high 32 bits as a signed integer.
434 * @returns {number} Signed high bits
435 * @expose
436 */
437 LongPrototype.getHighBits = function getHighBits() {
438 return this.high;
439 };
440
441 /**
442 * Gets the high 32 bits as an unsigned integer.
443 * @returns {number} Unsigned high bits
444 * @expose
445 */
446 LongPrototype.getHighBitsUnsigned = function getHighBitsUnsigned() {
447 return this.high >>> 0;
448 };
449
450 /**
451 * Gets the low 32 bits as a signed integer.
452 * @returns {number} Signed low bits
453 * @expose
454 */
455 LongPrototype.getLowBits = function getLowBits() {
456 return this.low;
457 };
458
459 /**
460 * Gets the low 32 bits as an unsigned integer.
461 * @returns {number} Unsigned low bits
462 * @expose
463 */
464 LongPrototype.getLowBitsUnsigned = function getLowBitsUnsigned() {
465 return this.low >>> 0;
466 };
467
468 /**
469 * Gets the number of bits needed to represent the absolute value of this Long.
470 * @returns {number}
471 * @expose
472 */
473 LongPrototype.getNumBitsAbs = function getNumBitsAbs() {
474 if (this.isNegative()) // Unsigned Longs are never negative
475 return this.eq(Long.MIN_VALUE) ? 64 : this.neg().getNumBitsAbs();
476 var val = this.high != 0 ? this.high : this.low;
477 for (var bit = 31; bit > 0; bit--)
478 if ((val & (1 << bit)) != 0)
479 break;
480 return this.high != 0 ? bit + 33 : bit + 1;
481 };
482
483 /**
484 * Tests if this Long's value equals zero.
485 * @returns {boolean}
486 * @expose
487 */
488 LongPrototype.isZero = function isZero() {
489 return this.high === 0 && this.low === 0;
490 };
491
492 /**
493 * Tests if this Long's value is negative.
494 * @returns {boolean}
495 * @expose
496 */
497 LongPrototype.isNegative = function isNegative() {
498 return !this.unsigned && this.high < 0;
499 };
500
501 /**
502 * Tests if this Long's value is positive.
503 * @returns {boolean}
504 * @expose
505 */
506 LongPrototype.isPositive = function isPositive() {
507 return this.unsigned || this.high >= 0;
508 };
509
510 /**
511 * Tests if this Long's value is odd.
512 * @returns {boolean}
513 * @expose
514 */
515 LongPrototype.isOdd = function isOdd() {
516 return (this.low & 1) === 1;
517 };
518
519 /**
520 * Tests if this Long's value is even.
521 * @returns {boolean}
522 * @expose
523 */
524 LongPrototype.isEven = function isEven() {
525 return (this.low & 1) === 0;
526 };
527
528 /**
529 * Tests if this Long's value equals the specified's.
530 * @param {!Long|number|string} other Other value
531 * @returns {boolean}
532 * @expose
533 */
534 LongPrototype.equals = function equals(other) {
535 if (!Long.isLong(other))
536 other = Long.fromValue(other);
537 if (this.unsigned !== other.unsigned && (this.high >>> 31) === 1 && (other.high >>> 31) === 1)
538 return false;
539 return this.high === other.high && this.low === other.low;
540 };
541
542 /**
543 * Tests if this Long's value equals the specified's. This is an alias of {@link Long#equals}.
544 * @function
545 * @param {!Long|number|string} other Other value
546 * @returns {boolean}
547 * @expose
548 */
549 LongPrototype.eq = LongPrototype.equals;
550
551 /**
552 * Tests if this Long's value differs from the specified's.
553 * @param {!Long|number|string} other Other value
554 * @returns {boolean}
555 * @expose
556 */
557 LongPrototype.notEquals = function notEquals(other) {
558 return !this.eq(/* validates */ other);
559 };
560
561 /**
562 * Tests if this Long's value differs from the specified's. This is an alias of {@link Long#notEquals}.
563 * @function
564 * @param {!Long|number|string} other Other value
565 * @returns {boolean}
566 * @expose
567 */
568 LongPrototype.neq = LongPrototype.notEquals;
569
570 /**
571 * Tests if this Long's value is less than the specified's.
572 * @param {!Long|number|string} other Other value
573 * @returns {boolean}
574 * @expose
575 */
576 LongPrototype.lessThan = function lessThan(other) {
577 return this.compare(/* validates */ other) < 0;
578 };
579
580 /**
581 * Tests if this Long's value is less than the specified's. This is an alias of {@link Long#lessThan}.
582 * @function
583 * @param {!Long|number|string} other Other value
584 * @returns {boolean}
585 * @expose
586 */
587 LongPrototype.lt = LongPrototype.lessThan;
588
589 /**
590 * Tests if this Long's value is less than or equal the specified's.
591 * @param {!Long|number|string} other Other value
592 * @returns {boolean}
593 * @expose
594 */
595 LongPrototype.lessThanOrEqual = function lessThanOrEqual(other) {
596 return this.compare(/* validates */ other) <= 0;
597 };
598
599 /**
600 * Tests if this Long's value is less than or equal the specified's. This is an alias of {@link Long#lessThanOrEqual}.
601 * @function
602 * @param {!Long|number|string} other Other value
603 * @returns {boolean}
604 * @expose
605 */
606 LongPrototype.lte = LongPrototype.lessThanOrEqual;
607
608 /**
609 * Tests if this Long's value is greater than the specified's.
610 * @param {!Long|number|string} other Other value
611 * @returns {boolean}
612 * @expose
613 */
614 LongPrototype.greaterThan = function greaterThan(other) {
615 return this.compare(/* validates */ other) > 0;
616 };
617
618 /**
619 * Tests if this Long's value is greater than the specified's. This is an alias of {@link Long#greaterThan}.
620 * @function
621 * @param {!Long|number|string} other Other value
622 * @returns {boolean}
623 * @expose
624 */
625 LongPrototype.gt = LongPrototype.greaterThan;
626
627 /**
628 * Tests if this Long's value is greater than or equal the specified's.
629 * @param {!Long|number|string} other Other value
630 * @returns {boolean}
631 * @expose
632 */
633 LongPrototype.greaterThanOrEqual = function greaterThanOrEqual(other) {
634 return this.compare(/* validates */ other) >= 0;
635 };
636
637 /**
638 * Tests if this Long's value is greater than or equal the specified's. This is an alias of {@link Long#greaterThanOrEqual}.
639 * @function
640 * @param {!Long|number|string} other Other value
641 * @returns {boolean}
642 * @expose
643 */
644 LongPrototype.gte = LongPrototype.greaterThanOrEqual;
645
646 /**
647 * Compares this Long's value with the specified's.
648 * @param {!Long|number|string} other Other value
649 * @returns {number} 0 if they are the same, 1 if the this is greater and -1
650 * if the given one is greater
651 * @expose
652 */
653 LongPrototype.compare = function compare(other) {
654 if (!Long.isLong(other))
655 other = Long.fromValue(other);
656 if (this.eq(other))
657 return 0;
658 var thisNeg = this.isNegative(),
659 otherNeg = other.isNegative();
660 if (thisNeg && !otherNeg)
661 return -1;
662 if (!thisNeg && otherNeg)
663 return 1;
664 // At this point the sign bits are the same
665 if (!this.unsigned)
666 return this.sub(other).isNegative() ? -1 : 1;
667 // Both are positive if at least one is unsigned
668 return (other.high >>> 0) > (this.high >>> 0) || (other.high === this.high && (other.low >>> 0) > (this.low >>> 0)) ? -1 : 1;
669 };
670
671 /**
672 * Compares this Long's value with the specified's. This is an alias of {@link Long#compare}.
673 * @function
674 * @param {!Long|number|string} other Other value
675 * @returns {number} 0 if they are the same, 1 if the this is greater and -1
676 * if the given one is greater
677 * @expose
678 */
679 LongPrototype.comp = LongPrototype.compare;
680
681 /**
682 * Negates this Long's value.
683 * @returns {!Long} Negated Long
684 * @expose
685 */
686 LongPrototype.negate = function negate() {
687 if (!this.unsigned && this.eq(Long.MIN_VALUE))
688 return Long.MIN_VALUE;
689 return this.not().add(Long.ONE);
690 };
691
692 /**
693 * Negates this Long's value. This is an alias of {@link Long#negate}.
694 * @function
695 * @returns {!Long} Negated Long
696 * @expose
697 */
698 LongPrototype.neg = LongPrototype.negate;
699
700 /**
701 * Returns the sum of this and the specified Long.
702 * @param {!Long|number|string} addend Addend
703 * @returns {!Long} Sum
704 * @expose
705 */
706 LongPrototype.add = function add(addend) {
707 if (!Long.isLong(addend))
708 addend = Long.fromValue(addend);
709
710 // Divide each number into 4 chunks of 16 bits, and then sum the chunks.
711
712 var a48 = this.high >>> 16;
713 var a32 = this.high & 0xFFFF;
714 var a16 = this.low >>> 16;
715 var a00 = this.low & 0xFFFF;
716
717 var b48 = addend.high >>> 16;
718 var b32 = addend.high & 0xFFFF;
719 var b16 = addend.low >>> 16;
720 var b00 = addend.low & 0xFFFF;
721
722 var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
723 c00 += a00 + b00;
724 c16 += c00 >>> 16;
725 c00 &= 0xFFFF;
726 c16 += a16 + b16;
727 c32 += c16 >>> 16;
728 c16 &= 0xFFFF;
729 c32 += a32 + b32;
730 c48 += c32 >>> 16;
731 c32 &= 0xFFFF;
732 c48 += a48 + b48;
733 c48 &= 0xFFFF;
734 return new Long((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);
735 };
736
737 /**
738 * Returns the difference of this and the specified Long.
739 * @param {!Long|number|string} subtrahend Subtrahend
740 * @returns {!Long} Difference
741 * @expose
742 */
743 LongPrototype.subtract = function subtract(subtrahend) {
744 if (!Long.isLong(subtrahend))
745 subtrahend = Long.fromValue(subtrahend);
746 return this.add(subtrahend.neg());
747 };
748
749 /**
750 * Returns the difference of this and the specified Long. This is an alias of {@link Long#subtract}.
751 * @function
752 * @param {!Long|number|string} subtrahend Subtrahend
753 * @returns {!Long} Difference
754 * @expose
755 */
756 LongPrototype.sub = LongPrototype.subtract;
757
758 /**
759 * Returns the product of this and the specified Long.
760 * @param {!Long|number|string} multiplier Multiplier
761 * @returns {!Long} Product
762 * @expose
763 */
764 LongPrototype.multiply = function multiply(multiplier) {
765 if (this.isZero())
766 return Long.ZERO;
767 if (!Long.isLong(multiplier))
768 multiplier = Long.fromValue(multiplier);
769 if (multiplier.isZero())
770 return Long.ZERO;
771 if (this.eq(Long.MIN_VALUE))
772 return multiplier.isOdd() ? Long.MIN_VALUE : Long.ZERO;
773 if (multiplier.eq(Long.MIN_VALUE))
774 return this.isOdd() ? Long.MIN_VALUE : Long.ZERO;
775
776 if (this.isNegative()) {
777 if (multiplier.isNegative())
778 return this.neg().mul(multiplier.neg());
779 else
780 return this.neg().mul(multiplier).neg();
781 } else if (multiplier.isNegative())
782 return this.mul(multiplier.neg()).neg();
783
784 // If both longs are small, use float multiplication
785 if (this.lt(TWO_PWR_24) && multiplier.lt(TWO_PWR_24))
786 return Long.fromNumber(this.toNumber() * multiplier.toNumber(), this.unsigned);
787
788 // Divide each long into 4 chunks of 16 bits, and then add up 4x4 products.
789 // We can skip products that would overflow.
790
791 var a48 = this.high >>> 16;
792 var a32 = this.high & 0xFFFF;
793 var a16 = this.low >>> 16;
794 var a00 = this.low & 0xFFFF;
795
796 var b48 = multiplier.high >>> 16;
797 var b32 = multiplier.high & 0xFFFF;
798 var b16 = multiplier.low >>> 16;
799 var b00 = multiplier.low & 0xFFFF;
800
801 var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
802 c00 += a00 * b00;
803 c16 += c00 >>> 16;
804 c00 &= 0xFFFF;
805 c16 += a16 * b00;
806 c32 += c16 >>> 16;
807 c16 &= 0xFFFF;
808 c16 += a00 * b16;
809 c32 += c16 >>> 16;
810 c16 &= 0xFFFF;
811 c32 += a32 * b00;
812 c48 += c32 >>> 16;
813 c32 &= 0xFFFF;
814 c32 += a16 * b16;
815 c48 += c32 >>> 16;
816 c32 &= 0xFFFF;
817 c32 += a00 * b32;
818 c48 += c32 >>> 16;
819 c32 &= 0xFFFF;
820 c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48;
821 c48 &= 0xFFFF;
822 return new Long((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);
823 };
824
825 /**
826 * Returns the product of this and the specified Long. This is an alias of {@link Long#multiply}.
827 * @function
828 * @param {!Long|number|string} multiplier Multiplier
829 * @returns {!Long} Product
830 * @expose
831 */
832 LongPrototype.mul = LongPrototype.multiply;
833
834 /**
835 * Returns this Long divided by the specified.
836 * @param {!Long|number|string} divisor Divisor
837 * @returns {!Long} Quotient
838 * @expose
839 */
840 LongPrototype.divide = function divide(divisor) {
841 if (!Long.isLong(divisor))
842 divisor = Long.fromValue(divisor);
843 if (divisor.isZero())
844 throw Error('division by zero');
845 if (this.isZero())
846 return this.unsigned ? Long.UZERO : Long.ZERO;
847 var approx, rem, res;
848 if (this.eq(Long.MIN_VALUE)) {
849 if (divisor.eq(Long.ONE) || divisor.eq(Long.NEG_ONE))
850 return Long.MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE
851 else if (divisor.eq(Long.MIN_VALUE))
852 return Long.ONE;
853 else {
854 // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|.
855 var halfThis = this.shr(1);
856 approx = halfThis.div(divisor).shl(1);
857 if (approx.eq(Long.ZERO)) {
858 return divisor.isNegative() ? Long.ONE : Long.NEG_ONE;
859 } else {
860 rem = this.sub(divisor.mul(approx));
861 res = approx.add(rem.div(divisor));
862 return res;
863 }
864 }
865 } else if (divisor.eq(Long.MIN_VALUE))
866 return this.unsigned ? Long.UZERO : Long.ZERO;
867 if (this.isNegative()) {
868 if (divisor.isNegative())
869 return this.neg().div(divisor.neg());
870 return this.neg().div(divisor).neg();
871 } else if (divisor.isNegative())
872 return this.div(divisor.neg()).neg();
873
874 // Repeat the following until the remainder is less than other: find a
875 // floating-point that approximates remainder / other *from below*, add this
876 // into the result, and subtract it from the remainder. It is critical that
877 // the approximate value is less than or equal to the real value so that the
878 // remainder never becomes negative.
879 res = Long.ZERO;
880 rem = this;
881 while (rem.gte(divisor)) {
882 // Approximate the result of division. This may be a little greater or
883 // smaller than the actual value.
884 approx = Math.max(1, Math.floor(rem.toNumber() / divisor.toNumber()));
885
886 // We will tweak the approximate result by changing it in the 48-th digit or
887 // the smallest non-fractional digit, whichever is larger.
888 var log2 = Math.ceil(Math.log(approx) / Math.LN2),
889 delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48),
890
891 // Decrease the approximation until it is smaller than the remainder. Note
892 // that if it is too large, the product overflows and is negative.
893 approxRes = Long.fromNumber(approx),
894 approxRem = approxRes.mul(divisor);
895 while (approxRem.isNegative() || approxRem.gt(rem)) {
896 approx -= delta;
897 approxRes = Long.fromNumber(approx, this.unsigned);
898 approxRem = approxRes.mul(divisor);
899 }
900
901 // We know the answer can't be zero... and actually, zero would cause
902 // infinite recursion since we would make no progress.
903 if (approxRes.isZero())
904 approxRes = Long.ONE;
905
906 res = res.add(approxRes);
907 rem = rem.sub(approxRem);
908 }
909 return res;
910 };
911
912 /**
913 * Returns this Long divided by the specified. This is an alias of {@link Long#divide}.
914 * @function
915 * @param {!Long|number|string} divisor Divisor
916 * @returns {!Long} Quotient
917 * @expose
918 */
919 LongPrototype.div = LongPrototype.divide;
920
921 /**
922 * Returns this Long modulo the specified.
923 * @param {!Long|number|string} divisor Divisor
924 * @returns {!Long} Remainder
925 * @expose
926 */
927 LongPrototype.modulo = function modulo(divisor) {
928 if (!Long.isLong(divisor))
929 divisor = Long.fromValue(divisor);
930 return this.sub(this.div(divisor).mul(divisor));
931 };
932
933 /**
934 * Returns this Long modulo the specified. This is an alias of {@link Long#modulo}.
935 * @function
936 * @param {!Long|number|string} divisor Divisor
937 * @returns {!Long} Remainder
938 * @expose
939 */
940 LongPrototype.mod = LongPrototype.modulo;
941
942 /**
943 * Returns the bitwise NOT of this Long.
944 * @returns {!Long}
945 * @expose
946 */
947 LongPrototype.not = function not() {
948 return new Long(~this.low, ~this.high, this.unsigned);
949 };
950
951 /**
952 * Returns the bitwise AND of this Long and the specified.
953 * @param {!Long|number|string} other Other Long
954 * @returns {!Long}
955 * @expose
956 */
957 LongPrototype.and = function and(other) {
958 if (!Long.isLong(other))
959 other = Long.fromValue(other);
960 return new Long(this.low & other.low, this.high & other.high, this.unsigned);
961 };
962
963 /**
964 * Returns the bitwise OR of this Long and the specified.
965 * @param {!Long|number|string} other Other Long
966 * @returns {!Long}
967 * @expose
968 */
969 LongPrototype.or = function or(other) {
970 if (!Long.isLong(other))
971 other = Long.fromValue(other);
972 return new Long(this.low | other.low, this.high | other.high, this.unsigned);
973 };
974
975 /**
976 * Returns the bitwise XOR of this Long and the given one.
977 * @param {!Long|number|string} other Other Long
978 * @returns {!Long}
979 * @expose
980 */
981 LongPrototype.xor = function xor(other) {
982 if (!Long.isLong(other))
983 other = Long.fromValue(other);
984 return new Long(this.low ^ other.low, this.high ^ other.high, this.unsigned);
985 };
986
987 /**
988 * Returns this Long with bits shifted to the left by the given amount.
989 * @param {number|!Long} numBits Number of bits
990 * @returns {!Long} Shifted Long
991 * @expose
992 */
993 LongPrototype.shiftLeft = function shiftLeft(numBits) {
994 if (Long.isLong(numBits))
995 numBits = numBits.toInt();
996 if ((numBits &= 63) === 0)
997 return this;
998 else if (numBits < 32)
999 return new Long(this.low << numBits, (this.high << numBits) | (this.low >>> (32 - numBits)), this.unsigned);
1000 else
1001 return new Long(0, this.low << (numBits - 32), this.unsigned);
1002 };
1003
1004 /**
1005 * Returns this Long with bits shifted to the left by the given amount. This is an alias of {@link Long#shiftLeft}.
1006 * @function
1007 * @param {number|!Long} numBits Number of bits
1008 * @returns {!Long} Shifted Long
1009 * @expose
1010 */
1011 LongPrototype.shl = LongPrototype.shiftLeft;
1012
1013 /**
1014 * Returns this Long with bits arithmetically shifted to the right by the given amount.
1015 * @param {number|!Long} numBits Number of bits
1016 * @returns {!Long} Shifted Long
1017 * @expose
1018 */
1019 LongPrototype.shiftRight = function shiftRight(numBits) {
1020 if (Long.isLong(numBits))
1021 numBits = numBits.toInt();
1022 if ((numBits &= 63) === 0)
1023 return this;
1024 else if (numBits < 32)
1025 return new Long((this.low >>> numBits) | (this.high << (32 - numBits)), this.high >> numBits, this.unsigned);
1026 else
1027 return new Long(this.high >> (numBits - 32), this.high >= 0 ? 0 : -1, this.unsigned);
1028 };
1029
1030 /**
1031 * Returns this Long with bits arithmetically shifted to the right by the given amount. This is an alias of {@link Long#shiftRight}.
1032 * @function
1033 * @param {number|!Long} numBits Number of bits
1034 * @returns {!Long} Shifted Long
1035 * @expose
1036 */
1037 LongPrototype.shr = LongPrototype.shiftRight;
1038
1039 /**
1040 * Returns this Long with bits logically shifted to the right by the given amount.
1041 * @param {number|!Long} numBits Number of bits
1042 * @returns {!Long} Shifted Long
1043 * @expose
1044 */
1045 LongPrototype.shiftRightUnsigned = function shiftRightUnsigned(numBits) {
1046 if (Long.isLong(numBits))
1047 numBits = numBits.toInt();
1048 numBits &= 63;
1049 if (numBits === 0)
1050 return this;
1051 else {
1052 var high = this.high;
1053 if (numBits < 32) {
1054 var low = this.low;
1055 return new Long((low >>> numBits) | (high << (32 - numBits)), high >>> numBits, this.unsigned);
1056 } else if (numBits === 32)
1057 return new Long(high, 0, this.unsigned);
1058 else
1059 return new Long(high >>> (numBits - 32), 0, this.unsigned);
1060 }
1061 };
1062
1063 /**
1064 * Returns this Long with bits logically shifted to the right by the given amount. This is an alias of {@link Long#shiftRightUnsigned}.
1065 * @function
1066 * @param {number|!Long} numBits Number of bits
1067 * @returns {!Long} Shifted Long
1068 * @expose
1069 */
1070 LongPrototype.shru = LongPrototype.shiftRightUnsigned;
1071
1072 /**
1073 * Converts this Long to signed.
1074 * @returns {!Long} Signed long
1075 * @expose
1076 */
1077 LongPrototype.toSigned = function toSigned() {
1078 if (!this.unsigned)
1079 return this;
1080 return new Long(this.low, this.high, false);
1081 };
1082
1083 /**
1084 * Converts this Long to unsigned.
1085 * @returns {!Long} Unsigned long
1086 * @expose
1087 */
1088 LongPrototype.toUnsigned = function toUnsigned() {
1089 if (this.unsigned)
1090 return this;
1091 return new Long(this.low, this.high, true);
1092 };
1093
1094 return Long;
1095});