As JavaScript does not handle very large numbers very well...
JavaScript only stores 53 significant bits, and then it uses some
more bits to tell how many zeroes comes after those.

That is why
Math.pow(2,52) != Math.pow(2,52)+1
but
Math.pow(2,53) == Math.pow(2,53)+1

It needs 54 bits to represent 2^53+1 precisely. Since there are only 53 bits
available, the least significant bit is lost.

(There are some extra details about how the bits are really used, but
I think they would only confuze matters here
I recommend that we add BigInteger into the framework.

From: https://github.com/silentmatt/javasc.../biginteger.js
PHP Code:
/*
    JavaScript BigInteger library version 0.9
    http://silentmatt.com/biginteger/

    Copyright (c) 2009 Matthew Crumley <email@matthewcrumley.com>
    Copyright (c) 2010,2011 by John Tobey <John.Tobey@gmail.com>
    Licensed under the MIT license.

    Support for arbitrary internal representation base was added by
    Vitaly Magerya.
*/
/*
    File: biginteger.js

    Exports:

        <BigInteger>
*/
/*
    Class: BigInteger
    An arbitrarily-large integer.

    <BigInteger> objects should be considered immutable. None of the "built-in"
    methods modify *this* or their arguments. All properties should be
    considered private.

    All the methods of <BigInteger> instances can be called "statically". The
    static versions are convenient if you don't already have a <BigInteger>
    object.

    As an example, these calls are equivalent.

    > BigInteger(4).multiply(5); // returns BigInteger(20);
    > BigInteger.multiply(4, 5); // returns BigInteger(20);

    > var a = 42;
    > var a = BigInteger.toJSValue("0b101010"); // Not completely useless...
*/
// IE doesn't support Array.prototype.map
if (!Array.prototype.map) {
    Array.
prototype.map = function (fun /*, thisp*/ ) {
        var 
len this.length >>> 0;
        if (
typeof fun !== "function") {
            throw new 
TypeError();
        }

        var 
res = new Array(len);
        var 
thisp arguments[1];
        for (var 
0leni++) {
            if (
i in this) {
                
res[i] = fun.call(thispthis[i], ithis);
            }
        }

        return 
res;
    };
}

/*
    Constructor: BigInteger()
    Convert a value to a <BigInteger>.

    Although <BigInteger()> is the constructor for <BigInteger> objects, it is
    best not to call it as a constructor. If *n* is a <BigInteger> object, it is
    simply returned as-is. Otherwise, <BigInteger()> is equivalent to <parse>
    without a radix argument.

    > var n0 = BigInteger();      // Same as <BigInteger.ZERO>
    > var n1 = BigInteger("123"); // Create a new <BigInteger> with value 123
    > var n2 = BigInteger(123);   // Create a new <BigInteger> with value 123
    > var n3 = BigInteger(n2);    // Return n2, unchanged

    The constructor form only takes an array and a sign. *n* must be an
    array of numbers in little-endian order, where each digit is between 0
    and BigInteger.base.  The second parameter sets the sign: -1 for
    negative, +1 for positive, or 0 for zero. The array is *not copied and
    may be modified*. If the array contains only zeros, the sign parameter
    is ignored and is forced to zero.

    > new BigInteger([5], -1): create a new BigInteger with value -5

    Parameters:

        n - Value to convert to a <BigInteger>.

    Returns:

        A <BigInteger> value.

    See Also:

        <parse>, <BigInteger>
*/
function BigInteger(ns) {
    if (!(
this instanceof BigInteger)) {
        if (
instanceof BigInteger) {
            return 
n;
        } else if (
typeof n === "undefined") {
            return 
BigInteger.ZERO;
        }
        return 
BigInteger.parse(n);
    }

    
|| []; // Provide the nullary constructor for subclasses.
    
while (n.length && !n[n.length 1]) {
        --
n.length;
    }
    
this._d n;
    
this._s n.length ? (|| 1) : 0;
}

// Base-10 speedup hacks in parse, toString, exp10 and log functions
// require base to be a power of 10. 10^7 is the largest such power
// that won't cause a precision loss when digits are multiplied.
BigInteger.base 10000000;
BigInteger.base_log10 7;

// Constant: ZERO
// <BigInteger> 0.
BigInteger.ZERO = new BigInteger([], 0);

// Constant: ONE
// <BigInteger> 1.
BigInteger.ONE = new BigInteger([1], 1);

// Constant: M_ONE
// <BigInteger> -1.
BigInteger.M_ONE = new BigInteger(BigInteger.ONE._d, -1);

// Constant: _0
// Shortcut for <ZERO>.
BigInteger._0 BigInteger.ZERO;

// Constant: _1
// Shortcut for <ONE>.
BigInteger._1 BigInteger.ONE;

/*
    Constant: small
    Array of <BigIntegers> from 0 to 36.

    These are used internally for parsing, but useful when you need a "small"
    <BigInteger>.

    See Also:

        <ZERO>, <ONE>, <_0>, <_1>
*/
BigInteger.small = [
BigInteger.ZEROBigInteger.ONE,
/* Assuming BigInteger.base > 36 */
new BigInteger([2], 1), new BigInteger([3], 1), new BigInteger([4], 1), new BigInteger([5], 1), new BigInteger([6], 1), new BigInteger([7], 1), new BigInteger([8], 1), new BigInteger([9], 1), new BigInteger([10], 1), new BigInteger([11], 1), new BigInteger([12], 1), new BigInteger([13], 1), new BigInteger([14], 1), new BigInteger([15], 1), new BigInteger([16], 1), new BigInteger([17], 1), new BigInteger([18], 1), new BigInteger([19], 1), new BigInteger([20], 1), new BigInteger([21], 1), new BigInteger([22], 1), new BigInteger([23], 1), new BigInteger([24], 1), new BigInteger([25], 1), new BigInteger([26], 1), new BigInteger([27], 1), new BigInteger([28], 1), new BigInteger([29], 1), new BigInteger([30], 1), new BigInteger([31], 1), new BigInteger([32], 1), new BigInteger([33], 1), new BigInteger([34], 1), new BigInteger([35], 1), new BigInteger([36], 1)];

// Used for parsing/radix conversion
BigInteger.digits "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");

/*
    Method: toString
    Convert a <BigInteger> to a string.

    When *base* is greater than 10, letters are upper case.

    Parameters:

        base - Optional base to represent the number in (default is base 10).
               Must be between 2 and 36 inclusive, or an Error will be thrown.

    Returns:

        The string representation of the <BigInteger>.
*/
BigInteger.prototype.toString = function (base) {
    
base = +base || 10;
    if (
base || base 36) {
        throw new 
Error("illegal radix " base ".");
    }
    if (
this._s === 0) {
        return 
"0";
    }
    if (
base === 10) {
        var 
str this._s "-" "";
        
str += this._d[this._d.length 1].toString();
        for (var 
this._d.length 2>= 0i--) {
            var 
group this._d[i].toString();
            while (
group.length BigInteger.base_log10group '0' group;
            
str += group;
        }
        return 
str;
    } else {
        var 
numerals BigInteger.digits;
        
base BigInteger.small[base];
        var 
sign this._s;

        var 
this.abs();
        var 
digits = [];
        var 
digit;

        while (
n._s !== 0) {
            var 
divmod n.divRem(base);
            
divmod[0];
            
digit divmod[1];
            
// TODO: This could be changed to unshift instead of reversing at the end.
            // Benchmark both to compare speeds.
            
digits.push(numerals[digit.valueOf()]);
        }
        return (
sign "-" "") + digits.reverse().join("");
    }
};

// Verify strings for parsing
BigInteger.radixRegex = [/^$/, /^$/, /^[01]*$/, /^[012]*$/, /^[0-3]*$/, /^[0-4]*$/, /^[0-5]*$/, /^[0-6]*$/, /^[0-7]*$/, /^[0-8]*$/, /^[0-9]*$/, /^[0-9aA]*$/, /^[0-9abAB]*$/, /^[0-9abcABC]*$/, /^[0-9a-dA-D]*$/, /^[0-9a-eA-E]*$/, /^[0-9a-fA-F]*$/, /^[0-9a-gA-G]*$/, /^[0-9a-hA-H]*$/, /^[0-9a-iA-I]*$/, /^[0-9a-jA-J]*$/, /^[0-9a-kA-K]*$/, /^[0-9a-lA-L]*$/, /^[0-9a-mA-M]*$/, /^[0-9a-nA-N]*$/, /^[0-9a-oA-O]*$/, /^[0-9a-pA-P]*$/, /^[0-9a-qA-Q]*$/, /^[0-9a-rA-R]*$/, /^[0-9a-sA-S]*$/, /^[0-9a-tA-T]*$/, /^[0-9a-uA-U]*$/, /^[0-9a-vA-V]*$/, /^[0-9a-wA-W]*$/, /^[0-9a-xA-X]*$/, /^[0-9a-yA-Y]*$/, /^[0-9a-zA-Z]*$/];

/*
    Function: parse
    Parse a string into a <BigInteger>.

    *base* is optional but, if provided, must be from 2 to 36 inclusive. If
    *base* is not provided, it will be guessed based on the leading characters
    of *s* as follows:

    - "0x" or "0X": *base* = 16
    - "0c" or "0C": *base* = 8
    - "0b" or "0B": *base* = 2
    - else: *base* = 10

    If no base is provided, or *base* is 10, the number can be in exponential
    form. For example, these are all valid:

    > BigInteger.parse("1e9");              // Same as "1000000000"
    > BigInteger.parse("1.234*10^3");       // Same as 1234
    > BigInteger.parse("56789 * 10 ** -2"); // Same as 567

    If any characters fall outside the range defined by the radix, an exception
    will be thrown.

    Parameters:

        s - The string to parse.
        base - Optional radix (default is to guess based on *s*).

    Returns:

        a <BigInteger> instance.
*/
BigInteger.parse = function (sbase) {
    
// Expands a number in exponential form to decimal form.
    // expandExponential("-13.441*10^5") === "1344100";
    // expandExponential("1.12300e-1") === "0.112300";
    // expandExponential(1000000000000000000000000000000) === "1000000000000000000000000000000";
    
function expandExponential(str) {
        
str str.replace(/\s*[*xX]\s*10\s*(\^|\*\*)\s*/, "e");

        return 
str.replace(/^([+\-])?(\d+)\.?(\d*)[eE]([+\-]?\d+)$/, function (xsnfc) {
            
= +c;
            var 
0;
            var 
n.length c;
            
= (f).length;
            
= ((Math.abs(c)) >= 0);
            var 
= (new Array(1)).join("0");
            var 
f;
            return (
|| "") + (+= z).substr(0+= z.length 0) + (r.length "." r.substr(i) : "");
        });
    }

    
s.toString();
    if (
typeof base === "undefined" || +base === 10) {
        
expandExponential(s);
    }

    var 
parts = /^([+\-]?)(0[xXcCbB])?([0-9A-Za-z]*)(?:\.\d*)?$/.exec(s);
    if (
parts) {
        var 
sign parts[1] || "+";
        var 
baseSection parts[2] || "";
        var 
digits parts[3] || "";

        if (
typeof base === "undefined") {
            
// Guess base
            
if (baseSection === "0x" || baseSection === "0X") { // Hex
                
base 16;
            } else if (
baseSection === "0c" || baseSection === "0C") { // Octal
                
base 8;
            } else if (
baseSection === "0b" || baseSection === "0B") { // Binary
                
base 2;
            } else {
                
base 10;
            }
        } else if (
base || base 36) {
            throw new 
Error("Illegal radix " base ".");
        }

        
base = +base;

        
// Check for digits outside the range
        
if (!(BigInteger.radixRegex[base].test(digits))) {
            throw new 
Error("Bad digit for radix " base);
        }

        
// Strip leading zeros, and convert to array
        
digits digits.replace(/^0+/, "").split("");
        if (
digits.length === 0) {
            return 
BigInteger.ZERO;
        }

        
// Get the sign (we know it's not zero)
        
sign = (sign === "-") ? -1;

        
// Optimize 10
        
if (base == 10) {
            var 
= [];
            while (
digits.length >= BigInteger.base_log10) {
                
d.push(parseInt(digits.splice(-BigInteger.base_log10).join(''), 10));
            }
            
d.push(parseInt(digits.join(''), 10));
            return new 
BigInteger(dsign);
        }

        
// Optimize base
        
if (base === BigInteger.base) {
            return new 
BigInteger(digits.map(Number).reverse(), sign);
        }

        
// Do the conversion
        
var BigInteger.ZERO;
        
base BigInteger.small[base];
        var 
small BigInteger.small;
        for (var 
0digits.lengthi++) {
            
d.multiply(base).add(small[parseInt(digits[i], 36)]);
        }
        return new 
BigInteger(d._dsign);
    } else {
        throw new 
Error("Invalid BigInteger format: " s);
    }
};

/*
    Function: add
    Add two <BigIntegers>.

    Parameters:

        n - The number to add to *this*. Will be converted to a <BigInteger>.

    Returns:

        The numbers added together.

    See Also:

        <subtract>, <multiply>, <quotient>, <next>
*/
BigInteger.prototype.add = function (n) {
    if (
this._s === 0) {
        return 
BigInteger(n);
    }

    
BigInteger(n);
    if (
n._s === 0) {
        return 
this;
    }
    if (
this._s !== n._s) {
        
n.negate();
        return 
this.subtract(n);
    }

    var 
this._d;
    var 
n._d;
    var 
al a.length;
    var 
bl b.length;
    var 
sum = new Array(Math.max(albl) + 1);
    var 
size Math.min(albl);
    var 
carry 0;
    var 
digit;

    for (var 
0sizei++) {
        
digit a[i] + b[i] + carry;
        
sum[i] = digit BigInteger.base;
        
carry = (digit BigInteger.base) | 0;
    }
    if (
bl al) {
        
b;
        
al bl;
    }
    for (
sizecarry && ali++) {
        
digit a[i] + carry;
        
sum[i] = digit BigInteger.base;
        
carry = (digit BigInteger.base) | 0;
    }
    if (
carry) {
        
sum[i] = carry;
    }

    for (; 
ali++) {
        
sum[i] = a[i];
    }

    return new 
BigInteger(sumthis._s);
};

/*
    Function: negate
    Get the additive inverse of a <BigInteger>.

    Returns:

        A <BigInteger> with the same magnatude, but with the opposite sign.

    See Also:

        <abs>
*/
BigInteger.prototype.negate = function () {
    return new 
BigInteger(this._d, -this._s);
};

/*
    Function: abs
    Get the absolute value of a <BigInteger>.

    Returns:

        A <BigInteger> with the same magnatude, but always positive (or zero).

    See Also:

        <negate>
*/
BigInteger.prototype.abs = function () {
    return (
this._s 0) ? this.negate() : this;
};

/*
    Function: subtract
    Subtract two <BigIntegers>.

    Parameters:

        n - The number to subtract from *this*. Will be converted to a <BigInteger>.

    Returns:

        The *n* subtracted from *this*.

    See Also:

        <add>, <multiply>, <quotient>, <prev>
*/
BigInteger.prototype.subtract = function (n) {
    if (
this._s === 0) {
        return 
BigInteger(n).negate();
    }

    
BigInteger(n);
    if (
n._s === 0) {
        return 
this;
    }
    if (
this._s !== n._s) {
        
n.negate();
        return 
this.add(n);
    }

    var 
this;
    var 
t;
    
// negative - negative => -|a| - -|b| => -|a| + |b| => |b| - |a|
    
if (this._s 0) {
        
m;
        
= new BigInteger(n._d1);
        
= new BigInteger(t._d1);
    }

    
// Both are positive => a - b
    
var sign m.compareAbs(n);
    if (
sign === 0) {
        return 
BigInteger.ZERO;
    } else if (
sign 0) {
        
// swap m and n
        
n;
        
m;
        
t;
    }

    
// a > b
    
var m._d;
    var 
n._d;
    var 
al a.length;
    var 
bl b.length;
    var 
diff = new Array(al); // al >= bl since a > b
    
var borrow 0;
    var 
i;
    var 
digit;

    for (
0bli++) {
        
digit a[i] - borrow b[i];
        if (
digit 0) {
            
digit += BigInteger.base;
            
borrow 1;
        } else {
            
borrow 0;
        }
        
diff[i] = digit;
    }
    for (
blali++) {
        
digit a[i] - borrow;
        if (
digit 0) {
            
digit += BigInteger.base;
        } else {
            
diff[i++] = digit;
            break;
        }
        
diff[i] = digit;
    }
    for (; 
ali++) {
        
diff[i] = a[i];
    }

    return new 
BigInteger(diffsign);
};

(function () {
    function 
addOne(nsign) {
        var 
n._d;
        var 
sum a.slice();
        var 
carry true;
        var 
0;

        while (
true) {
            var 
digit = (a[i] || 0) + 1;
            
sum[i] = digit BigInteger.base;
            if (
digit <= BigInteger.base 1) {
                break;
            }++
i;
        }

        return new 
BigInteger(sumsign);
    }

    function 
subtractOne(nsign) {
        var 
n._d;
        var 
sum a.slice();
        var 
borrow true;
        var 
0;

        while (
true) {
            var 
digit = (a[i] || 0) - 1;
            if (
digit 0) {
                
sum[i] = digit BigInteger.base;
            } else {
                
sum[i] = digit;
                break;
            }++
i;
        }

        return new 
BigInteger(sumsign);
    }

    
/*
        Function: next
        Get the next <BigInteger> (add one).

        Returns:

            *this* + 1.

        See Also:

            <add>, <prev>
    */
    
BigInteger.prototype.next = function () {
        switch (
this._s) {
        case 
0:
            return 
BigInteger.ONE;
        case -
1:
            return 
subtractOne(this, -1);
            
// case 1:
        
default:
            return 
addOne(this1);
        }
    };

    
/*
        Function: prev
        Get the previous <BigInteger> (subtract one).

        Returns:

            *this* - 1.

        See Also:

            <next>, <subtract>
    */
    
BigInteger.prototype.prev = function () {
        switch (
this._s) {
        case 
0:
            return 
BigInteger.M_ONE;
        case -
1:
            return 
addOne(this, -1);
            
// case 1:
        
default:
            return 
subtractOne(this1);
        }
    };
})();

/*
    Function: compareAbs
    Compare the absolute value of two <BigIntegers>.

    Calling <compareAbs> is faster than calling <abs> twice, then <compare>.

    Parameters:

        n - The number to compare to *this*. Will be converted to a <BigInteger>.

    Returns:

        -1, 0, or +1 if *|this|* is less than, equal to, or greater than *|n|*.

    See Also:

        <compare>, <abs>
*/
BigInteger.prototype.compareAbs = function (n) {
    if (
this === n) {
        return 
0;
    }

    if (!(
instanceof BigInteger)) {
        if (!
isFinite(n)) {
            return (
isNaN(n) ? : -1);
        }
        
BigInteger(n);
    }

    if (
this._s === 0) {
        return (
n._s !== 0) ? -0;
    }
    if (
n._s === 0) {
        return 
1;
    }

    var 
this._d.length;
    var 
nl n._d.length;
    if (
nl) {
        return -
1;
    } else if (
nl) {
        return 
1;
    }

    var 
this._d;
    var 
n._d;
    for (var 
1>= 0i--) {
        if (
a[i] !== b[i]) {
            return 
a[i] < b[i] ? -1;
        }
    }

    return 
0;
};

/*
    Function: compare
    Compare two <BigIntegers>.

    Parameters:

        n - The number to compare to *this*. Will be converted to a <BigInteger>.

    Returns:

        -1, 0, or +1 if *this* is less than, equal to, or greater than *n*.

    See Also:

        <compareAbs>, <isPositive>, <isNegative>, <isUnit>
*/
BigInteger.prototype.compare = function (n) {
    if (
this === n) {
        return 
0;
    }

    
BigInteger(n);

    if (
this._s === 0) {
        return -
n._s;
    }

    if (
this._s === n._s) { // both positive or both negative
        
var cmp this.compareAbs(n);
        return 
cmp this._s;
    } else {
        return 
this._s;
    }
};

/*
    Function: isUnit
    Return true iff *this* is either 1 or -1.

    Returns:

        true if *this* compares equal to <BigInteger.ONE> or <BigInteger.M_ONE>.

    See Also:

        <isZero>, <isNegative>, <isPositive>, <compareAbs>, <compare>,
        <BigInteger.ONE>, <BigInteger.M_ONE>
*/
BigInteger.prototype.isUnit = function () {
    return 
this === BigInteger.ONE || this === BigInteger.M_ONE || (this._d.length === && this._d[0] === 1);
};

/*
    Function: multiply
    Multiply two <BigIntegers>.

    Parameters:

        n - The number to multiply *this* by. Will be converted to a
        <BigInteger>.

    Returns:

        The numbers multiplied together.

    See Also:

        <add>, <subtract>, <quotient>, <square>
*/
BigInteger.prototype.multiply = function (n) {
    
// TODO: Consider adding Karatsuba multiplication for large numbers
    
if (this._s === 0) {
        return 
BigInteger.ZERO;
    }

    
BigInteger(n);
    if (
n._s === 0) {
        return 
BigInteger.ZERO;
    }
    if (
this.isUnit()) {
        if (
this._s 0) {
            return 
n.negate();
        }
        return 
n;
    }
    if (
n.isUnit()) {
        if (
n._s 0) {
            return 
this.negate();
        }
        return 
this;
    }
    if (
this === n) {
        return 
this.square();
    }

    var 
= (this._d.length >= n._d.length);
    var 
= (this n)._d// a will be longer than b
    
var = (this)._d;
    var 
al a.length;
    var 
bl b.length;

    var 
pl al bl;
    var 
partial = new Array(pl);
    var 
i;
    for (
0pli++) {
        
partial[i] = 0;
    }

    for (
0bli++) {
        var 
carry 0;
        var 
bi b[i];
        var 
jlimit al i;
        var 
digit;
        for (var 
ijlimitj++) {
            
digit partial[j] + bi a[i] + carry;
            
carry = (digit BigInteger.base) | 0;
            
partial[j] = (digit BigInteger.base) | 0;
        }
        if (
carry) {
            
digit partial[j] + carry;
            
carry = (digit BigInteger.base) | 0;
            
partial[j] = digit BigInteger.base;
        }
    }
    return new 
BigInteger(partialthis._s n._s);
};

// Multiply a BigInteger by a single-digit native number
// Assumes that this and n are >= 0
// This is not really intended to be used outside the library itself
BigInteger.prototype.multiplySingleDigit = function (n) {
    if (
=== || this._s === 0) {
        return 
BigInteger.ZERO;
    }
    if (
=== 1) {
        return 
this;
    }

    var 
digit;
    if (
this._d.length === 1) {
        
digit this._d[0] * n;
        if (
digit >= BigInteger.base) {
            return new 
BigInteger([(digit BigInteger.base) | 0, (digit BigInteger.base) | 0], 1);
        }
        return new 
BigInteger([digit], 1);
    }

    if (
=== 2) {
        return 
this.add(this);
    }
    if (
this.isUnit()) {
        return new 
BigInteger([n], 1);
    }

    var 
this._d;
    var 
al a.length;

    var 
pl al 1;
    var 
partial = new Array(pl);
    for (var 
0pli++) {
        
partial[i] = 0;
    }

    var 
carry 0;
    for (var 
0alj++) {
        
digit a[j] + carry;
        
carry = (digit BigInteger.base) | 0;
        
partial[j] = (digit BigInteger.base) | 0;
    }
    if (
carry) {
        
digit carry;
        
carry = (digit BigInteger.base) | 0;
        
partial[j] = digit BigInteger.base;
    }

    return new 
BigInteger(partial1);
};

/*
    Function: square
    Multiply a <BigInteger> by itself.

    This is slightly faster than regular multiplication, since it removes the
    duplicated multiplcations.

    Returns:

        > this.multiply(this)

    See Also:
        <multiply>
*/
BigInteger.prototype.square = function () {
    
// Normally, squaring a 10-digit number would take 100 multiplications.
    // Of these 10 are unique diagonals, of the remaining 90 (100-10), 45 are repeated.
    // This procedure saves (N*(N-1))/2 multiplications, (e.g., 45 of 100 multiplies).
    // Based on code by Gary Darby, Intellitech Systems Inc., www.DelphiForFun.org
    
if (this._s === 0) {
        return 
BigInteger.ZERO;
    }
    if (
this.isUnit()) {
        return 
BigInteger.ONE;
    }

    var 
digits this._d;
    var 
length digits.length;
    var 
imult1 = new Array(length length 1);
    var 
productcarryk;
    var 
i;

    
// Calculate diagonal
    
for (0lengthi++) {
        
2;
        
product digits[i] * digits[i];
        
carry = (product BigInteger.base) | 0;
        
imult1[k] = product BigInteger.base;
        
imult1[1] = carry;
    }

    
// Calculate repeating part
    
for (0lengthi++) {
        
carry 0;
        
1;
        for (var 
1lengthj++, k++) {
            
product digits[j] * digits[i] * imult1[k] + carry;
            
carry = (product BigInteger.base) | 0;
            
imult1[k] = product BigInteger.base;
        }
        
length i;
        var 
digit carry imult1[k];
        
carry = (digit BigInteger.base) | 0;
        
imult1[k] = digit BigInteger.base;
        
imult1[1] += carry;
    }

    return new 
BigInteger(imult11);
};

/*
    Function: quotient
    Divide two <BigIntegers> and truncate towards zero.

    <quotient> throws an exception if *n* is zero.

    Parameters:

        n - The number to divide *this* by. Will be converted to a <BigInteger>.

    Returns:

        The *this* / *n*, truncated to an integer.

    See Also:

        <add>, <subtract>, <multiply>, <divRem>, <remainder>
*/
BigInteger.prototype.quotient = function (n) {
    return 
this.divRem(n)[0];
};

/*
    Function: divide
    Deprecated synonym for <quotient>.
*/
BigInteger.prototype.divide BigInteger.prototype.quotient;

/*
    Function: remainder
    Calculate the remainder of two <BigIntegers>.

    <remainder> throws an exception if *n* is zero.

    Parameters:

        n - The remainder after *this* is divided *this* by *n*. Will be
            converted to a <BigInteger>.

    Returns:

        *this* % *n*.

    See Also:

        <divRem>, <quotient>
*/
BigInteger.prototype.remainder = function (n) {
    return 
this.divRem(n)[1];
};

/*
    Function: divRem
    Calculate the integer quotient and remainder of two <BigIntegers>.

    <divRem> throws an exception if *n* is zero.

    Parameters:

        n - The number to divide *this* by. Will be converted to a <BigInteger>.

    Returns:

        A two-element array containing the quotient and the remainder.

        > a.divRem(b)

        is exactly equivalent to

        > [a.quotient(b), a.remainder(b)]

        except it is faster, because they are calculated at the same time.

    See Also:

        <quotient>, <remainder>
*/
BigInteger.prototype.divRem = function (n) {
    
BigInteger(n);
    if (
n._s === 0) {
        throw new 
Error("Divide by zero");
    }
    if (
this._s === 0) {
        return [
BigInteger.ZEROBigInteger.ZERO];
    }
    if (
n._d.length === 1) {
        return 
this.divRemSmall(n._s n._d[0]);
    }

    
// Test for easy cases -- |n1| <= |n2|
    
switch (this.compareAbs(n)) {
    case 
0:
        
// n1 == n2
        
return [this._s === n._s BigInteger.ONE BigInteger.M_ONEBigInteger.ZERO];
    case -
1:
        
// |n1| < |n2|
        
return [BigInteger.ZEROthis];
    }

    var 
sign this._s n._s;
    var 
n.abs();
    var 
b_digits this._d.slice();
    var 
digits n._d.length;
    var 
max b_digits.length;
    var 
quot = [];
    var 
guess;

    var 
part = new BigInteger([], 1);
    
part._s 1;

    while (
b_digits.length) {
        
part._d.unshift(b_digits.pop());
        
part = new BigInteger(part._d1);

        if (
part.compareAbs(n) < 0) {
            
quot.push(0);
            continue;
        }
        if (
part._s === 0) {
            
guess 0;
        } else {
            var 
xlen part._d.length,
                
ylen a._d.length;
            var 
highx part._d[xlen 1] * BigInteger.base part._d[xlen 2];
            var 
highy a._d[ylen 1] * BigInteger.base a._d[ylen 2];
            if (
part._d.length a._d.length) {
                
// The length of part._d can either match a._d length,
                // or exceed it by one.
                
highx = (highx 1) * BigInteger.base;
            }
            
guess Math.ceil(highx highy);
        }
        do {
            var 
check a.multiplySingleDigit(guess);
            if (
check.compareAbs(part) <= 0) {
                break;
            }
            
guess--;
        } while (
guess);

        
quot.push(guess);
        if (!
guess) {
            continue;
        }
        var 
diff part.subtract(check);
        
part._d diff._d.slice();
    }

    return [new 
BigInteger(quot.reverse(), sign), new BigInteger(part._dthis._s)];
};

// Throws an exception if n is outside of (-BigInteger.base, -1] or
// [1, BigInteger.base).  It's not necessary to call this, since the
// other division functions will call it if they are able to.
BigInteger.prototype.divRemSmall = function (n) {
    var 
r;
    
= +n;
    if (
=== 0) {
        throw new 
Error("Divide by zero");
    }

    var 
n_s ? -1;
    var 
sign this._s n_s;
    
Math.abs(n);

    if (
|| >= BigInteger.base) {
        throw new 
Error("Argument out of range");
    }

    if (
this._s === 0) {
        return [
BigInteger.ZEROBigInteger.ZERO];
    }

    if (
=== || === -1) {
        return [(
sign === 1) ? this.abs() : new BigInteger(this._dsign), BigInteger.ZERO];
    }

    
// 2 <= n < BigInteger.base
    // divide a single digit by a single digit
    
if (this._d.length === 1) {
        var 
= new BigInteger([(this._d[0] / n) | 0], 1);
        
= new BigInteger([(this._d[0] % n) | 0], 1);
        if (
sign 0) {
            
q.negate();
        }
        if (
this._s 0) {
            
r.negate();
        }
        return [
qr];
    }

    var 
digits this._d.slice();
    var 
quot = new Array(digits.length);
    var 
part 0;
    var 
diff 0;
    var 
0;
    var 
guess;

    while (
digits.length) {
        
part part BigInteger.base digits[digits.length 1];
        if (
part n) {
            
quot[i++] = 0;
            
digits.pop();
            
diff BigInteger.base diff part;
            continue;
        }
        if (
part === 0) {
            
guess 0;
        } else {
            
guess = (part n) | 0;
        }

        var 
check guess;
        
diff part check;
        
quot[i++] = guess;
        if (!
guess) {
            
digits.pop();
            continue;
        }

        
digits.pop();
        
part diff;
    }

    
= new BigInteger([diff], 1);
    if (
this._s 0) {
        
r.negate();
    }
    return [new 
BigInteger(quot.reverse(), sign), r];
};

/*
    Function: isEven
    Return true iff *this* is divisible by two.

    Note that <BigInteger.ZERO> is even.

    Returns:

        true if *this* is even, false otherwise.

    See Also:

        <isOdd>
*/
BigInteger.prototype.isEven = function () {
    var 
digits this._d;
    return 
this._s === || digits.length === || (digits[0] % 2) === 0;
};

/*
    Function: isOdd
    Return true iff *this* is not divisible by two.

    Returns:

        true if *this* is odd, false otherwise.

    See Also:

        <isEven>
*/
BigInteger.prototype.isOdd = function () {
    return !
this.isEven();
};

/*
    Function: sign
    Get the sign of a <BigInteger>.

    Returns:

        * -1 if *this* < 0
        * 0 if *this* == 0
        * +1 if *this* > 0

    See Also:

        <isZero>, <isPositive>, <isNegative>, <compare>, <BigInteger.ZERO>
*/
BigInteger.prototype.sign = function () {
    return 
this._s;
};

/*
    Function: isPositive
    Return true iff *this* > 0.

    Returns:

        true if *this*.compare(<BigInteger.ZERO>) == 1.

    See Also:

        <sign>, <isZero>, <isNegative>, <isUnit>, <compare>, <BigInteger.ZERO>
*/
BigInteger.prototype.isPositive = function () {
    return 
this._s 0;
};

/*
    Function: isNegative
    Return true iff *this* < 0.

    Returns:

        true if *this*.compare(<BigInteger.ZERO>) == -1.

    See Also:

        <sign>, <isPositive>, <isZero>, <isUnit>, <compare>, <BigInteger.ZERO>
*/
BigInteger.prototype.isNegative = function () {
    return 
this._s 0;
};

/*
    Function: isZero
    Return true iff *this* == 0.

    Returns:

        true if *this*.compare(<BigInteger.ZERO>) == 0.

    See Also:

        <sign>, <isPositive>, <isNegative>, <isUnit>, <BigInteger.ZERO>
*/
BigInteger.prototype.isZero = function () {
    return 
this._s === 0;
};

/*
    Function: exp10
    Multiply a <BigInteger> by a power of 10.

    This is equivalent to, but faster than

    > if (n >= 0) {
    >     return this.multiply(BigInteger("1e" + n));
    > }
    > else { // n <= 0
    >     return this.quotient(BigInteger("1e" + -n));
    > }

    Parameters:

        n - The power of 10 to multiply *this* by. *n* is converted to a
        javascipt number and must be no greater than <BigInteger.MAX_EXP>
        (0x7FFFFFFF), or an exception will be thrown.

    Returns:

        *this* * (10 ** *n*), truncated to an integer if necessary.

    See Also:

        <pow>, <multiply>
*/
BigInteger.prototype.exp10 = function (n) {
    
= +n;
    if (
=== 0) {
        return 
this;
    }
    if (
Math.abs(n) > Number(BigInteger.MAX_EXP)) {
        throw new 
Error("exponent too large in BigInteger.exp10");
    }
    if (
0) {
        var 
= new BigInteger(this._d.slice(), this._s);

        for (; 
>= BigInteger.base_log10-= BigInteger.base_log10) {
            
k._d.unshift(0);
        }
        if (
== 0) return k;
        
k._s 1;
        
k.multiplySingleDigit(Math.pow(10n));
        return (
this._s k.negate() : k);
    } else if (-
>= this._d.length BigInteger.base_log10) {
        return 
BigInteger.ZERO;
    } else {
        var 
= new BigInteger(this._d.slice(), this._s);

        for (
= -n>= BigInteger.base_log10-= BigInteger.base_log10) {
            
k._d.shift();
        }
        return (
== 0) ? k.divRemSmall(Math.pow(10n))[0];
    }
};

/*
    Function: pow
    Raise a <BigInteger> to a power.

    In this implementation, 0**0 is 1.

    Parameters:

        n - The exponent to raise *this* by. *n* must be no greater than
        <BigInteger.MAX_EXP> (0x7FFFFFFF), or an exception will be thrown.

    Returns:

        *this* raised to the *nth* power.

    See Also:

        <modPow>
*/
BigInteger.prototype.pow = function (n) {
    if (
this.isUnit()) {
        if (
this._s 0) {
            return 
this;
        } else {
            return 
BigInteger(n).isOdd() ? this this.negate();
        }
    }

    
BigInteger(n);
    if (
n._s === 0) {
        return 
BigInteger.ONE;
    } else if (
n._s 0) {
        if (
this._s === 0) {
            throw new 
Error("Divide by zero");
        } else {
            return 
BigInteger.ZERO;
        }
    }
    if (
this._s === 0) {
        return 
BigInteger.ZERO;
    }
    if (
n.isUnit()) {
        return 
this;
    }

    if (
n.compareAbs(BigInteger.MAX_EXP) > 0) {
        throw new 
Error("exponent too large in BigInteger.pow");
    }
    var 
this;
    var 
aux BigInteger.ONE;
    var 
two BigInteger.small[2];

    while (
n.isPositive()) {
        if (
n.isOdd()) {
            
aux aux.multiply(x);
            if (
n.isUnit()) {
                return 
aux;
            }
        }
        
x.square();
        
n.quotient(two);
    }

    return 
aux;
};

/*
    Function: modPow
    Raise a <BigInteger> to a power (mod m).

    Because it is reduced by a modulus, <modPow> is not limited by
    <BigInteger.MAX_EXP> like <pow>.

    Parameters:

        exponent - The exponent to raise *this* by. Must be positive.
        modulus - The modulus.

    Returns:

        *this* ^ *exponent* (mod *modulus*).

    See Also:

        <pow>, <mod>
*/
BigInteger.prototype.modPow = function (exponentmodulus) {
    var 
result BigInteger.ONE;
    var 
base this;

    while (
exponent.isPositive()) {
        if (
exponent.isOdd()) {
            
result result.multiply(base).remainder(modulus);
        }

        
exponent exponent.quotient(BigInteger.small[2]);
        if (
exponent.isPositive()) {
            
base base.square().remainder(modulus);
        }
    }

    return 
result;
};

/*
    Function: log
    Get the natural logarithm of a <BigInteger> as a native JavaScript number.

    This is equivalent to

    > Math.log(this.toJSValue())

    but handles values outside of the native number range.

    Returns:

        log( *this* )

    See Also:

        <toJSValue>
*/
BigInteger.prototype.log = function () {
    switch (
this._s) {
    case 
0:
        return -
Infinity;
    case -
1:
        return 
NaN;
    default:
        
// Fall through.
    
}

    var 
this._d.length;

    if (
BigInteger.base_log10 30) {
        return 
Math.log(this.valueOf());
    }

    var 
Math.ceil(30 BigInteger.base_log10);
    var 
firstNdigits this._d.slice(N);
    return 
Math.log((new BigInteger(firstNdigits1)).valueOf()) + (N) * Math.log(BigInteger.base);
};

/*
    Function: valueOf
    Convert a <BigInteger> to a native JavaScript integer.

    This is called automatically by JavaScipt to convert a <BigInteger> to a
    native value.

    Returns:

        > parseInt(this.toString(), 10)

    See Also:

        <toString>, <toJSValue>
*/
BigInteger.prototype.valueOf = function () {
    return 
parseInt(this.toString(), 10);
};

/*
    Function: toJSValue
    Convert a <BigInteger> to a native JavaScript integer.

    This is the same as valueOf, but more explicitly named.

    Returns:

        > parseInt(this.toString(), 10)

    See Also:

        <toString>, <valueOf>
*/
BigInteger.prototype.toJSValue = function () {
    return 
parseInt(this.toString(), 10);
};

// Constant: MAX_EXP
// The largest exponent allowed in <pow> and <exp10> (0x7FFFFFFF or 2147483647).
BigInteger.MAX_EXP BigInteger(0x7FFFFFFF);

(function () {
    function 
makeUnary(fn) {
        return function (
a) {
            return 
fn.call(BigInteger(a));
        };
    }

    function 
makeBinary(fn) {
        return function (
ab) {
            return 
fn.call(BigInteger(a), BigInteger(b));
        };
    }

    function 
makeTrinary(fn) {
        return function (
abc) {
            return 
fn.call(BigInteger(a), BigInteger(b), BigInteger(c));
        };
    }

    (function () {
        var 
ifn;
        var 
unary "toJSValue,isEven,isOdd,sign,isZero,isNegative,abs,isUnit,square,negate,isPositive,toString,next,prev,log".split(",");
        var 
binary "compare,remainder,divRem,subtract,add,quotient,divide,multiply,pow,compareAbs".split(",");
        var 
trinary = ["modPow"];

        for (
0unary.lengthi++) {
            
fn unary[i];
            
BigInteger[fn] = makeUnary(BigInteger.prototype[fn]);
        }

        for (
0binary.lengthi++) {
            
fn binary[i];
            
BigInteger[fn] = makeBinary(BigInteger.prototype[fn]);
        }

        for (
0trinary.lengthi++) {
            
fn trinary[i];
            
BigInteger[fn] = makeTrinary(BigInteger.prototype[fn]);
        }

        
BigInteger.exp10 = function (xn) {
            return 
BigInteger(x).exp10(n);
        };
    })();
})();

if (
typeof exports !== 'undefined') {
    
exports.BigInteger BigInteger;