114 lines
3.0 KiB
JavaScript
114 lines
3.0 KiB
JavaScript
// Big integer base-10 printing library
|
|
// Copyright (c) 2008-2020 Lapo Luchini <lapo@lapo.it>
|
|
|
|
// Permission to use, copy, modify, and/or distribute this software for any
|
|
// purpose with or without fee is hereby granted, provided that the above
|
|
// copyright notice and this permission notice appear in all copies.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
(typeof define != 'undefined' ? define : function (factory) { 'use strict';
|
|
if (typeof module == 'object') module.exports = factory();
|
|
else window.int10 = factory();
|
|
})(function () {
|
|
"use strict";
|
|
|
|
var max = 10000000000000; // biggest 10^n integer that can still fit 2^53 when multiplied by 256
|
|
|
|
/**
|
|
* Arbitrary length base-10 value.
|
|
* @param {number} value - Optional initial value (will be 0 otherwise).
|
|
*/
|
|
function Int10(value) {
|
|
this.buf = [+value || 0];
|
|
}
|
|
|
|
/**
|
|
* Multiply value by m and add c.
|
|
* @param {number} m - multiplier, must be < =256
|
|
* @param {number} c - value to add
|
|
*/
|
|
Int10.prototype.mulAdd = function (m, c) {
|
|
// assert(m <= 256)
|
|
var b = this.buf,
|
|
l = b.length,
|
|
i, t;
|
|
for (i = 0; i < l; ++i) {
|
|
t = b[i] * m + c;
|
|
if (t < max)
|
|
c = 0;
|
|
else {
|
|
c = 0|(t / max);
|
|
t -= c * max;
|
|
}
|
|
b[i] = t;
|
|
}
|
|
if (c > 0)
|
|
b[i] = c;
|
|
};
|
|
|
|
/**
|
|
* Subtract value.
|
|
* @param {number} c - value to subtract
|
|
*/
|
|
Int10.prototype.sub = function (c) {
|
|
var b = this.buf,
|
|
l = b.length,
|
|
i, t;
|
|
for (i = 0; i < l; ++i) {
|
|
t = b[i] - c;
|
|
if (t < 0) {
|
|
t += max;
|
|
c = 1;
|
|
} else
|
|
c = 0;
|
|
b[i] = t;
|
|
}
|
|
while (b[b.length - 1] === 0)
|
|
b.pop();
|
|
};
|
|
|
|
/**
|
|
* Convert to decimal string representation.
|
|
* @param {*} base - optional value, only value accepted is 10
|
|
*/
|
|
Int10.prototype.toString = function (base) {
|
|
if ((base || 10) != 10)
|
|
throw 'only base 10 is supported';
|
|
var b = this.buf,
|
|
s = b[b.length - 1].toString();
|
|
for (var i = b.length - 2; i >= 0; --i)
|
|
s += (max + b[i]).toString().substring(1);
|
|
return s;
|
|
};
|
|
|
|
/**
|
|
* Convert to Number value representation.
|
|
* Will probably overflow 2^53 and thus become approximate.
|
|
*/
|
|
Int10.prototype.valueOf = function () {
|
|
var b = this.buf,
|
|
v = 0;
|
|
for (var i = b.length - 1; i >= 0; --i)
|
|
v = v * max + b[i];
|
|
return v;
|
|
};
|
|
|
|
/**
|
|
* Return value as a simple Number (if it is <= 10000000000000), or return this.
|
|
*/
|
|
Int10.prototype.simplify = function () {
|
|
var b = this.buf;
|
|
return (b.length == 1) ? b[0] : this;
|
|
};
|
|
|
|
return Int10;
|
|
|
|
});
|