in asdoc/library/closure/goog/math/integer.js [500:556]
goog.math.Integer.prototype.multiply = function(other) {
if (this.isZero()) {
return goog.math.Integer.ZERO;
} else if (other.isZero()) {
return goog.math.Integer.ZERO;
}
if (this.isNegative()) {
if (other.isNegative()) {
return this.negate().multiply(other.negate());
} else {
return this.negate().multiply(other).negate();
}
} else if (other.isNegative()) {
return this.multiply(other.negate()).negate();
}
// If both numbers are small, use float multiplication
if (this.lessThan(goog.math.Integer.TWO_PWR_24_) &&
other.lessThan(goog.math.Integer.TWO_PWR_24_)) {
return goog.math.Integer.fromNumber(this.toNumber() * other.toNumber());
}
// Fill in an array of 16-bit products.
var len = this.bits_.length + other.bits_.length;
var arr = [];
for (var i = 0; i < 2 * len; i++) {
arr[i] = 0;
}
for (var i = 0; i < this.bits_.length; i++) {
for (var j = 0; j < other.bits_.length; j++) {
var a1 = this.getBits(i) >>> 16;
var a0 = this.getBits(i) & 0xFFFF;
var b1 = other.getBits(j) >>> 16;
var b0 = other.getBits(j) & 0xFFFF;
arr[2 * i + 2 * j] += a0 * b0;
goog.math.Integer.carry16_(arr, 2 * i + 2 * j);
arr[2 * i + 2 * j + 1] += a1 * b0;
goog.math.Integer.carry16_(arr, 2 * i + 2 * j + 1);
arr[2 * i + 2 * j + 1] += a0 * b1;
goog.math.Integer.carry16_(arr, 2 * i + 2 * j + 1);
arr[2 * i + 2 * j + 2] += a1 * b1;
goog.math.Integer.carry16_(arr, 2 * i + 2 * j + 2);
}
}
// Combine the 16-bit values into 32-bit values.
for (var i = 0; i < len; i++) {
arr[i] = (arr[2 * i + 1] << 16) | arr[2 * i];
}
for (var i = len; i < 2 * len; i++) {
arr[i] = 0;
}
return new goog.math.Integer(arr, 0);
};