| /** | ||
| * IntN.js embeddable (c) 2014 Daniel Wirtz <dcode@dcode.io> | ||
| * Released under the Apache License, Version 2.0 | ||
| * see: https://github.com/dcodeIO/IntN.js for details | ||
| */ | ||
| var IntN = (function() { | ||
| "use strict"; | ||
| /** | ||
| * Creates a class for representing `nBits` bit integers. | ||
| * @param {number} nBits Number of bits (must be a positive multiple of 8) | ||
| * @returns {!Function} | ||
| * @inner | ||
| */ | ||
| function makeIntN(nBits) { | ||
| if (nBits <= 0 || (nBits%8) !== 0) | ||
| throw Error("illegal number of bits: "+nBits+" (not a positive multiple of 8)"); | ||
| // Make sure to return singleton classes | ||
| if (classes[nBits]) | ||
| return classes[nBits]; | ||
| /** | ||
| * Number of bytes. | ||
| * @type {number} | ||
| * @inner | ||
| */ | ||
| var nBytes = (nBits/8)|0; | ||
| /** | ||
| * Maximum byte index. | ||
| * @type {number} | ||
| * @inner | ||
| */ | ||
| var maxIndex = nBytes-1; | ||
| /** | ||
| * Array of binary zeroes. | ||
| * @type {!Array.<number>} | ||
| * @inner | ||
| */ | ||
| var zeroes = new Array(nBytes); | ||
| for (var i=0; i<nBytes; ++i) | ||
| zeroes[i] = 0; | ||
| /** | ||
| * Array of binary ones. | ||
| * @type {!Array.<number>} | ||
| * @inner | ||
| */ | ||
| var ones = new Array(nBytes); | ||
| for (i=0; i<nBytes; ++i) | ||
| ones[i] = 0xff; | ||
| /** | ||
| * Constructs a new IntN, where N is the number of bits represented by this class. | ||
| * @class A class for representing arbitrary size integers, both signed and unsigned. | ||
| * @exports IntN | ||
| * @param {!Array.<number>|number} bytes Byte values, least significant first | ||
| * @param {boolean=} unsigned Whether unsigned or signed, defaults to `false` for signed | ||
| * @constructor | ||
| */ | ||
| function IntN(bytes, unsigned) { | ||
| /** | ||
| * Represented byte values, least significant first. | ||
| * @type {!Array.<number>} | ||
| * @expose | ||
| */ | ||
| this.bytes = new Array(nBytes); | ||
| for (var i=0, k=bytes.length; i<k; ++i) | ||
| this.bytes[i] = bytes[i] & 0xff; | ||
| for (; i<nBytes; ++i) | ||
| this.bytes[i] = 0; | ||
| /** | ||
| * Whether unsigned or otherwise signed. | ||
| * @type {boolean} | ||
| * @expose | ||
| */ | ||
| this.unsigned = !!unsigned; | ||
| // ++IntN.NEW_COUNT; | ||
| } | ||
| /** | ||
| * Number of bits represented by this IntN class. | ||
| * @type {number} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.BITS = nBits|0; | ||
| /** | ||
| * Number of bytes represented by this IntN class. | ||
| * @type {number} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.BYTES = nBytes; | ||
| /** | ||
| * Number of so far created instances for performance analysis. | ||
| * @type {number} | ||
| * @private | ||
| * @expose | ||
| */ | ||
| // IntN.NEW_COUNT = 0; | ||
| // General utility | ||
| /** | ||
| * Tests if an object is an N bit integer, where N is this class's number of bits. | ||
| * @param {*} obj Object to test | ||
| * @returns {boolean} `true` if it is an N bit integer, otherwise `false` | ||
| * @expose | ||
| */ | ||
| IntN.isIntN = function(obj) { | ||
| return (obj && Array.isArray(obj.bytes) && obj.bytes.length === nBytes && typeof obj.unsigned === 'boolean') | ||
| === true; | ||
| }; | ||
| /** | ||
| * Converts the specified value to an IntN. | ||
| * @param {number|string|!{bytes: !Array.<number>, unsigned: boolean}} val Value | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.valueOf = function(val) { | ||
| if (typeof val === 'number') | ||
| return IntN.fromNumber(val); | ||
| else if (typeof val === 'string') | ||
| return IntN.fromString(val); | ||
| else if (val && val instanceof IntN && val.bytes.length == nBytes) | ||
| return val; | ||
| // Throws for not an object (undefined, null) bytes not an array (in constructor), | ||
| // fills smaller, truncates larger N (does not respect sign if differing): | ||
| return new IntN(val.bytes, val.unsigned); | ||
| }; | ||
| /** | ||
| * Casts this IntN of size N to the specified target IntN of size M. | ||
| * @param {!Function} TargetIntN Target IntN class | ||
| * @param {boolean=} unsigned Whether unsigned or not, defaults to this' {@link IntN#unsigned} | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.cast = function(TargetIntN, unsigned) { | ||
| unsigned = typeof unsigned === 'boolean' ? unsigned : this.unsigned; | ||
| var retainMsb = this.isNegative(), | ||
| val = retainMsb ? this.not() : this; | ||
| val = new TargetIntN(val.bytes, unsigned); | ||
| return retainMsb ? val.not() : val; | ||
| }; | ||
| // Basic constants | ||
| /** | ||
| * Signed zero. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.ZERO = new IntN([], false); | ||
| /** | ||
| * Unsigned zero. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.UZERO = new IntN([], true); | ||
| /** | ||
| * Signed one. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.ONE = new IntN([1], false); | ||
| /** | ||
| * Unsigned one. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.UONE = new IntN([1], true); | ||
| /** | ||
| * Minimum signed value. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.MIN_VALUE = new IntN(zeroes.slice(0, nBytes)); | ||
| IntN.MIN_VALUE.bytes[maxIndex] |= 0x80; | ||
| /** | ||
| * Maximum signed value. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.MAX_VALUE = new IntN(ones.slice(0, nBytes)); | ||
| IntN.MAX_VALUE.bytes[maxIndex] &= 0x7f; | ||
| /** | ||
| * Maximum unsigned value. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.MAX_UNSIGNED_VALUE = new IntN(ones.slice(0, nBytes), true); | ||
| // Signed evaluation | ||
| /** | ||
| * Tests if this IntN is signed. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isSigned = function() { | ||
| return !this.unsigned; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is unsigned. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isUnsigned = function() { | ||
| return this.unsigned; | ||
| }; | ||
| // Signed conversion | ||
| /** | ||
| * Converts this IntN to signed and returns the result. | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toSigned = function() { | ||
| if (!this.unsigned) | ||
| return this; | ||
| return new IntN(this.bytes, false); | ||
| }; | ||
| /** | ||
| * Converts this IntN to unsigned and returns the result. | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toUnsigned = function() { | ||
| if (this.unsigned) | ||
| return this; | ||
| return new IntN(this.bytes, true); | ||
| }; | ||
| // Arithmetic evalutation | ||
| /** | ||
| * Tests if this IntN is (signed and) negative. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isNegative = function() { | ||
| return !this.unsigned && (this.bytes[maxIndex] & 0x80) === 0x80; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is (unsigned or) positive. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isPositive = function() { | ||
| return this.unsigned || (this.bytes[maxIndex] & 0x80) === 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is even. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isEven = function() { | ||
| return (this.bytes[0] & 1) === 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is odd. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isOdd = function() { | ||
| return (this.bytes[0] & 1) === 1; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is zero. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isZero = function() { | ||
| for (var i=0; i<nBytes; ++i) | ||
| if (this.bytes[i] !== 0) | ||
| return false; | ||
| return true; | ||
| }; | ||
| /** | ||
| * Compares this IntN with the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {number} `0` if both are the same, `1` if this is greater and `-1` if the specified is greater | ||
| * @expose | ||
| */ | ||
| IntN.prototype.compare = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| if (this.isNegative() && !other.isNegative()) | ||
| return -1; | ||
| if (!this.isNegative() && other.isNegative()) | ||
| return 1; | ||
| for (var i=maxIndex; i>=0; --i) | ||
| if (this.bytes[i] < other.bytes[i]) | ||
| return -1; | ||
| else if (this.bytes[i] > other.bytes[i]) | ||
| return 1; | ||
| return 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN equals the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.equals = function(other) { | ||
| return this.compare(other) === 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN does not equal the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.notEquals = function(other) { | ||
| return this.compare(other) !== 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is less than (<) the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.lessThan = function(other) { | ||
| return this.compare(other) === -1; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is less than or equal (<=) the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.lessThanEqual = function(other) { | ||
| return this.compare(other) <= 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is greater than (>) the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.greaterThan = function(other) { | ||
| return this.compare(other) === 1; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is greater than or equal (>=) the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.greaterThanEqual = function(other) { | ||
| return this.compare(other) >= 0; | ||
| }; | ||
| // Integer conversion | ||
| /** | ||
| * Constructs an IntN from a 32bit integer value. | ||
| * @param {number} value Integer value | ||
| * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.fromInt = function(value, unsigned) { | ||
| value = value|0; | ||
| var val; | ||
| if (value < 0) { | ||
| if (value === int32_min_value) // -MIN_VALUE = MIN_VALUE | ||
| return IntN.MIN_VALUE; | ||
| val = IntN.fromInt(-value, unsigned).negate(); | ||
| return val; | ||
| } | ||
| var bytes = new Array(nBytes); | ||
| for (var i=0; i<nBytes; ++i) | ||
| bytes[i] = (value >>> (i*8)) & 0xff; | ||
| val = new IntN(bytes, unsigned); | ||
| return val; | ||
| }; | ||
| /** | ||
| * Converts this IntN to a 32bit integer. | ||
| * @param {boolean=} unsigned Whether unsigned or not, defaults to this' {@link IntN#unsigned} | ||
| * @returns {number} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toInt = function(unsigned) { | ||
| unsigned = typeof unsigned === 'boolean' ? unsigned : this.unsigned; | ||
| var retainMsb = this.isNegative(), | ||
| val = retainMsb ? this.not() : this; | ||
| for (var i=0, result=0; i<Math.min(4, val.bytes.length); ++i) | ||
| result |= val.bytes[i] << (i*8); | ||
| if (retainMsb) | ||
| result = ~result; | ||
| return unsigned ? result >>> 0 : result; | ||
| }; | ||
| /** | ||
| * Reassembles an IntN from an array of 32bit integers, least significant first. | ||
| * @param {!Array.<number>} ints Array of 32bit integers | ||
| * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.fromInts = function(ints, unsigned) { | ||
| var result = IntN.ZERO; | ||
| for (var i=0, k=Math.min(ints.length, Math.ceil(nBytes/4)), val; i<k; ++i) | ||
| val = ints[i], | ||
| result = result.or(new IntN([ | ||
| val & 0xff, | ||
| (val >>> 8) & 0xff, | ||
| (val >>> 16) & 0xff, | ||
| (val >>> 24) & 0xff | ||
| ]).shiftLeft(i*32)); | ||
| return unsigned ? result.toUnsigned() : result; | ||
| }; | ||
| /** | ||
| * Disassembles this IntN into an array of 32bit integers, least significant first. | ||
| * @returns {!Array.<number>} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toInts = function() { | ||
| var numChunks = Math.ceil(nBytes/4), | ||
| arr = new Array(numChunks); | ||
| for (var i=0, offset=0, val; i<numChunks; offset=++i*4) { | ||
| val = 0; | ||
| for (var j=0, l=Math.min(4, nBytes-offset); j<l; ++j) | ||
| val |= this.bytes[offset+j] << (j*8); | ||
| arr[i] = val; | ||
| } | ||
| return arr; | ||
| }; | ||
| // Number conversion | ||
| /** | ||
| * Constructs an IntN from a number (double, 52 bit mantissa) value. | ||
| * @param {number} value Number value | ||
| * @param {boolean=} unsigned Whether unsigned or not, defaults `false` for signed | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.fromNumber = function(value, unsigned) { | ||
| if (typeof value !== 'number') | ||
| throw TypeError("illegal arguments: "+typeof(value)); | ||
| if (value !== value || !isFinite(value) || value === 0) | ||
| return unsigned ? IntN.UZERO : IntN.ZERO; | ||
| if (value < 0) | ||
| return IntN.fromNumber(-value, unsigned).negate(); | ||
| // now always gt 0: | ||
| for (var i=0, bytes=new Array(nBytes); i<nBytes; ++i) | ||
| bytes[i] = (value % 256) & 0xff, // bytes[maxIndex] may overflow the sign bit | ||
| value = Math.floor(value / 256); | ||
| return new IntN(bytes, unsigned); | ||
| }; | ||
| /** | ||
| * Converts this IntN to a number (double, 52 bit mantissa) value. | ||
| * @returns {number} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toNumber = function() { | ||
| if (this.isZero()) | ||
| return 0; | ||
| if (this.isNegative()) | ||
| return this.equals(IntN.MIN_VALUE) ? +int32_min_value : -this.negate().toNumber(); // -MIN_VALUE = MIN_VALUE | ||
| // now always gt 0: | ||
| for (var i=0, result=0, k=Math.min(nBytes, 7); i<k; ++i) // 7 bytes = 56 bits | ||
| result += this.bytes[i] * double_256_pwr[i]; | ||
| return result; | ||
| }; | ||
| // Bitwise operations | ||
| /** | ||
| * Performs a bitwise not (~) operation and returns the result. | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.not = function() { | ||
| for (var i=0, bytes=new Array(nBytes); i<nBytes; ++i) | ||
| bytes[i] = ~this.bytes[i]; // & 0xff not necessary, see test | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| /** | ||
| * Performs a bitwise and (&) operation and returns the resulting Int. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.and = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| for (var i=0, bytes=new Array(nBytes); i<nBytes; ++i) | ||
| bytes[i] = this.bytes[i] & other.bytes[i]; | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| /** | ||
| * Performs a bitwise or (|) operation and returns the resulting Int. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.or = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| for (var i=0, bytes=new Array(nBytes); i<nBytes; ++i) | ||
| bytes[i] = this.bytes[i] | other.bytes[i]; | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| /** | ||
| * Performs a bitwise xor (^) operation and returns the result. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.xor = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| for (var i=0, bytes=new Array(nBytes); i<nBytes; ++i) | ||
| bytes[i] = this.bytes[i] ^ other.bytes[i]; | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| /** | ||
| * Performs a shift left (<<) operation and returns the result. | ||
| * @param {!IntN|number} numBits Number of bits | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.shiftLeft = function(numBits) { | ||
| if (IntN.isIntN(numBits)) | ||
| numBits = numBits.toInt(); | ||
| numBits &= nBits-1; // << 0 ^= << n | ||
| if (numBits === 0) | ||
| return this; | ||
| var numBytes = (numBits/8)|0; // Full byte skips | ||
| numBits %= 8; // Byte level bit skips | ||
| for (var i=0, bytes=zeroes.slice(0, nBytes), idx; i<nBytes; ++i) { | ||
| if ((idx = i+numBytes) >= nBytes) | ||
| break; | ||
| bytes[idx] |= (this.bytes[i] << numBits) & 0xff; | ||
| if (++idx < nBytes) | ||
| bytes[idx] |= (this.bytes[i] << numBits >>> 8) & 0xff; | ||
| } | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| /** | ||
| * Performs a shift right (>>, >>>) operation and returns the result. | ||
| * @param {!IntN|number} numBits Number of bits | ||
| * @param {boolean=} logical Whether to perform a logical (>>>) shift right, defaults to `false` for an arithmetic | ||
| * shift right (>>) | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.shiftRight = function(numBits, logical) { | ||
| if (IntN.isIntN(numBits)) | ||
| numBits = numBits.toInt(); | ||
| numBits &= nBits-1; // >> 0 ^= >> n | ||
| if (numBits === 0) | ||
| return this; | ||
| var numBytes = (numBits/8)|0; // Full byte skips | ||
| numBits %= 8; // Byte level bit skips | ||
| var bytes = zeroes.slice(0, nBytes), i; | ||
| if (!logical && (this.bytes[maxIndex] & 0x80) === 0x80) { | ||
| var k; for (i=nBytes-1, k=nBytes-numBytes-1; i>=k; --i) | ||
| bytes[i] = 0xff; | ||
| bytes[++i /* !k */] = (bytes[i] << (7-numBits)) & 0xff; | ||
| } | ||
| var idx; | ||
| for (i=0; i<nBytes; ++i) { | ||
| if ((idx = i-numBytes) >= 0) | ||
| bytes[idx] |= (this.bytes[i] >>> numBits) & 0xff; | ||
| if (--idx >= 0) | ||
| bytes[idx] |= (this.bytes[i] << 8 >>> numBits) & 0xff; | ||
| } | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| /** | ||
| * Performs an unsigned shift right (>>>) operation and returns the result. | ||
| * @param {!IntN|number} numBits Number of bits | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.shiftRightUnsigned = function(numBits) { | ||
| return this.shiftRight(numBits, true); | ||
| }; | ||
| // Arithmetic operations | ||
| /** | ||
| * Adds the specified to this IntN and returns the result. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.add = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| if (other.isZero()) | ||
| return this; | ||
| if (this.isZero()) | ||
| return this.unsigned ? other.toUnsigned() : other.toSigned(); | ||
| var carry = this.and(other), | ||
| result = this.xor(other), | ||
| carryPwr2; | ||
| while (!carry.isZero()) | ||
| carryPwr2 = carry.shiftLeft(1), | ||
| carry = result.and(carryPwr2), | ||
| result = result.xor(carryPwr2); | ||
| return result; | ||
| }; | ||
| /** | ||
| * Negates this IntN (*-1) and returns the result. | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.negate = function() { | ||
| return this.not().add(IntN.ONE); | ||
| }; | ||
| /** | ||
| * Negative signed one. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.NEG_ONE = IntN.ONE.negate(); | ||
| /** | ||
| * Subtracts the specified from this IntN and returns the result. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.subtract = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| return this.add(other.negate()); | ||
| }; | ||
| /** | ||
| * Returns this IntN's absolute value as an unsigned IntN. | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.absolute = function() { | ||
| if (this.unsigned) | ||
| return this; | ||
| return (this.isNegative() ? this.negate() : this).toUnsigned(); | ||
| }; | ||
| /** | ||
| * Multiplies this IntN with the specified and returns the result. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.multiply = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| if (this.isZero()) // other == 0 will break the loop below early while this == 0 will not | ||
| return this; | ||
| var isNegative = this.isNegative() !== other.isNegative(), | ||
| a = this.absolute(), | ||
| b = other.absolute(), | ||
| result = this.unsigned ? IntN.UZERO : IntN.ZERO; | ||
| for(;!b.isZero(); a=a.shiftLeft(1), b=b.shiftRight(1, true)) | ||
| if ((b.bytes[0] & 1) === 1) | ||
| result = result.add(a); | ||
| return isNegative ? result.negate() : result; | ||
| }; | ||
| /** | ||
| * Divides the specified dividend by the specified divisor. This method is used internally by {@link IntN#divide} | ||
| * and {@link IntN#modulo} and is exposed statically in case both the result and the remainder are required. | ||
| * @param {!IntN} dividend | ||
| * @param {!IntN} divisor | ||
| * @returns {!{quotient: !IntN, remainder: !IntN}} | ||
| * @expose | ||
| */ | ||
| IntN.divide = function(dividend, divisor) { | ||
| if (divisor.isZero()) | ||
| throw Error("division by zero"); | ||
| if (dividend.isZero()) | ||
| return { | ||
| "quotient": dividend.unsigned ? IntN.UZERO : IntN.ZERO, | ||
| "remainder": dividend | ||
| }; | ||
| var isNegative = dividend.isNegative() !== divisor.isNegative(), | ||
| quotient = dividend.unsigned ? IntN.UZERO : IntN.ZERO, | ||
| remainder = dividend.absolute(), | ||
| product = divisor.absolute(), | ||
| term = IntN.UONE, | ||
| maxTerm = IntN.MIN_VALUE.toUnsigned(); | ||
| while (term.lessThan(maxTerm) && product.lessThan(remainder)) | ||
| product = product.shiftLeft(1), | ||
| term = term.shiftLeft(1); | ||
| while (term.greaterThanEqual(IntN.UONE)) { | ||
| if (product.lessThanEqual(remainder)) | ||
| quotient = quotient.add(term), | ||
| remainder = remainder.subtract(product); | ||
| product = product.shiftRight(1, true); | ||
| term = term.shiftRight(1, true); | ||
| } | ||
| return { | ||
| "quotient": isNegative ? quotient.negate() : quotient, | ||
| "remainder": remainder | ||
| }; | ||
| }; | ||
| /** | ||
| * Divides this IntN by the specified and returns the result. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.divide = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| return IntN.divide(this, other)['quotient']; | ||
| }; | ||
| /** | ||
| * Returns the remainder of the division of this IntN by the specified. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.modulo = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| return IntN.divide(this, other)['remainder']; | ||
| }; | ||
| /** | ||
| * Converts this IntN to its full binary representation. This returns N (number of bits) binary digits for | ||
| * testing and debugging, followed by the character `U` if unsigned. | ||
| * @param {boolean=} spaces Whether to insert spaces between bytes, defaults to `false` | ||
| * @returns {string} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toDebug = function(spaces) { | ||
| for (var i=maxIndex, byt, out=""; i>=0; --i) { | ||
| byt = this.bytes[i].toString(2); | ||
| while (byt.length < 8) | ||
| byt = '0'+byt; | ||
| out += byt; | ||
| if (spaces && i > 0) | ||
| out += ' '; | ||
| } | ||
| if (this.unsigned) | ||
| out += spaces ? " U" : 'U'; | ||
| return out; | ||
| }; | ||
| // String conversion | ||
| /** | ||
| * IntN representing 2. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var IntN_2 = IntN.fromInt(2); | ||
| /** | ||
| * IntN representing 36. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var IntN_36 = IntN.fromInt(36); | ||
| /** | ||
| * Converts a string using the specified radix to an IntN. | ||
| * @param {string} value String | ||
| * @param {(boolean|number)=} unsigned Whether unsigned or not, defaults to `false` for signed (omittable) | ||
| * @param {number=} radix Radix (2-36), defaults to 10 | ||
| * @returns {!IntN} | ||
| * @throws {RangeError} If `radix` is out of range | ||
| * @throws {Error} If `value` contains illegal characters | ||
| * @expose | ||
| */ | ||
| IntN.fromString = function(value, unsigned, radix) { | ||
| if (typeof unsigned === 'number') | ||
| radix = unsigned, | ||
| unsigned = false; | ||
| value = (value+"").toLowerCase(); | ||
| radix = radix || 10; | ||
| if (radix < 2 || radix > 36) | ||
| throw RangeError("radix out of range: "+radix+" (2-36)"); | ||
| if (value.charAt(0) === '-') | ||
| return IntN.fromString(value.substring(1), unsigned, radix).negate(); | ||
| if (value.charAt(0) === '+') | ||
| value = value.substring(1); | ||
| // now always gte 0: | ||
| if (value === '0' || value === 'NaN' || value === 'Infinity') | ||
| return unsigned ? IntN.UZERO : IntN.ZERO; | ||
| // now always gt 0: | ||
| var result = unsigned ? IntN.UZERO : IntN.ZERO, | ||
| radixToPower = (radix === 2) | ||
| ? function(i) { return 1 << i; } | ||
| : Math.pow.bind(Math, radix); | ||
| for (var i=0, k=value.length, ch, val; i<k; ++i) { | ||
| ch = value.charAt(k-i-1); | ||
| val = chars.indexOf(ch); | ||
| if (val < 0 || val > radix) | ||
| throw Error("illegal interior character: "+ch); | ||
| result = result.add(IntN.fromInt(val).multiply(IntN.fromInt(radixToPower(i)))); | ||
| } | ||
| return result; | ||
| }; | ||
| /** | ||
| * Converts this IntN to a string of the specified radix. | ||
| * @param {!IntN|number|string} radix Radix (2-36), defaults to 10 | ||
| * @returns {string} | ||
| * @throws {RangeError} If `radix` is out of range | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toString = function(radix) { | ||
| radix = radix || 10; | ||
| if (!IntN.isIntN(radix)) | ||
| radix = IntN.valueOf(radix); | ||
| if (radix.lessThan(IntN_2) || radix.greaterThan(IntN_36)) | ||
| throw RangeError("radix out of range: "+radix.toInt()+" (2-36)"); | ||
| var zero = this.unsigned ? IntN.UZERO : IntN.ZERO; | ||
| if (this.equals(zero)) | ||
| return '0'; | ||
| if (this.isNegative()) { | ||
| if (this.equals(IntN.MIN_VALUE)) { // -MIN_VALUE = MIN_VALUE | ||
| var div = IntN.divide(this, radix)['quotient'], | ||
| rem = div.multiply(radix).subtract(this); | ||
| return div.toString(radix) + rem.toInt().toString(radix.toInt()); | ||
| } | ||
| return '-'+this.negate().toString(radix); | ||
| } | ||
| // now always gt 0: | ||
| var result = this, | ||
| digits = [], | ||
| mod; | ||
| do | ||
| mod = result.modulo(radix), | ||
| digits.unshift(chars.charAt(mod.toInt())), | ||
| result = IntN.divide(result, radix)['quotient']; | ||
| while (!result.equals(zero)); | ||
| return digits.join(''); | ||
| }; | ||
| // Setup aliases | ||
| IntN['isInt'+nBits] = IntN.isIntN; | ||
| for (var key in aliases.statics) | ||
| if (aliases.statics.hasOwnProperty(key)) | ||
| for (i=0; i<aliases.statics[key].length; ++i) | ||
| IntN[aliases.statics[key][i]] = IntN[key]; | ||
| for (key in aliases.prototype) | ||
| if (aliases.prototype.hasOwnProperty(key)) | ||
| for (i=0; i<aliases.prototype[key].length; ++i) | ||
| IntN.prototype[aliases.prototype[key][i]] = IntN.prototype[key]; | ||
| return classes[nBits] = IntN; | ||
| } // makeIntN | ||
| /** | ||
| * Classes cache. | ||
| * @type {!Object.<number,!Function>} | ||
| * @inner | ||
| */ | ||
| var classes = {}; | ||
| /** | ||
| * Minimum 32bit signed integer value. | ||
| * @type {number} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var int32_min_value = 0x80000000|0; | ||
| /** | ||
| * Relevant powers (0-7) of 256 for number conversion. | ||
| * @type {!Array.<number>} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var double_256_pwr = [ | ||
| 1, | ||
| 256, | ||
| 65536, | ||
| 16777216, | ||
| 4294967296, | ||
| 1099511627776, | ||
| 281474976710656 | ||
| // >= ^7 is inexact | ||
| ]; | ||
| /** | ||
| * Valid characters for string conversion. | ||
| * @type {string} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var chars = "0123456789abcdefghijklmnopqrstuvwxyz"; | ||
| /** | ||
| * Alias names of static and prototype methods. | ||
| * @type {!{statics: !Object.<string,!Array.<string>>, prototype: !Object.<string,!Array.<string>>}} | ||
| * @inner | ||
| */ | ||
| var aliases = { | ||
| statics: { | ||
| // General utility | ||
| // 'isIntN': ['isInt'+nBits] // not known yet | ||
| }, | ||
| prototype: { | ||
| // Arithmetic evaluation | ||
| 'compare': ['comp'], | ||
| 'equals': ['eq', 'equal', '=='], | ||
| 'notEquals': ['ne', 'notEqual', '!='], | ||
| 'lessThan': ['lt', 'less', 'lesser', '<'], | ||
| 'lessThanEqual': ['lte', 'lessThanOrEqual', '<='], | ||
| 'greaterThan': ['gt', 'greater', '>'], | ||
| 'greaterThanEqual': ['gte', 'greaterThanOrEqual', '>='], | ||
| // Bitwise operations | ||
| 'not': ['~'], | ||
| 'and': ['&'], | ||
| 'or': ['|'], | ||
| 'xor': ['^'], | ||
| 'shiftLeft': ['lsh', 'leftShift', '<<'], | ||
| 'shiftRight': ['rsh', 'rightShift', '>>'], | ||
| 'shiftRightUnsigned': ['rshu', 'rightShiftUnsigned', '>>>'], | ||
| // Arithmetic operations | ||
| 'add': ['plus', '+'], | ||
| 'negate': ['neg', '!'], | ||
| 'subtract': ['sub', 'minus', '-'], | ||
| 'absolute': ['abs', '||'], | ||
| 'multiply': ['mult', '*'], | ||
| 'divide': ['div', '/'], | ||
| 'modulo': ['mod', '%'] | ||
| } | ||
| }; | ||
| return makeIntN; | ||
| })(); |
| //? INTN_STANDALONE = false; | ||
| /** | ||
| * IntN.js embeddable (c) 2014 Daniel Wirtz <dcode@dcode.io> | ||
| * Released under the Apache License, Version 2.0 | ||
| * see: https://github.com/dcodeIO/IntN.js for details | ||
| */ | ||
| //? include("lib.js"); |
+983
| var IntN = (function() { | ||
| "use strict"; | ||
| /** | ||
| * Creates a class for representing `nBits` bit integers. | ||
| * @param {number} nBits Number of bits (must be a positive multiple of 8) | ||
| * @returns {!Function} | ||
| * @inner | ||
| */ | ||
| function makeIntN(nBits) { | ||
| if (nBits <= 0 || (nBits%8) !== 0) | ||
| throw Error("illegal number of bits: "+nBits+" (not a positive multiple of 8)"); | ||
| // Make sure to return singleton classes | ||
| if (classes[nBits]) | ||
| return classes[nBits]; | ||
| /** | ||
| * Number of bytes. | ||
| * @type {number} | ||
| * @inner | ||
| */ | ||
| var nBytes = (nBits/8)|0; | ||
| /** | ||
| * Maximum byte index. | ||
| * @type {number} | ||
| * @inner | ||
| */ | ||
| var maxIndex = nBytes-1; | ||
| /** | ||
| * Array of binary zeroes. | ||
| * @type {!Array.<number>} | ||
| * @inner | ||
| */ | ||
| var zeroes = new Array(nBytes); | ||
| for (var i=0; i<nBytes; ++i) | ||
| zeroes[i] = 0; | ||
| /** | ||
| * Array of binary ones. | ||
| * @type {!Array.<number>} | ||
| * @inner | ||
| */ | ||
| var ones = new Array(nBytes); | ||
| for (i=0; i<nBytes; ++i) | ||
| ones[i] = 0xff; | ||
| /** | ||
| * Constructs a new IntN, where N is the number of bits represented by this class. | ||
| * @class A class for representing arbitrary size integers, both signed and unsigned. | ||
| * @exports IntN | ||
| * @param {!Array.<number>|number} bytes Byte values, least significant first | ||
| * @param {boolean=} unsigned Whether unsigned or signed, defaults to `false` for signed | ||
| * @constructor | ||
| */ | ||
| function IntN(bytes, unsigned) { | ||
| /** | ||
| * Represented byte values, least significant first. | ||
| * @type {!Array.<number>} | ||
| * @expose | ||
| */ | ||
| this.bytes = new Array(nBytes); | ||
| for (var i=0, k=bytes.length; i<k; ++i) | ||
| this.bytes[i] = bytes[i] & 0xff; | ||
| for (; i<nBytes; ++i) | ||
| this.bytes[i] = 0; | ||
| /** | ||
| * Whether unsigned or otherwise signed. | ||
| * @type {boolean} | ||
| * @expose | ||
| */ | ||
| this.unsigned = !!unsigned; | ||
| // ++IntN.NEW_COUNT; | ||
| } | ||
| /** | ||
| * Number of bits represented by this IntN class. | ||
| * @type {number} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.BITS = nBits|0; | ||
| /** | ||
| * Number of bytes represented by this IntN class. | ||
| * @type {number} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.BYTES = nBytes; | ||
| /** | ||
| * Number of so far created instances for performance analysis. | ||
| * @type {number} | ||
| * @private | ||
| * @expose | ||
| */ | ||
| // IntN.NEW_COUNT = 0; | ||
| // General utility | ||
| /** | ||
| * Tests if an object is an N bit integer, where N is this class's number of bits. | ||
| * @param {*} obj Object to test | ||
| * @returns {boolean} `true` if it is an N bit integer, otherwise `false` | ||
| * @expose | ||
| */ | ||
| IntN.isIntN = function(obj) { | ||
| return (obj && Array.isArray(obj.bytes) && obj.bytes.length === nBytes && typeof obj.unsigned === 'boolean') | ||
| === true; | ||
| }; | ||
| /** | ||
| * Converts the specified value to an IntN. | ||
| * @param {number|string|!{bytes: !Array.<number>, unsigned: boolean}} val Value | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.valueOf = function(val) { | ||
| if (typeof val === 'number') | ||
| return IntN.fromNumber(val); | ||
| else if (typeof val === 'string') | ||
| return IntN.fromString(val); | ||
| else if (val && val instanceof IntN && val.bytes.length == nBytes) | ||
| return val; | ||
| // Throws for not an object (undefined, null) bytes not an array (in constructor), | ||
| // fills smaller, truncates larger N (does not respect sign if differing): | ||
| return new IntN(val.bytes, val.unsigned); | ||
| }; | ||
| /** | ||
| * Casts this IntN of size N to the specified target IntN of size M. | ||
| * @param {!Function} TargetIntN Target IntN class | ||
| * @param {boolean=} unsigned Whether unsigned or not, defaults to this' {@link IntN#unsigned} | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.cast = function(TargetIntN, unsigned) { | ||
| unsigned = typeof unsigned === 'boolean' ? unsigned : this.unsigned; | ||
| var retainMsb = this.isNegative(), | ||
| val = retainMsb ? this.not() : this; | ||
| val = new TargetIntN(val.bytes, unsigned); | ||
| return retainMsb ? val.not() : val; | ||
| }; | ||
| // Basic constants | ||
| /** | ||
| * Signed zero. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.ZERO = new IntN([], false); | ||
| /** | ||
| * Unsigned zero. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.UZERO = new IntN([], true); | ||
| /** | ||
| * Signed one. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.ONE = new IntN([1], false); | ||
| /** | ||
| * Unsigned one. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.UONE = new IntN([1], true); | ||
| /** | ||
| * Minimum signed value. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.MIN_VALUE = new IntN(zeroes.slice(0, nBytes)); | ||
| IntN.MIN_VALUE.bytes[maxIndex] |= 0x80; | ||
| /** | ||
| * Maximum signed value. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.MAX_VALUE = new IntN(ones.slice(0, nBytes)); | ||
| IntN.MAX_VALUE.bytes[maxIndex] &= 0x7f; | ||
| /** | ||
| * Maximum unsigned value. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.MAX_UNSIGNED_VALUE = new IntN(ones.slice(0, nBytes), true); | ||
| // Signed evaluation | ||
| /** | ||
| * Tests if this IntN is signed. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isSigned = function() { | ||
| return !this.unsigned; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is unsigned. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isUnsigned = function() { | ||
| return this.unsigned; | ||
| }; | ||
| // Signed conversion | ||
| /** | ||
| * Converts this IntN to signed and returns the result. | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toSigned = function() { | ||
| if (!this.unsigned) | ||
| return this; | ||
| return new IntN(this.bytes, false); | ||
| }; | ||
| /** | ||
| * Converts this IntN to unsigned and returns the result. | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toUnsigned = function() { | ||
| if (this.unsigned) | ||
| return this; | ||
| return new IntN(this.bytes, true); | ||
| }; | ||
| // Arithmetic evalutation | ||
| /** | ||
| * Tests if this IntN is (signed and) negative. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isNegative = function() { | ||
| return !this.unsigned && (this.bytes[maxIndex] & 0x80) === 0x80; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is (unsigned or) positive. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isPositive = function() { | ||
| return this.unsigned || (this.bytes[maxIndex] & 0x80) === 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is even. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isEven = function() { | ||
| return (this.bytes[0] & 1) === 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is odd. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isOdd = function() { | ||
| return (this.bytes[0] & 1) === 1; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is zero. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isZero = function() { | ||
| for (var i=0; i<nBytes; ++i) | ||
| if (this.bytes[i] !== 0) | ||
| return false; | ||
| return true; | ||
| }; | ||
| /** | ||
| * Compares this IntN with the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {number} `0` if both are the same, `1` if this is greater and `-1` if the specified is greater | ||
| * @expose | ||
| */ | ||
| IntN.prototype.compare = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| if (this.isNegative() && !other.isNegative()) | ||
| return -1; | ||
| if (!this.isNegative() && other.isNegative()) | ||
| return 1; | ||
| for (var i=maxIndex; i>=0; --i) | ||
| if (this.bytes[i] < other.bytes[i]) | ||
| return -1; | ||
| else if (this.bytes[i] > other.bytes[i]) | ||
| return 1; | ||
| return 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN equals the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.equals = function(other) { | ||
| return this.compare(other) === 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN does not equal the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.notEquals = function(other) { | ||
| return this.compare(other) !== 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is less than (<) the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.lessThan = function(other) { | ||
| return this.compare(other) === -1; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is less than or equal (<=) the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.lessThanEqual = function(other) { | ||
| return this.compare(other) <= 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is greater than (>) the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.greaterThan = function(other) { | ||
| return this.compare(other) === 1; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is greater than or equal (>=) the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.greaterThanEqual = function(other) { | ||
| return this.compare(other) >= 0; | ||
| }; | ||
| // Integer conversion | ||
| /** | ||
| * Constructs an IntN from a 32bit integer value. | ||
| * @param {number} value Integer value | ||
| * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.fromInt = function(value, unsigned) { | ||
| value = value|0; | ||
| var val; | ||
| if (value < 0) { | ||
| if (value === int32_min_value) // -MIN_VALUE = MIN_VALUE | ||
| return IntN.MIN_VALUE; | ||
| val = IntN.fromInt(-value, unsigned).negate(); | ||
| return val; | ||
| } | ||
| var bytes = new Array(nBytes); | ||
| for (var i=0; i<nBytes; ++i) | ||
| bytes[i] = (value >>> (i*8)) & 0xff; | ||
| val = new IntN(bytes, unsigned); | ||
| return val; | ||
| }; | ||
| /** | ||
| * Converts this IntN to a 32bit integer. | ||
| * @param {boolean=} unsigned Whether unsigned or not, defaults to this' {@link IntN#unsigned} | ||
| * @returns {number} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toInt = function(unsigned) { | ||
| unsigned = typeof unsigned === 'boolean' ? unsigned : this.unsigned; | ||
| var retainMsb = this.isNegative(), | ||
| val = retainMsb ? this.not() : this; | ||
| for (var i=0, result=0; i<Math.min(4, val.bytes.length); ++i) | ||
| result |= val.bytes[i] << (i*8); | ||
| if (retainMsb) | ||
| result = ~result; | ||
| return unsigned ? result >>> 0 : result; | ||
| }; | ||
| /** | ||
| * Reassembles an IntN from an array of 32bit integers, least significant first. | ||
| * @param {!Array.<number>} ints Array of 32bit integers | ||
| * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.fromInts = function(ints, unsigned) { | ||
| var result = IntN.ZERO; | ||
| for (var i=0, k=Math.min(ints.length, Math.ceil(nBytes/4)), val; i<k; ++i) | ||
| val = ints[i], | ||
| result = result.or(new IntN([ | ||
| val & 0xff, | ||
| (val >>> 8) & 0xff, | ||
| (val >>> 16) & 0xff, | ||
| (val >>> 24) & 0xff | ||
| ]).shiftLeft(i*32)); | ||
| return unsigned ? result.toUnsigned() : result; | ||
| }; | ||
| /** | ||
| * Disassembles this IntN into an array of 32bit integers, least significant first. | ||
| * @returns {!Array.<number>} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toInts = function() { | ||
| var numChunks = Math.ceil(nBytes/4), | ||
| arr = new Array(numChunks); | ||
| for (var i=0, offset=0, val; i<numChunks; offset=++i*4) { | ||
| val = 0; | ||
| for (var j=0, l=Math.min(4, nBytes-offset); j<l; ++j) | ||
| val |= this.bytes[offset+j] << (j*8); | ||
| arr[i] = val; | ||
| } | ||
| return arr; | ||
| }; | ||
| // Number conversion | ||
| /** | ||
| * Constructs an IntN from a number (double, 52 bit mantissa) value. | ||
| * @param {number} value Number value | ||
| * @param {boolean=} unsigned Whether unsigned or not, defaults `false` for signed | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.fromNumber = function(value, unsigned) { | ||
| if (typeof value !== 'number') | ||
| throw TypeError("illegal arguments: "+typeof(value)); | ||
| if (value !== value || !isFinite(value) || value === 0) | ||
| return unsigned ? IntN.UZERO : IntN.ZERO; | ||
| if (value < 0) | ||
| return IntN.fromNumber(-value, unsigned).negate(); | ||
| // now always gt 0: | ||
| for (var i=0, bytes=new Array(nBytes); i<nBytes; ++i) | ||
| bytes[i] = (value % 256) & 0xff, // bytes[maxIndex] may overflow the sign bit | ||
| value = Math.floor(value / 256); | ||
| return new IntN(bytes, unsigned); | ||
| }; | ||
| /** | ||
| * Converts this IntN to a number (double, 52 bit mantissa) value. | ||
| * @returns {number} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toNumber = function() { | ||
| if (this.isZero()) | ||
| return 0; | ||
| if (this.isNegative()) | ||
| return this.equals(IntN.MIN_VALUE) ? +int32_min_value : -this.negate().toNumber(); // -MIN_VALUE = MIN_VALUE | ||
| // now always gt 0: | ||
| for (var i=0, result=0, k=Math.min(nBytes, 7); i<k; ++i) // 7 bytes = 56 bits | ||
| result += this.bytes[i] * double_256_pwr[i]; | ||
| return result; | ||
| }; | ||
| // Bitwise operations | ||
| /** | ||
| * Performs a bitwise not (~) operation and returns the result. | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.not = function() { | ||
| for (var i=0, bytes=new Array(nBytes); i<nBytes; ++i) | ||
| bytes[i] = ~this.bytes[i]; // & 0xff not necessary, see test | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| /** | ||
| * Performs a bitwise and (&) operation and returns the resulting Int. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.and = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| for (var i=0, bytes=new Array(nBytes); i<nBytes; ++i) | ||
| bytes[i] = this.bytes[i] & other.bytes[i]; | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| /** | ||
| * Performs a bitwise or (|) operation and returns the resulting Int. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.or = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| for (var i=0, bytes=new Array(nBytes); i<nBytes; ++i) | ||
| bytes[i] = this.bytes[i] | other.bytes[i]; | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| /** | ||
| * Performs a bitwise xor (^) operation and returns the result. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.xor = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| for (var i=0, bytes=new Array(nBytes); i<nBytes; ++i) | ||
| bytes[i] = this.bytes[i] ^ other.bytes[i]; | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| /** | ||
| * Performs a shift left (<<) operation and returns the result. | ||
| * @param {!IntN|number} numBits Number of bits | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.shiftLeft = function(numBits) { | ||
| if (IntN.isIntN(numBits)) | ||
| numBits = numBits.toInt(); | ||
| numBits &= nBits-1; // << 0 ^= << n | ||
| if (numBits === 0) | ||
| return this; | ||
| var numBytes = (numBits/8)|0; // Full byte skips | ||
| numBits %= 8; // Byte level bit skips | ||
| for (var i=0, bytes=zeroes.slice(0, nBytes), idx; i<nBytes; ++i) { | ||
| if ((idx = i+numBytes) >= nBytes) | ||
| break; | ||
| bytes[idx] |= (this.bytes[i] << numBits) & 0xff; | ||
| if (++idx < nBytes) | ||
| bytes[idx] |= (this.bytes[i] << numBits >>> 8) & 0xff; | ||
| } | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| /** | ||
| * Performs a shift right (>>, >>>) operation and returns the result. | ||
| * @param {!IntN|number} numBits Number of bits | ||
| * @param {boolean=} logical Whether to perform a logical (>>>) shift right, defaults to `false` for an arithmetic | ||
| * shift right (>>) | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.shiftRight = function(numBits, logical) { | ||
| if (IntN.isIntN(numBits)) | ||
| numBits = numBits.toInt(); | ||
| numBits &= nBits-1; // >> 0 ^= >> n | ||
| if (numBits === 0) | ||
| return this; | ||
| var numBytes = (numBits/8)|0; // Full byte skips | ||
| numBits %= 8; // Byte level bit skips | ||
| var bytes = zeroes.slice(0, nBytes), i; | ||
| if (!logical && (this.bytes[maxIndex] & 0x80) === 0x80) { | ||
| var k; for (i=nBytes-1, k=nBytes-numBytes-1; i>=k; --i) | ||
| bytes[i] = 0xff; | ||
| bytes[++i /* !k */] = (bytes[i] << (7-numBits)) & 0xff; | ||
| } | ||
| var idx; | ||
| for (i=0; i<nBytes; ++i) { | ||
| if ((idx = i-numBytes) >= 0) | ||
| bytes[idx] |= (this.bytes[i] >>> numBits) & 0xff; | ||
| if (--idx >= 0) | ||
| bytes[idx] |= (this.bytes[i] << 8 >>> numBits) & 0xff; | ||
| } | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| /** | ||
| * Performs an unsigned shift right (>>>) operation and returns the result. | ||
| * @param {!IntN|number} numBits Number of bits | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.shiftRightUnsigned = function(numBits) { | ||
| return this.shiftRight(numBits, true); | ||
| }; | ||
| // Arithmetic operations | ||
| /** | ||
| * Adds the specified to this IntN and returns the result. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.add = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| if (other.isZero()) | ||
| return this; | ||
| if (this.isZero()) | ||
| return this.unsigned ? other.toUnsigned() : other.toSigned(); | ||
| var carry = this.and(other), | ||
| result = this.xor(other), | ||
| carryPwr2; | ||
| while (!carry.isZero()) | ||
| carryPwr2 = carry.shiftLeft(1), | ||
| carry = result.and(carryPwr2), | ||
| result = result.xor(carryPwr2); | ||
| return result; | ||
| }; | ||
| /** | ||
| * Negates this IntN (*-1) and returns the result. | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.negate = function() { | ||
| return this.not().add(IntN.ONE); | ||
| }; | ||
| /** | ||
| * Negative signed one. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.NEG_ONE = IntN.ONE.negate(); | ||
| /** | ||
| * Subtracts the specified from this IntN and returns the result. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.subtract = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| return this.add(other.negate()); | ||
| }; | ||
| /** | ||
| * Returns this IntN's absolute value as an unsigned IntN. | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.absolute = function() { | ||
| if (this.unsigned) | ||
| return this; | ||
| return (this.isNegative() ? this.negate() : this).toUnsigned(); | ||
| }; | ||
| /** | ||
| * Multiplies this IntN with the specified and returns the result. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.multiply = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| if (this.isZero()) // other == 0 will break the loop below early while this == 0 will not | ||
| return this; | ||
| var isNegative = this.isNegative() !== other.isNegative(), | ||
| a = this.absolute(), | ||
| b = other.absolute(), | ||
| result = this.unsigned ? IntN.UZERO : IntN.ZERO; | ||
| for(;!b.isZero(); a=a.shiftLeft(1), b=b.shiftRight(1, true)) | ||
| if ((b.bytes[0] & 1) === 1) | ||
| result = result.add(a); | ||
| return isNegative ? result.negate() : result; | ||
| }; | ||
| /** | ||
| * Divides the specified dividend by the specified divisor. This method is used internally by {@link IntN#divide} | ||
| * and {@link IntN#modulo} and is exposed statically in case both the result and the remainder are required. | ||
| * @param {!IntN} dividend | ||
| * @param {!IntN} divisor | ||
| * @returns {!{quotient: !IntN, remainder: !IntN}} | ||
| * @expose | ||
| */ | ||
| IntN.divide = function(dividend, divisor) { | ||
| if (divisor.isZero()) | ||
| throw Error("division by zero"); | ||
| if (dividend.isZero()) | ||
| return { | ||
| "quotient": dividend.unsigned ? IntN.UZERO : IntN.ZERO, | ||
| "remainder": dividend | ||
| }; | ||
| var isNegative = dividend.isNegative() !== divisor.isNegative(), | ||
| quotient = dividend.unsigned ? IntN.UZERO : IntN.ZERO, | ||
| remainder = dividend.absolute(), | ||
| product = divisor.absolute(), | ||
| term = IntN.UONE, | ||
| maxTerm = IntN.MIN_VALUE.toUnsigned(); | ||
| while (term.lessThan(maxTerm) && product.lessThan(remainder)) | ||
| product = product.shiftLeft(1), | ||
| term = term.shiftLeft(1); | ||
| while (term.greaterThanEqual(IntN.UONE)) { | ||
| if (product.lessThanEqual(remainder)) | ||
| quotient = quotient.add(term), | ||
| remainder = remainder.subtract(product); | ||
| product = product.shiftRight(1, true); | ||
| term = term.shiftRight(1, true); | ||
| } | ||
| return { | ||
| "quotient": isNegative ? quotient.negate() : quotient, | ||
| "remainder": remainder | ||
| }; | ||
| }; | ||
| /** | ||
| * Divides this IntN by the specified and returns the result. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.divide = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| return IntN.divide(this, other)['quotient']; | ||
| }; | ||
| /** | ||
| * Returns the remainder of the division of this IntN by the specified. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.modulo = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| return IntN.divide(this, other)['remainder']; | ||
| }; | ||
| /** | ||
| * Converts this IntN to its full binary representation. This returns N (number of bits) binary digits for | ||
| * testing and debugging, followed by the character `U` if unsigned. | ||
| * @param {boolean=} spaces Whether to insert spaces between bytes, defaults to `false` | ||
| * @returns {string} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toDebug = function(spaces) { | ||
| for (var i=maxIndex, byt, out=""; i>=0; --i) { | ||
| byt = this.bytes[i].toString(2); | ||
| while (byt.length < 8) | ||
| byt = '0'+byt; | ||
| out += byt; | ||
| if (spaces && i > 0) | ||
| out += ' '; | ||
| } | ||
| if (this.unsigned) | ||
| out += spaces ? " U" : 'U'; | ||
| return out; | ||
| }; | ||
| // String conversion | ||
| /** | ||
| * IntN representing 2. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var IntN_2 = IntN.fromInt(2); | ||
| /** | ||
| * IntN representing 36. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var IntN_36 = IntN.fromInt(36); | ||
| /** | ||
| * Converts a string using the specified radix to an IntN. | ||
| * @param {string} value String | ||
| * @param {(boolean|number)=} unsigned Whether unsigned or not, defaults to `false` for signed (omittable) | ||
| * @param {number=} radix Radix (2-36), defaults to 10 | ||
| * @returns {!IntN} | ||
| * @throws {RangeError} If `radix` is out of range | ||
| * @throws {Error} If `value` contains illegal characters | ||
| * @expose | ||
| */ | ||
| IntN.fromString = function(value, unsigned, radix) { | ||
| if (typeof unsigned === 'number') | ||
| radix = unsigned, | ||
| unsigned = false; | ||
| value = (value+"").toLowerCase(); | ||
| radix = radix || 10; | ||
| if (radix < 2 || radix > 36) | ||
| throw RangeError("radix out of range: "+radix+" (2-36)"); | ||
| if (value.charAt(0) === '-') | ||
| return IntN.fromString(value.substring(1), unsigned, radix).negate(); | ||
| if (value.charAt(0) === '+') | ||
| value = value.substring(1); | ||
| // now always gte 0: | ||
| if (value === '0' || value === 'NaN' || value === 'Infinity') | ||
| return unsigned ? IntN.UZERO : IntN.ZERO; | ||
| // now always gt 0: | ||
| var result = unsigned ? IntN.UZERO : IntN.ZERO, | ||
| radixToPower = (radix === 2) | ||
| ? function(i) { return 1 << i; } | ||
| : Math.pow.bind(Math, radix); | ||
| for (var i=0, k=value.length, ch, val; i<k; ++i) { | ||
| ch = value.charAt(k-i-1); | ||
| val = chars.indexOf(ch); | ||
| if (val < 0 || val > radix) | ||
| throw Error("illegal interior character: "+ch); | ||
| result = result.add(IntN.fromInt(val).multiply(IntN.fromInt(radixToPower(i)))); | ||
| } | ||
| return result; | ||
| }; | ||
| /** | ||
| * Converts this IntN to a string of the specified radix. | ||
| * @param {!IntN|number|string} radix Radix (2-36), defaults to 10 | ||
| * @returns {string} | ||
| * @throws {RangeError} If `radix` is out of range | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toString = function(radix) { | ||
| radix = radix || 10; | ||
| if (!IntN.isIntN(radix)) | ||
| radix = IntN.valueOf(radix); | ||
| if (radix.lessThan(IntN_2) || radix.greaterThan(IntN_36)) | ||
| throw RangeError("radix out of range: "+radix.toInt()+" (2-36)"); | ||
| var zero = this.unsigned ? IntN.UZERO : IntN.ZERO; | ||
| if (this.equals(zero)) | ||
| return '0'; | ||
| if (this.isNegative()) { | ||
| if (this.equals(IntN.MIN_VALUE)) { // -MIN_VALUE = MIN_VALUE | ||
| var div = IntN.divide(this, radix)['quotient'], | ||
| rem = div.multiply(radix).subtract(this); | ||
| return div.toString(radix) + rem.toInt().toString(radix.toInt()); | ||
| } | ||
| return '-'+this.negate().toString(radix); | ||
| } | ||
| // now always gt 0: | ||
| var result = this, | ||
| digits = [], | ||
| mod; | ||
| do | ||
| mod = result.modulo(radix), | ||
| digits.unshift(chars.charAt(mod.toInt())), | ||
| result = IntN.divide(result, radix)['quotient']; | ||
| while (!result.equals(zero)); | ||
| return digits.join(''); | ||
| }; | ||
| // Setup aliases | ||
| IntN['isInt'+nBits] = IntN.isIntN; | ||
| for (var key in aliases.statics) | ||
| if (aliases.statics.hasOwnProperty(key)) | ||
| for (i=0; i<aliases.statics[key].length; ++i) | ||
| IntN[aliases.statics[key][i]] = IntN[key]; | ||
| for (key in aliases.prototype) | ||
| if (aliases.prototype.hasOwnProperty(key)) | ||
| for (i=0; i<aliases.prototype[key].length; ++i) | ||
| IntN.prototype[aliases.prototype[key][i]] = IntN.prototype[key]; | ||
| return classes[nBits] = IntN; | ||
| } // makeIntN | ||
| /** | ||
| * Classes cache. | ||
| * @type {!Object.<number,!Function>} | ||
| * @inner | ||
| */ | ||
| var classes = {}; | ||
| /** | ||
| * Minimum 32bit signed integer value. | ||
| * @type {number} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var int32_min_value = 0x80000000|0; | ||
| /** | ||
| * Relevant powers (0-7) of 256 for number conversion. | ||
| * @type {!Array.<number>} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var double_256_pwr = [ | ||
| 1, | ||
| 256, | ||
| 65536, | ||
| 16777216, | ||
| 4294967296, | ||
| 1099511627776, | ||
| 281474976710656 | ||
| // >= ^7 is inexact | ||
| ]; | ||
| /** | ||
| * Valid characters for string conversion. | ||
| * @type {string} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var chars = "0123456789abcdefghijklmnopqrstuvwxyz"; | ||
| /** | ||
| * Alias names of static and prototype methods. | ||
| * @type {!{statics: !Object.<string,!Array.<string>>, prototype: !Object.<string,!Array.<string>>}} | ||
| * @inner | ||
| */ | ||
| var aliases = { | ||
| statics: { | ||
| // General utility | ||
| // 'isIntN': ['isInt'+nBits] // not known yet | ||
| }, | ||
| prototype: { | ||
| // Arithmetic evaluation | ||
| 'compare': ['comp'], | ||
| 'equals': ['eq', 'equal', '=='], | ||
| 'notEquals': ['ne', 'notEqual', '!='], | ||
| 'lessThan': ['lt', 'less', 'lesser', '<'], | ||
| 'lessThanEqual': ['lte', 'lessThanOrEqual', '<='], | ||
| 'greaterThan': ['gt', 'greater', '>'], | ||
| 'greaterThanEqual': ['gte', 'greaterThanOrEqual', '>='], | ||
| // Bitwise operations | ||
| 'not': ['~'], | ||
| 'and': ['&'], | ||
| 'or': ['|'], | ||
| 'xor': ['^'], | ||
| 'shiftLeft': ['lsh', 'leftShift', '<<'], | ||
| 'shiftRight': ['rsh', 'rightShift', '>>'], | ||
| 'shiftRightUnsigned': ['rshu', 'rightShiftUnsigned', '>>>'], | ||
| // Arithmetic operations | ||
| 'add': ['plus', '+'], | ||
| 'negate': ['neg', '!'], | ||
| 'subtract': ['sub', 'minus', '-'], | ||
| 'absolute': ['abs', '||'], | ||
| 'multiply': ['mult', '*'], | ||
| 'divide': ['div', '/'], | ||
| 'modulo': ['mod', '%'] | ||
| } | ||
| }; | ||
| return makeIntN; | ||
| })(); |
+882
-862
@@ -24,859 +24,893 @@ /* | ||
| /** | ||
| * Creates a class for representing `nBits` bit integers. | ||
| * @param {number} nBits Number of bits (must be a positive multiple of 8) | ||
| * @returns {!Function} | ||
| * @inner | ||
| */ | ||
| function makeIntN(nBits) { | ||
| if (nBits <= 0 || (nBits%8) !== 0) | ||
| throw Error("illegal number of bits: "+nBits+" (not a positive multiple of 8)"); | ||
| // Make sure to return singleton classes | ||
| if (classes[nBits]) | ||
| return classes[nBits]; | ||
| var IntN = (function() { | ||
| "use strict"; | ||
| /** | ||
| * Number of bits represented by this IntN class. | ||
| * @type {number} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.BITS = nBits|0; | ||
| /** | ||
| * Number of bytes. | ||
| * @type {number} | ||
| * Creates a class for representing `nBits` bit integers. | ||
| * @param {number} nBits Number of bits (must be a positive multiple of 8) | ||
| * @returns {!Function} | ||
| * @inner | ||
| */ | ||
| var nBytes = (nBits/8)|0; | ||
| function makeIntN(nBits) { | ||
| if (nBits <= 0 || (nBits%8) !== 0) | ||
| throw Error("illegal number of bits: "+nBits+" (not a positive multiple of 8)"); | ||
| /** | ||
| * Number of bytes represented by this IntN class. | ||
| * @type {number} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.BYTES = nBytes; | ||
| // Make sure to return singleton classes | ||
| if (classes[nBits]) | ||
| return classes[nBits]; | ||
| /** | ||
| * Maximum byte index. | ||
| * @type {number} | ||
| * @inner | ||
| */ | ||
| var maxIndex = nBytes-1; | ||
| /** | ||
| * Number of bytes. | ||
| * @type {number} | ||
| * @inner | ||
| */ | ||
| var nBytes = (nBits/8)|0; | ||
| /** | ||
| * Array of binary zeroes. | ||
| * @type {!Array.<number>} | ||
| * @inner | ||
| */ | ||
| var zeroes = new Array(nBytes); | ||
| (function() { | ||
| /** | ||
| * Maximum byte index. | ||
| * @type {number} | ||
| * @inner | ||
| */ | ||
| var maxIndex = nBytes-1; | ||
| /** | ||
| * Array of binary zeroes. | ||
| * @type {!Array.<number>} | ||
| * @inner | ||
| */ | ||
| var zeroes = new Array(nBytes); | ||
| for (var i=0; i<nBytes; ++i) | ||
| zeroes[i] = 0; | ||
| })(); | ||
| /** | ||
| * Array of binary ones. | ||
| * @type {!Array.<number>} | ||
| * @inner | ||
| */ | ||
| var ones = new Array(nBytes); | ||
| (function() { | ||
| for (var i=0; i<nBytes; ++i) | ||
| /** | ||
| * Array of binary ones. | ||
| * @type {!Array.<number>} | ||
| * @inner | ||
| */ | ||
| var ones = new Array(nBytes); | ||
| for (i=0; i<nBytes; ++i) | ||
| ones[i] = 0xff; | ||
| })(); | ||
| /** | ||
| * Constructs a new IntN, where N is the number of bits represented by this class. | ||
| * @class A class for representing arbitrary size integers, both signed and unsigned. | ||
| * @exports IntN | ||
| * @param {!Array.<number>} bytes Byte values, least significant first | ||
| * @param {boolean=} unsigned Whether unsigned or signed, defaults to `false` for signed | ||
| * @constructor | ||
| */ | ||
| function IntN(bytes, unsigned) { | ||
| /** | ||
| * Constructs a new IntN, where N is the number of bits represented by this class. | ||
| * @class A class for representing arbitrary size integers, both signed and unsigned. | ||
| * @exports IntN | ||
| * @param {!Array.<number>|number} bytes Byte values, least significant first | ||
| * @param {boolean=} unsigned Whether unsigned or signed, defaults to `false` for signed | ||
| * @constructor | ||
| */ | ||
| function IntN(bytes, unsigned) { | ||
| /** | ||
| * Represented byte values, least significant first. | ||
| * @type {!Array.<number>} | ||
| * @expose | ||
| */ | ||
| this.bytes = new Array(nBytes); | ||
| for (var i=0, k=bytes.length; i<k; ++i) | ||
| this.bytes[i] = bytes[i] & 0xff; | ||
| for (; i<nBytes; ++i) | ||
| this.bytes[i] = 0; | ||
| /** | ||
| * Whether unsigned or otherwise signed. | ||
| * @type {boolean} | ||
| * @expose | ||
| */ | ||
| this.unsigned = !!unsigned; | ||
| // ++IntN.NEW_COUNT; | ||
| } | ||
| /** | ||
| * Represented byte values, least significant first. | ||
| * @type {!Array.<number>} | ||
| * Number of bits represented by this IntN class. | ||
| * @type {number} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| this.bytes = new Array(nBytes); | ||
| IntN.BITS = nBits|0; | ||
| for (var i=0, k=bytes.length; i<k; ++i) | ||
| this.bytes[i] = bytes[i] & 0xff; | ||
| for (; i<nBytes; ++i) | ||
| this.bytes[i] = 0; | ||
| /** | ||
| * Number of bytes represented by this IntN class. | ||
| * @type {number} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.BYTES = nBytes; | ||
| /** | ||
| * Whether unsigned or otherwise signed. | ||
| * @type {boolean} | ||
| * Number of so far created instances for performance analysis. | ||
| * @type {number} | ||
| * @private | ||
| * @expose | ||
| */ | ||
| this.unsigned = !!unsigned; | ||
| // ++IntN.NEW_COUNT; | ||
| } | ||
| // IntN.NEW_COUNT = 0; | ||
| /** | ||
| * Number of so far created instances for performance analysis. | ||
| * @type {number} | ||
| * @private | ||
| * @expose | ||
| */ | ||
| // IntN.NEW_COUNT = 0; | ||
| // General utility | ||
| // General utility | ||
| /** | ||
| * Tests if an object is an N bit integer, where N is this class's number of bits. | ||
| * @param {*} obj Object to test | ||
| * @returns {boolean} `true` if it is an N bit integer, otherwise `false` | ||
| * @expose | ||
| */ | ||
| IntN.isIntN = function(obj) { | ||
| return (obj && Array.isArray(obj.bytes) && obj.bytes.length === nBytes && typeof obj.unsigned === 'boolean') | ||
| === true; | ||
| }; | ||
| /** | ||
| * Tests if an object is an N bit integer, where N is this class's number of bits. | ||
| * @param {*} obj Object to test | ||
| * @returns {boolean} `true` if it is an N bit integer, otherwise `false` | ||
| * @expose | ||
| */ | ||
| IntN.isIntN = function(obj) { | ||
| return (obj && Array.isArray(obj.bytes) && obj.bytes.length === nBytes && typeof obj.unsigned === 'boolean') | ||
| === true; | ||
| }; | ||
| /** | ||
| * Converts the specified value to an IntN. | ||
| * @param {number|string|!{bytes: !Array.<number>, unsigned: boolean}} val Value | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.valueOf = function(val) { | ||
| if (typeof val === 'number') | ||
| return IntN.fromNumber(val); | ||
| else if (typeof val === 'string') | ||
| return IntN.fromString(val); | ||
| else if (val && val instanceof IntN && val.bytes.length == nBytes) | ||
| return val; | ||
| // Throws for not an object (undefined, null) bytes not an array (in constructor), | ||
| // fills smaller, truncates larger N (does not respect sign if differing): | ||
| return new IntN(val.bytes, val.unsigned); | ||
| }; | ||
| /** | ||
| * Converts the specified value to an IntN. | ||
| * @param {number|string|!{bytes: !Array.<number>, unsigned: boolean}} val Value | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.valueOf = function(val) { | ||
| if (typeof val === 'number') | ||
| return IntN.fromNumber(val); | ||
| else if (typeof val === 'string') | ||
| return IntN.fromString(val); | ||
| else if (val && val instanceof IntN && val.bytes.length == nBytes) | ||
| return val; | ||
| // Throws for not an object (undefined, null) bytes not an array (in constructor), | ||
| // fills smaller, truncates larger N (does not respect sign if differing): | ||
| return new IntN(val.bytes, val.unsigned); | ||
| }; | ||
| /** | ||
| * Casts this IntN of size N to the specified target IntN of size M. | ||
| * @param {!Function} TargetIntN Target IntN class | ||
| * @param {boolean=} unsigned Whether unsigned or not, defaults to this' {@link IntN#unsigned} | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.cast = function(TargetIntN, unsigned) { | ||
| unsigned = typeof unsigned === 'boolean' ? unsigned : this.unsigned; | ||
| var retainMsb = this.isNegative(), | ||
| val = retainMsb ? this.not() : this; | ||
| val = new TargetIntN(val.bytes, unsigned); | ||
| return retainMsb ? val.not() : val; | ||
| }; | ||
| /** | ||
| * Casts this IntN of size N to the specified target IntN of size M. | ||
| * @param {!Function} TargetIntN Target IntN class | ||
| * @param {boolean=} unsigned Whether unsigned or not, defaults to this' {@link IntN#unsigned} | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.cast = function(TargetIntN, unsigned) { | ||
| unsigned = typeof unsigned === 'boolean' ? unsigned : this.unsigned; | ||
| var retainMsb = this.isNegative(), | ||
| val = retainMsb ? this.not() : this; | ||
| val = new TargetIntN(val.bytes, unsigned); | ||
| return retainMsb ? val.not() : val; | ||
| }; | ||
| // Basic constants | ||
| // Basic constants | ||
| /** | ||
| * Signed zero. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.ZERO = new IntN([], false); | ||
| /** | ||
| * Signed zero. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.ZERO = new IntN([], false); | ||
| /** | ||
| * Unsigned zero. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.UZERO = new IntN([], true); | ||
| /** | ||
| * Unsigned zero. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.UZERO = new IntN([], true); | ||
| /** | ||
| * Signed one. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.ONE = new IntN([1], false); | ||
| /** | ||
| * Signed one. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.ONE = new IntN([1], false); | ||
| /** | ||
| * Unsigned one. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.UONE = new IntN([1], true); | ||
| /** | ||
| * Unsigned one. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.UONE = new IntN([1], true); | ||
| /** | ||
| * Minimum signed value. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.MIN_VALUE = new IntN(zeroes.slice(0, nBytes)); | ||
| IntN.MIN_VALUE.bytes[maxIndex] |= 0x80; | ||
| /** | ||
| * Minimum signed value. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.MIN_VALUE = new IntN(zeroes.slice(0, nBytes)); | ||
| IntN.MIN_VALUE.bytes[maxIndex] |= 0x80; | ||
| /** | ||
| * Maximum signed value. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.MAX_VALUE = new IntN(ones.slice(0, nBytes)); | ||
| IntN.MAX_VALUE.bytes[maxIndex] &= 0x7f; | ||
| /** | ||
| * Maximum signed value. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.MAX_VALUE = new IntN(ones.slice(0, nBytes)); | ||
| IntN.MAX_VALUE.bytes[maxIndex] &= 0x7f; | ||
| /** | ||
| * Maximum unsigned value. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.MAX_UNSIGNED_VALUE = new IntN(ones.slice(0, nBytes), true); | ||
| /** | ||
| * Maximum unsigned value. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.MAX_UNSIGNED_VALUE = new IntN(ones.slice(0, nBytes), true); | ||
| // Signed evaluation | ||
| // Signed evaluation | ||
| /** | ||
| * Tests if this IntN is signed. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isSigned = function() { | ||
| return !this.unsigned; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is signed. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isSigned = function() { | ||
| return !this.unsigned; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is unsigned. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isUnsigned = function() { | ||
| return this.unsigned; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is unsigned. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isUnsigned = function() { | ||
| return this.unsigned; | ||
| }; | ||
| // Signed conversion | ||
| // Signed conversion | ||
| /** | ||
| * Converts this IntN to signed and returns the result. | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toSigned = function() { | ||
| if (!this.unsigned) | ||
| return this; | ||
| return new IntN(this.bytes, false); | ||
| }; | ||
| /** | ||
| * Converts this IntN to signed and returns the result. | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toSigned = function() { | ||
| if (!this.unsigned) | ||
| return this; | ||
| return new IntN(this.bytes, false); | ||
| }; | ||
| /** | ||
| * Converts this IntN to unsigned and returns the result. | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toUnsigned = function() { | ||
| if (this.unsigned) | ||
| return this; | ||
| return new IntN(this.bytes, true); | ||
| }; | ||
| /** | ||
| * Converts this IntN to unsigned and returns the result. | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toUnsigned = function() { | ||
| if (this.unsigned) | ||
| return this; | ||
| return new IntN(this.bytes, true); | ||
| }; | ||
| // Arithmetic evalutation | ||
| // Arithmetic evalutation | ||
| /** | ||
| * Tests if this IntN is (signed and) negative. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isNegative = function() { | ||
| return !this.unsigned && (this.bytes[maxIndex] & 0x80) === 0x80; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is (signed and) negative. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isNegative = function() { | ||
| return !this.unsigned && (this.bytes[maxIndex] & 0x80) === 0x80; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is (unsigned or) positive. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isPositive = function() { | ||
| return this.unsigned || (this.bytes[maxIndex] & 0x80) === 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is (unsigned or) positive. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isPositive = function() { | ||
| return this.unsigned || (this.bytes[maxIndex] & 0x80) === 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is even. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isEven = function() { | ||
| return (this.bytes[0] & 1) === 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is even. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isEven = function() { | ||
| return (this.bytes[0] & 1) === 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is odd. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isOdd = function() { | ||
| return (this.bytes[0] & 1) === 1; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is odd. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isOdd = function() { | ||
| return (this.bytes[0] & 1) === 1; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is zero. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isZero = function() { | ||
| for (var i=0; i<nBytes; ++i) | ||
| if (this.bytes[i] !== 0) | ||
| return false; | ||
| return true; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is zero. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isZero = function() { | ||
| for (var i=0; i<nBytes; ++i) | ||
| if (this.bytes[i] !== 0) | ||
| return false; | ||
| return true; | ||
| }; | ||
| /** | ||
| * Compares this IntN with the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {number} `0` if both are the same, `1` if this is greater and `-1` if the specified is greater | ||
| * @expose | ||
| */ | ||
| IntN.prototype.compare = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| if (this.isNegative() && !other.isNegative()) | ||
| return -1; | ||
| if (!this.isNegative() && other.isNegative()) | ||
| return 1; | ||
| for (var i=maxIndex; i>=0; --i) | ||
| if (this.bytes[i] < other.bytes[i]) | ||
| /** | ||
| * Compares this IntN with the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {number} `0` if both are the same, `1` if this is greater and `-1` if the specified is greater | ||
| * @expose | ||
| */ | ||
| IntN.prototype.compare = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| if (this.isNegative() && !other.isNegative()) | ||
| return -1; | ||
| else if (this.bytes[i] > other.bytes[i]) | ||
| if (!this.isNegative() && other.isNegative()) | ||
| return 1; | ||
| return 0; | ||
| }; | ||
| for (var i=maxIndex; i>=0; --i) | ||
| if (this.bytes[i] < other.bytes[i]) | ||
| return -1; | ||
| else if (this.bytes[i] > other.bytes[i]) | ||
| return 1; | ||
| return 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN equals the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.equals = function(other) { | ||
| return this.compare(other) === 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN equals the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.equals = function(other) { | ||
| return this.compare(other) === 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN does not equal the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.notEquals = function(other) { | ||
| return this.compare(other) !== 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN does not equal the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.notEquals = function(other) { | ||
| return this.compare(other) !== 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is less than (<) the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.lessThan = function(other) { | ||
| return this.compare(other) === -1; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is less than (<) the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.lessThan = function(other) { | ||
| return this.compare(other) === -1; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is less than or equal (<=) the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.lessThanEqual = function(other) { | ||
| return this.compare(other) <= 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is less than or equal (<=) the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.lessThanEqual = function(other) { | ||
| return this.compare(other) <= 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is greater than (>) the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.greaterThan = function(other) { | ||
| return this.compare(other) === 1; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is greater than (>) the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.greaterThan = function(other) { | ||
| return this.compare(other) === 1; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is greater than or equal (>=) the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.greaterThanEqual = function(other) { | ||
| return this.compare(other) >= 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is greater than or equal (>=) the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.greaterThanEqual = function(other) { | ||
| return this.compare(other) >= 0; | ||
| }; | ||
| // Integer conversion | ||
| // Integer conversion | ||
| /** | ||
| * Constructs an IntN from a 32bit integer value. | ||
| * @param {number} value Integer value | ||
| * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.fromInt = function(value, unsigned) { | ||
| value = value|0; | ||
| var val; | ||
| if (value < 0) { | ||
| if (value === int32_min_value) // -MIN_VALUE = MIN_VALUE | ||
| return IntN.MIN_VALUE; | ||
| val = IntN.fromInt(-value, unsigned).negate(); | ||
| /** | ||
| * Constructs an IntN from a 32bit integer value. | ||
| * @param {number} value Integer value | ||
| * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.fromInt = function(value, unsigned) { | ||
| value = value|0; | ||
| var val; | ||
| if (value < 0) { | ||
| if (value === int32_min_value) // -MIN_VALUE = MIN_VALUE | ||
| return IntN.MIN_VALUE; | ||
| val = IntN.fromInt(-value, unsigned).negate(); | ||
| return val; | ||
| } | ||
| var bytes = new Array(nBytes); | ||
| for (var i=0; i<nBytes; ++i) | ||
| bytes[i] = (value >>> (i*8)) & 0xff; | ||
| val = new IntN(bytes, unsigned); | ||
| return val; | ||
| } | ||
| var bytes = new Array(nBytes); | ||
| for (var i=0; i<nBytes; ++i) | ||
| bytes[i] = (value >>> (i*8)) & 0xff; | ||
| val = new IntN(bytes, unsigned); | ||
| return val; | ||
| }; | ||
| }; | ||
| /** | ||
| * Converts this IntN to a 32bit integer value. | ||
| * @param {boolean=} unsigned Whether unsigned or not, defaults to this' {@link IntN#unsigned} | ||
| * @returns {number} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toInt = function(unsigned) { | ||
| unsigned = typeof unsigned === 'boolean' ? unsigned : this.unsigned; | ||
| var retainMsb = this.isNegative(), | ||
| val = retainMsb ? this.not() : this; | ||
| for (var i=0, result=0; i<Math.min(4, val.bytes.length); ++i) | ||
| result |= val.bytes[i] << (i*8); | ||
| if (retainMsb) | ||
| result = ~result; | ||
| return unsigned ? result >>> 0 : result; | ||
| }; | ||
| /** | ||
| * Converts this IntN to a 32bit integer. | ||
| * @param {boolean=} unsigned Whether unsigned or not, defaults to this' {@link IntN#unsigned} | ||
| * @returns {number} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toInt = function(unsigned) { | ||
| unsigned = typeof unsigned === 'boolean' ? unsigned : this.unsigned; | ||
| var retainMsb = this.isNegative(), | ||
| val = retainMsb ? this.not() : this; | ||
| for (var i=0, result=0; i<Math.min(4, val.bytes.length); ++i) | ||
| result |= val.bytes[i] << (i*8); | ||
| if (retainMsb) | ||
| result = ~result; | ||
| return unsigned ? result >>> 0 : result; | ||
| }; | ||
| // Number conversion | ||
| /** | ||
| * Reassembles an IntN from an array of 32bit integers, least significant first. | ||
| * @param {!Array.<number>} ints Array of 32bit integers | ||
| * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.fromInts = function(ints, unsigned) { | ||
| var result = IntN.ZERO; | ||
| for (var i=0, k=Math.min(ints.length, Math.ceil(nBytes/4)), val; i<k; ++i) | ||
| val = ints[i], | ||
| result = result.or(new IntN([ | ||
| val & 0xff, | ||
| (val >>> 8) & 0xff, | ||
| (val >>> 16) & 0xff, | ||
| (val >>> 24) & 0xff | ||
| ]).shiftLeft(i*32)); | ||
| return unsigned ? result.toUnsigned() : result; | ||
| }; | ||
| /** | ||
| * Constructs an IntN from a number (double, 52 bit mantissa) value. | ||
| * @param {number} value Number value | ||
| * @param {boolean=} unsigned Whether unsigned or not, defaults `false` for signed | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.fromNumber = function(value, unsigned) { | ||
| if (typeof value !== 'number') | ||
| throw TypeError("illegal arguments: "+typeof(value)); | ||
| if (value !== value || !isFinite(value) || value === 0) | ||
| return unsigned ? IntN.UZERO : IntN.ZERO; | ||
| if (value < 0) | ||
| return IntN.fromNumber(-value, unsigned).negate(); | ||
| // now always gt 0: | ||
| for (var i=0, bytes=new Array(nBytes); i<nBytes; ++i) | ||
| bytes[i] = (value % 256) & 0xff, // bytes[maxIndex] may overflow the sign bit | ||
| value = Math.floor(value / 256); | ||
| return new IntN(bytes, unsigned); | ||
| }; | ||
| /** | ||
| * Disassembles this IntN into an array of 32bit integers, least significant first. | ||
| * @returns {!Array.<number>} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toInts = function() { | ||
| var numChunks = Math.ceil(nBytes/4), | ||
| arr = new Array(numChunks); | ||
| for (var i=0, offset=0, val; i<numChunks; offset=++i*4) { | ||
| val = 0; | ||
| for (var j=0, l=Math.min(4, nBytes-offset); j<l; ++j) | ||
| val |= this.bytes[offset+j] << (j*8); | ||
| arr[i] = val; | ||
| } | ||
| return arr; | ||
| }; | ||
| /** | ||
| * Converts this IntN to a number (double, 52 bit mantissa) value. | ||
| * @returns {number} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toNumber = function() { | ||
| if (this.isZero()) | ||
| return 0; | ||
| if (this.isNegative()) | ||
| return this.equals(IntN.MIN_VALUE) ? +int32_min_value : -this.negate().toNumber(); // -MIN_VALUE = MIN_VALUE | ||
| // now always gt 0: | ||
| for (var i=0, result=0, k=Math.min(nBytes, 7); i<k; ++i) // 7 bytes = 56 bits | ||
| result += this.bytes[i] * double_256_pwr[i]; | ||
| return result; | ||
| }; | ||
| // Number conversion | ||
| // Bitwise operations | ||
| /** | ||
| * Constructs an IntN from a number (double, 52 bit mantissa) value. | ||
| * @param {number} value Number value | ||
| * @param {boolean=} unsigned Whether unsigned or not, defaults `false` for signed | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.fromNumber = function(value, unsigned) { | ||
| if (typeof value !== 'number') | ||
| throw TypeError("illegal arguments: "+typeof(value)); | ||
| if (value !== value || !isFinite(value) || value === 0) | ||
| return unsigned ? IntN.UZERO : IntN.ZERO; | ||
| if (value < 0) | ||
| return IntN.fromNumber(-value, unsigned).negate(); | ||
| // now always gt 0: | ||
| for (var i=0, bytes=new Array(nBytes); i<nBytes; ++i) | ||
| bytes[i] = (value % 256) & 0xff, // bytes[maxIndex] may overflow the sign bit | ||
| value = Math.floor(value / 256); | ||
| return new IntN(bytes, unsigned); | ||
| }; | ||
| /** | ||
| * Performs a bitwise not (~) operation and returns the result. | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.not = function() { | ||
| for (var i=0, bytes=new Array(nBytes); i<nBytes; ++i) | ||
| bytes[i] = ~this.bytes[i]; // & 0xff not necessary, see test | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| /** | ||
| * Converts this IntN to a number (double, 52 bit mantissa) value. | ||
| * @returns {number} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toNumber = function() { | ||
| if (this.isZero()) | ||
| return 0; | ||
| if (this.isNegative()) | ||
| return this.equals(IntN.MIN_VALUE) ? +int32_min_value : -this.negate().toNumber(); // -MIN_VALUE = MIN_VALUE | ||
| // now always gt 0: | ||
| for (var i=0, result=0, k=Math.min(nBytes, 7); i<k; ++i) // 7 bytes = 56 bits | ||
| result += this.bytes[i] * double_256_pwr[i]; | ||
| return result; | ||
| }; | ||
| /** | ||
| * Performs a bitwise and (&) operation and returns the resulting Int. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.and = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| for (var i=0, bytes=new Array(nBytes); i<nBytes; ++i) | ||
| bytes[i] = this.bytes[i] & other.bytes[i]; | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| // Bitwise operations | ||
| /** | ||
| * Performs a bitwise or (|) operation and returns the resulting Int. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.or = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| for (var i=0, bytes=new Array(nBytes); i<nBytes; ++i) | ||
| bytes[i] = this.bytes[i] | other.bytes[i]; | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| /** | ||
| * Performs a bitwise not (~) operation and returns the result. | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.not = function() { | ||
| for (var i=0, bytes=new Array(nBytes); i<nBytes; ++i) | ||
| bytes[i] = ~this.bytes[i]; // & 0xff not necessary, see test | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| /** | ||
| * Performs a bitwise xor (^) operation and returns the result. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.xor = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| for (var i=0, bytes=new Array(nBytes); i<nBytes; ++i) | ||
| bytes[i] = this.bytes[i] ^ other.bytes[i]; | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| /** | ||
| * Performs a bitwise and (&) operation and returns the resulting Int. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.and = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| for (var i=0, bytes=new Array(nBytes); i<nBytes; ++i) | ||
| bytes[i] = this.bytes[i] & other.bytes[i]; | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| /** | ||
| * Performs a shift left (<<) operation and returns the result. | ||
| * @param {!IntN|number} numBits Number of bits | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.shiftLeft = function(numBits) { | ||
| if (IntN.isIntN(numBits)) | ||
| numBits = numBits.toInt(); | ||
| numBits &= nBits-1; // << 0 ^= << n | ||
| if (numBits === 0) | ||
| return this; | ||
| var numBytes = (numBits/8)|0; // Full byte skips | ||
| numBits %= 8; // Byte level bit skips | ||
| for (var i=0, bytes=zeroes.slice(0, nBytes), idx; i<nBytes; ++i) { | ||
| if ((idx = i+numBytes) >= nBytes) | ||
| break; | ||
| bytes[idx] |= (this.bytes[i] << numBits) & 0xff; | ||
| if (++idx < nBytes) | ||
| bytes[idx] |= (this.bytes[i] << numBits >>> 8) & 0xff; | ||
| } | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| /** | ||
| * Performs a bitwise or (|) operation and returns the resulting Int. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.or = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| for (var i=0, bytes=new Array(nBytes); i<nBytes; ++i) | ||
| bytes[i] = this.bytes[i] | other.bytes[i]; | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| /** | ||
| * Performs a shift right (>>, >>>) operation and returns the result. | ||
| * @param {!IntN|number} numBits Number of bits | ||
| * @param {boolean=} logical Whether to perform a logical (>>>) shift right, defaults to `false` for an arithmetic | ||
| * shift right (>>) | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.shiftRight = function(numBits, logical) { | ||
| if (IntN.isIntN(numBits)) | ||
| numBits = numBits.toInt(); | ||
| numBits &= nBits-1; // >> 0 ^= >> n | ||
| if (numBits === 0) | ||
| return this; | ||
| var numBytes = (numBits/8)|0; // Full byte skips | ||
| numBits %= 8; // Byte level bit skips | ||
| var bytes = zeroes.slice(0, nBytes), i; | ||
| if (!logical && (this.bytes[maxIndex] & 0x80) === 0x80) { | ||
| var k; for (i=nBytes-1, k=nBytes-numBytes-1; i>=k; --i) | ||
| bytes[i] = 0xff; | ||
| bytes[++i /* !k */] = (bytes[i] << (7-numBits)) & 0xff; | ||
| } | ||
| var idx; | ||
| for (i=0; i<nBytes; ++i) { | ||
| if ((idx = i-numBytes) >= 0) | ||
| bytes[idx] |= (this.bytes[i] >>> numBits) & 0xff; | ||
| if (--idx >= 0) | ||
| bytes[idx] |= (this.bytes[i] << 8 >>> numBits) & 0xff; | ||
| } | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| /** | ||
| * Performs a bitwise xor (^) operation and returns the result. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.xor = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| for (var i=0, bytes=new Array(nBytes); i<nBytes; ++i) | ||
| bytes[i] = this.bytes[i] ^ other.bytes[i]; | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| /** | ||
| * Performs an unsigned shift right (>>>) operation and returns the result. | ||
| * @param {!IntN|number} numBits Number of bits | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.shiftRightUnsigned = function(numBits) { | ||
| return this.shiftRight(numBits, true); | ||
| }; | ||
| /** | ||
| * Performs a shift left (<<) operation and returns the result. | ||
| * @param {!IntN|number} numBits Number of bits | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.shiftLeft = function(numBits) { | ||
| if (IntN.isIntN(numBits)) | ||
| numBits = numBits.toInt(); | ||
| numBits &= nBits-1; // << 0 ^= << n | ||
| if (numBits === 0) | ||
| return this; | ||
| var numBytes = (numBits/8)|0; // Full byte skips | ||
| numBits %= 8; // Byte level bit skips | ||
| for (var i=0, bytes=zeroes.slice(0, nBytes), idx; i<nBytes; ++i) { | ||
| if ((idx = i+numBytes) >= nBytes) | ||
| break; | ||
| bytes[idx] |= (this.bytes[i] << numBits) & 0xff; | ||
| if (++idx < nBytes) | ||
| bytes[idx] |= (this.bytes[i] << numBits >>> 8) & 0xff; | ||
| } | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| // Arithmetic operations | ||
| /** | ||
| * Performs a shift right (>>, >>>) operation and returns the result. | ||
| * @param {!IntN|number} numBits Number of bits | ||
| * @param {boolean=} logical Whether to perform a logical (>>>) shift right, defaults to `false` for an arithmetic | ||
| * shift right (>>) | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.shiftRight = function(numBits, logical) { | ||
| if (IntN.isIntN(numBits)) | ||
| numBits = numBits.toInt(); | ||
| numBits &= nBits-1; // >> 0 ^= >> n | ||
| if (numBits === 0) | ||
| return this; | ||
| var numBytes = (numBits/8)|0; // Full byte skips | ||
| numBits %= 8; // Byte level bit skips | ||
| var bytes = zeroes.slice(0, nBytes), i; | ||
| if (!logical && (this.bytes[maxIndex] & 0x80) === 0x80) { | ||
| var k; for (i=nBytes-1, k=nBytes-numBytes-1; i>=k; --i) | ||
| bytes[i] = 0xff; | ||
| bytes[++i /* !k */] = (bytes[i] << (7-numBits)) & 0xff; | ||
| } | ||
| var idx; | ||
| for (i=0; i<nBytes; ++i) { | ||
| if ((idx = i-numBytes) >= 0) | ||
| bytes[idx] |= (this.bytes[i] >>> numBits) & 0xff; | ||
| if (--idx >= 0) | ||
| bytes[idx] |= (this.bytes[i] << 8 >>> numBits) & 0xff; | ||
| } | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| /** | ||
| * Adds the specified to this IntN and returns the result. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.add = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| if (other.isZero()) | ||
| return this; | ||
| if (this.isZero()) | ||
| return this.unsigned ? other.toUnsigned() : other.toSigned(); | ||
| var carry = this.and(other), | ||
| result = this.xor(other), | ||
| shifted; | ||
| while (!carry.isZero()) | ||
| shifted = carry.shiftLeft(1), | ||
| carry = result.and(shifted), | ||
| result = result.xor(shifted); | ||
| return result; | ||
| }; | ||
| /** | ||
| * Performs an unsigned shift right (>>>) operation and returns the result. | ||
| * @param {!IntN|number} numBits Number of bits | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.shiftRightUnsigned = function(numBits) { | ||
| return this.shiftRight(numBits, true); | ||
| }; | ||
| /** | ||
| * Negates this IntN (*-1) and returns the result. | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.negate = function() { | ||
| return this.not().add(IntN.ONE); | ||
| }; | ||
| // Arithmetic operations | ||
| /** | ||
| * Negative signed one. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.NEG_ONE = IntN.ONE.negate(); | ||
| /** | ||
| * Adds the specified to this IntN and returns the result. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.add = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| if (other.isZero()) | ||
| return this; | ||
| if (this.isZero()) | ||
| return this.unsigned ? other.toUnsigned() : other.toSigned(); | ||
| var carry = this.and(other), | ||
| result = this.xor(other), | ||
| carryPwr2; | ||
| while (!carry.isZero()) | ||
| carryPwr2 = carry.shiftLeft(1), | ||
| carry = result.and(carryPwr2), | ||
| result = result.xor(carryPwr2); | ||
| return result; | ||
| }; | ||
| /** | ||
| * Subtracts the specified from this IntN and returns the result. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.subtract = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| return this.add(other.negate()); | ||
| }; | ||
| /** | ||
| * Negates this IntN (*-1) and returns the result. | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.negate = function() { | ||
| return this.not().add(IntN.ONE); | ||
| }; | ||
| /** | ||
| * Returns this IntN's absolute value as an unsigned IntN. | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.absolute = function() { | ||
| if (this.unsigned) | ||
| return this; | ||
| return (this.isNegative() ? this.negate() : this).toUnsigned(); | ||
| }; | ||
| /** | ||
| * Negative signed one. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.NEG_ONE = IntN.ONE.negate(); | ||
| /** | ||
| * Multiplies this IntN with the specified and returns the result. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.multiply = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| if (this.isZero()) // other == 0 will break the loop below early while this == 0 will not | ||
| return this; | ||
| var isNegative = this.isNegative() !== other.isNegative(), | ||
| a = this.absolute(), | ||
| b = other.absolute(), | ||
| result = this.unsigned ? IntN.UZERO : IntN.ZERO; | ||
| for(;!b.isZero(); a=a.shiftLeft(1), b=b.shiftRight(1, true)) | ||
| if ((b.bytes[0] & 1) === 1) | ||
| result = result.add(a); | ||
| return isNegative ? result.negate() : result; | ||
| }; | ||
| /** | ||
| * Subtracts the specified from this IntN and returns the result. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.subtract = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| return this.add(other.negate()); | ||
| }; | ||
| /** | ||
| * Divides the specified dividend by the specified divisor. This method is used internally by {@link IntN#divide} | ||
| * and {@link IntN#modulo} and is exposed statically in case both the result and the remainder are required. | ||
| * @param {!IntN} dividend | ||
| * @param {!IntN} divisor | ||
| * @returns {!{quotient: !IntN, remainder: !IntN}} | ||
| * @expose | ||
| */ | ||
| IntN.divide = function(dividend, divisor) { | ||
| if (divisor.isZero()) | ||
| throw Error("division by zero"); | ||
| if (dividend.isZero()) | ||
| /** | ||
| * Returns this IntN's absolute value as an unsigned IntN. | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.absolute = function() { | ||
| if (this.unsigned) | ||
| return this; | ||
| return (this.isNegative() ? this.negate() : this).toUnsigned(); | ||
| }; | ||
| /** | ||
| * Multiplies this IntN with the specified and returns the result. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.multiply = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| if (this.isZero()) // other == 0 will break the loop below early while this == 0 will not | ||
| return this; | ||
| var isNegative = this.isNegative() !== other.isNegative(), | ||
| a = this.absolute(), | ||
| b = other.absolute(), | ||
| result = this.unsigned ? IntN.UZERO : IntN.ZERO; | ||
| for(;!b.isZero(); a=a.shiftLeft(1), b=b.shiftRight(1, true)) | ||
| if ((b.bytes[0] & 1) === 1) | ||
| result = result.add(a); | ||
| return isNegative ? result.negate() : result; | ||
| }; | ||
| /** | ||
| * Divides the specified dividend by the specified divisor. This method is used internally by {@link IntN#divide} | ||
| * and {@link IntN#modulo} and is exposed statically in case both the result and the remainder are required. | ||
| * @param {!IntN} dividend | ||
| * @param {!IntN} divisor | ||
| * @returns {!{quotient: !IntN, remainder: !IntN}} | ||
| * @expose | ||
| */ | ||
| IntN.divide = function(dividend, divisor) { | ||
| if (divisor.isZero()) | ||
| throw Error("division by zero"); | ||
| if (dividend.isZero()) | ||
| return { | ||
| "quotient": dividend.unsigned ? IntN.UZERO : IntN.ZERO, | ||
| "remainder": dividend | ||
| }; | ||
| var isNegative = dividend.isNegative() !== divisor.isNegative(), | ||
| quotient = dividend.unsigned ? IntN.UZERO : IntN.ZERO, | ||
| remainder = dividend.absolute(), | ||
| product = divisor.absolute(), | ||
| term = IntN.UONE, | ||
| maxTerm = IntN.MIN_VALUE.toUnsigned(); | ||
| while (term.lessThan(maxTerm) && product.lessThan(remainder)) | ||
| product = product.shiftLeft(1), | ||
| term = term.shiftLeft(1); | ||
| while (term.greaterThanEqual(IntN.UONE)) { | ||
| if (product.lessThanEqual(remainder)) | ||
| quotient = quotient.add(term), | ||
| remainder = remainder.subtract(product); | ||
| product = product.shiftRight(1, true); | ||
| term = term.shiftRight(1, true); | ||
| } | ||
| return { | ||
| "quotient": dividend.unsigned ? IntN.UZERO : IntN.ZERO, | ||
| "remainder": dividend | ||
| "quotient": isNegative ? quotient.negate() : quotient, | ||
| "remainder": remainder | ||
| }; | ||
| var isNegative = dividend.isNegative() !== divisor.isNegative(), | ||
| quotient = dividend.unsigned ? IntN.UZERO : IntN.ZERO, | ||
| remainder = dividend.absolute(), | ||
| product = divisor.absolute(), | ||
| term = IntN.UONE, | ||
| maxTerm = IntN.MIN_VALUE.toUnsigned(); | ||
| while (term.lessThan(maxTerm) && product.lessThan(remainder)) | ||
| product = product.shiftLeft(1), | ||
| term = term.shiftLeft(1); | ||
| while (term.greaterThanEqual(IntN.UONE)) { | ||
| if (product.lessThanEqual(remainder)) | ||
| quotient = quotient.add(term), | ||
| remainder = remainder.subtract(product); | ||
| product = product.shiftRight(1, true); | ||
| term = term.shiftRight(1, true); | ||
| } | ||
| return { | ||
| "quotient": isNegative ? quotient.negate() : quotient, | ||
| "remainder": remainder | ||
| }; | ||
| }; | ||
| /** | ||
| * Divides this IntN by the specified and returns the result. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.divide = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| return IntN.divide(this, other)['quotient']; | ||
| }; | ||
| /** | ||
| * Divides this IntN by the specified and returns the result. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.divide = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| return IntN.divide(this, other)['quotient']; | ||
| }; | ||
| /** | ||
| * Returns the remainder of the division of this IntN by the specified. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.modulo = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| return IntN.divide(this, other)['remainder']; | ||
| }; | ||
| /** | ||
| * Returns the remainder of the division of this IntN by the specified. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.modulo = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| return IntN.divide(this, other)['remainder']; | ||
| }; | ||
| /** | ||
| * Converts this IntN to its full binary representation. This returns N (number of bits) binary digits for | ||
| * testing and debugging, followed by the character `U` if unsigned. | ||
| * @param {boolean=} spaces Whether to insert spaces between bytes, defaults to `false` | ||
| * @returns {string} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toDebug = function(spaces) { | ||
| for (var i=maxIndex, byt, out=""; i>=0; --i) { | ||
| byt = this.bytes[i].toString(2); | ||
| while (byt.length < 8) | ||
| byt = '0'+byt; | ||
| out += byt; | ||
| if (spaces && i > 0) | ||
| out += ' '; | ||
| } | ||
| if (this.unsigned) | ||
| out += spaces ? " U" : 'U'; | ||
| return out; | ||
| }; | ||
| /** | ||
| * Converts this IntN to its full binary representation. This returns N (number of bits) binary digits for | ||
| * testing and debugging, followed by the character `U` if unsigned. | ||
| * @param {boolean=} spaces Whether to insert spaces between bytes, defaults to `false` | ||
| * @returns {string} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toDebug = function(spaces) { | ||
| for (var i=maxIndex, byt, out=""; i>=0; --i) { | ||
| byt = this.bytes[i].toString(2); | ||
| while (byt.length < 8) | ||
| byt = '0'+byt; | ||
| out += byt; | ||
| if (spaces && i > 0) | ||
| out += ' '; | ||
| } | ||
| if (this.unsigned) | ||
| out += spaces ? " U" : 'U'; | ||
| return out; | ||
| }; | ||
| // String conversion | ||
| // String conversion | ||
| /** | ||
| * IntN representing 2. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var IntN_2 = IntN.fromInt(2); | ||
| /** | ||
| * IntN representing 2. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var IntN_2 = IntN.fromInt(2); | ||
| /** | ||
| * IntN representing 36. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var IntN_36 = IntN.fromInt(36); | ||
| /** | ||
| * IntN representing 36. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var IntN_36 = IntN.fromInt(36); | ||
| /** | ||
| * Converts a string using the specified radix to an IntN. | ||
| * @param {string} value String | ||
| * @param {(boolean|number)=} unsigned Whether unsigned or not, defaults to `false` for signed (omittable) | ||
| * @param {number=} radix Radix (2-36), defaults to 10 | ||
| * @returns {!IntN} | ||
| * @throws {RangeError} If `radix` is out of range | ||
| * @throws {Error} If `value` contains illegal characters | ||
| * @expose | ||
| */ | ||
| IntN.fromString = function(value, unsigned, radix) { | ||
| if (typeof unsigned === 'number') | ||
| radix = unsigned, | ||
| unsigned = false; | ||
| value = (value+"").toLowerCase(); | ||
| radix = radix || 10; | ||
| if (radix < 2 || radix > 36) | ||
| throw RangeError("radix out of range: "+radix+" (2-36)"); | ||
| if (value.charAt(0) === '-') | ||
| return IntN.fromString(value.substring(1), unsigned, radix).negate(); | ||
| if (value.charAt(0) === '+') | ||
| value = value.substring(1); | ||
| // now always gte 0: | ||
| if (value === '0' || value === 'NaN' || value === 'Infinity') | ||
| return unsigned ? IntN.UZERO : IntN.ZERO; | ||
| // now always gt 0: | ||
| var result = unsigned ? IntN.UZERO : IntN.ZERO, | ||
| radixToPower = (radix === 2) | ||
| ? function(i) { return 1 << i; } | ||
| : Math.pow.bind(Math, radix); | ||
| for (var i=0, k=value.length, ch, val; i<k; ++i) { | ||
| ch = value.charAt(k-i-1); | ||
| val = chars.indexOf(ch); | ||
| if (val < 0 || val > radix) | ||
| throw Error("illegal interior character: "+ch); | ||
| result = result.add(IntN.fromInt(val).multiply(IntN.fromInt(radixToPower(i)))); | ||
| } | ||
| return result; | ||
| }; | ||
| /** | ||
| * Converts a string using the specified radix to an IntN. | ||
| * @param {string} value String | ||
| * @param {(boolean|number)=} unsigned Whether unsigned or not, defaults to `false` for signed (omittable) | ||
| * @param {number=} radix Radix (2-36), defaults to 10 | ||
| * @returns {!IntN} | ||
| * @throws {RangeError} If `radix` is out of range | ||
| * @throws {Error} If `value` contains illegal characters | ||
| * @expose | ||
| */ | ||
| IntN.fromString = function(value, unsigned, radix) { | ||
| if (typeof unsigned === 'number') | ||
| radix = unsigned, | ||
| unsigned = false; | ||
| value = (value+"").toLowerCase(); | ||
| radix = radix || 10; | ||
| if (radix < 2 || radix > 36) | ||
| throw RangeError("radix out of range: "+radix+" (2-36)"); | ||
| if (value.charAt(0) === '-') | ||
| return IntN.fromString(value.substring(1), unsigned, radix).negate(); | ||
| if (value.charAt(0) === '+') | ||
| value = value.substring(1); | ||
| // now always gte 0: | ||
| if (value === '0' || value === 'NaN' || value === 'Infinity') | ||
| return unsigned ? IntN.UZERO : IntN.ZERO; | ||
| // now always gt 0: | ||
| var result = unsigned ? IntN.UZERO : IntN.ZERO, | ||
| radixToPower = (radix === 2) | ||
| ? function(i) { return 1 << i; } | ||
| : Math.pow.bind(Math, radix); | ||
| for (var i=0, k=value.length, ch, val; i<k; ++i) { | ||
| ch = value.charAt(k-i-1); | ||
| val = chars.indexOf(ch); | ||
| if (val < 0 || val > radix) | ||
| throw Error("illegal interior character: "+ch); | ||
| result = result.add(IntN.fromInt(val).multiply(IntN.fromInt(radixToPower(i)))); | ||
| } | ||
| return result; | ||
| }; | ||
| /** | ||
| * Converts this IntN to a string of the specified radix. | ||
| * @param {!IntN|number|string} radix Radix (2-36), defaults to 10 | ||
| * @returns {string} | ||
| * @throws {RangeError} If `radix` is out of range | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toString = function(radix) { | ||
| radix = radix || 10; | ||
| if (!IntN.isIntN(radix)) | ||
| radix = IntN.valueOf(radix); | ||
| if (radix.lessThan(IntN_2) || radix.greaterThan(IntN_36)) | ||
| throw RangeError("radix out of range: "+radix.toInt()+" (2-36)"); | ||
| var zero = this.unsigned ? IntN.UZERO : IntN.ZERO; | ||
| if (this.equals(zero)) | ||
| return '0'; | ||
| if (this.isNegative()) { | ||
| if (this.equals(IntN.MIN_VALUE)) { // -MIN_VALUE = MIN_VALUE | ||
| var div = IntN.divide(this, radix)['quotient'], | ||
| rem = div.multiply(radix).subtract(this); | ||
| return div.toString(radix) + rem.toInt().toString(radix.toInt()); | ||
| /** | ||
| * Converts this IntN to a string of the specified radix. | ||
| * @param {!IntN|number|string} radix Radix (2-36), defaults to 10 | ||
| * @returns {string} | ||
| * @throws {RangeError} If `radix` is out of range | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toString = function(radix) { | ||
| radix = radix || 10; | ||
| if (!IntN.isIntN(radix)) | ||
| radix = IntN.valueOf(radix); | ||
| if (radix.lessThan(IntN_2) || radix.greaterThan(IntN_36)) | ||
| throw RangeError("radix out of range: "+radix.toInt()+" (2-36)"); | ||
| var zero = this.unsigned ? IntN.UZERO : IntN.ZERO; | ||
| if (this.equals(zero)) | ||
| return '0'; | ||
| if (this.isNegative()) { | ||
| if (this.equals(IntN.MIN_VALUE)) { // -MIN_VALUE = MIN_VALUE | ||
| var div = IntN.divide(this, radix)['quotient'], | ||
| rem = div.multiply(radix).subtract(this); | ||
| return div.toString(radix) + rem.toInt().toString(radix.toInt()); | ||
| } | ||
| return '-'+this.negate().toString(radix); | ||
| } | ||
| return '-'+this.negate().toString(radix); | ||
| } | ||
| // now always gt 0: | ||
| var result = this, | ||
| digits = [], | ||
| mod; | ||
| do | ||
| mod = result.modulo(radix), | ||
| digits.unshift(chars.charAt(mod.toInt())), | ||
| result = IntN.divide(result, radix)['quotient']; | ||
| while (!result.equals(zero)); | ||
| return digits.join(''); | ||
| }; | ||
| // now always gt 0: | ||
| var result = this, | ||
| digits = [], | ||
| mod; | ||
| do | ||
| mod = result.modulo(radix), | ||
| digits.unshift(chars.charAt(mod.toInt())), | ||
| result = IntN.divide(result, radix)['quotient']; | ||
| while (!result.equals(zero)); | ||
| return digits.join(''); | ||
| }; | ||
| // Setup aliases | ||
| (function() { | ||
| var key, i; | ||
| // Setup aliases | ||
| IntN['isInt'+nBits] = IntN.isIntN; | ||
| for (key in aliases.statics) | ||
| for (var key in aliases.statics) | ||
| if (aliases.statics.hasOwnProperty(key)) | ||
@@ -889,109 +923,95 @@ for (i=0; i<aliases.statics[key].length; ++i) | ||
| IntN.prototype[aliases.prototype[key][i]] = IntN.prototype[key]; | ||
| })(); | ||
| return classes[nBits] = IntN; | ||
| } // makeIntN | ||
| /** | ||
| * Classes cache. | ||
| * @type {!Object.<number,!Function>} | ||
| * @inner | ||
| */ | ||
| var classes = {}; | ||
| return classes[nBits] = IntN; | ||
| /** | ||
| * Minimum 32bit signed integer value. | ||
| * @type {number} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var int32_min_value = 0x80000000|0; | ||
| } // makeIntN | ||
| /** | ||
| * Maximum 32bit signed integer value. | ||
| * @type {number} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var int32_max_value = 0x7fffffff|0; | ||
| /** | ||
| * Classes cache. | ||
| * @type {!Object.<number,!Function>} | ||
| * @inner | ||
| */ | ||
| var classes = {}; | ||
| /** | ||
| * Maximum 32bit unsigned integer value. | ||
| * @type {number} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var int32_max_unsigned_value = 0xffffffff>>>0; | ||
| /** | ||
| * Minimum 32bit signed integer value. | ||
| * @type {number} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var int32_min_value = 0x80000000|0; | ||
| /** | ||
| * Relevant powers (0-7) of 256 for number conversion. | ||
| * @type {!Array.<number>} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var double_256_pwr = [ | ||
| 1, | ||
| 256, | ||
| 65536, | ||
| 16777216, | ||
| 4294967296, | ||
| 1099511627776, | ||
| 281474976710656 | ||
| // >= ^7 is inexact | ||
| ]; | ||
| /** | ||
| * Relevant powers (0-7) of 256 for number conversion. | ||
| * @type {!Array.<number>} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var double_256_pwr = [ | ||
| 1, | ||
| 256, | ||
| 65536, | ||
| 16777216, | ||
| 4294967296, | ||
| 1099511627776, | ||
| 281474976710656 | ||
| // >= ^7 is inexact | ||
| ]; | ||
| /** | ||
| * Valid characters for string conversion. | ||
| * @type {string} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var chars = "0123456789abcdefghijklmnopqrstuvwxyz"; | ||
| /** | ||
| * Valid characters for string conversion. | ||
| * @type {string} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var chars = "0123456789abcdefghijklmnopqrstuvwxyz"; | ||
| /** | ||
| * Alias names of static and prototype methods. | ||
| * @type {!{statics: !Object.<string,!Array.<string>>, prototype: !Object.<string,!Array.<string>>}} | ||
| * @inner | ||
| */ | ||
| var aliases = { | ||
| statics: { | ||
| // General utility | ||
| // 'isIntN': ['isInt'+nBits] // not known yet | ||
| }, | ||
| prototype: { | ||
| // Arithmetic evaluation | ||
| 'compare': ['comp'], | ||
| 'equals': ['eq', 'equal', '=='], | ||
| 'notEquals': ['ne', 'notEqual', '!='], | ||
| 'lessThan': ['lt', 'less', 'lesser', '<'], | ||
| 'lessThanEqual': ['lte', 'lessThanOrEqual', '<='], | ||
| 'greaterThan': ['gt', 'greater', '>'], | ||
| 'greaterThanEqual': ['gte', 'greaterThanOrEqual', '>='], | ||
| // Bitwise operations | ||
| 'not': ['~'], | ||
| 'and': ['&'], | ||
| 'or': ['|'], | ||
| 'xor': ['^'], | ||
| 'shiftLeft': ['lsh', 'leftShift', '<<'], | ||
| 'shiftRight': ['rsh', 'rightShift', '>>'], | ||
| 'shiftRightUnsigned': ['rshu', 'rightShiftUnsigned', '>>>'], | ||
| // Arithmetic operations | ||
| 'add': ['plus', '+'], | ||
| 'negate': ['neg', '!'], | ||
| 'subtract': ['sub', 'minus', '-'], | ||
| 'absolute': ['abs', '||'], | ||
| 'multiply': ['mult', '*'], | ||
| 'divide': ['div', '/'], | ||
| 'modulo': ['mod', '%'] | ||
| } | ||
| }; | ||
| /** | ||
| * Alias names of static and prototype methods. | ||
| * @type {!{statics: !Object.<string,!Array.<string>>, prototype: !Object.<string,!Array.<string>>}} | ||
| * @inner | ||
| */ | ||
| var aliases = { | ||
| statics: { | ||
| // General utility | ||
| // 'isIntN': ['isInt'+nBits] // not known yet | ||
| }, | ||
| prototype: { | ||
| // Arithmetic evaluation | ||
| 'compare': ['comp'], | ||
| 'equals': ['eq', 'equal', '=='], | ||
| 'notEquals': ['ne', 'notEqual', '!='], | ||
| 'lessThan': ['lt', 'less', 'lesser', '<'], | ||
| 'lessThanEqual': ['lte', 'lessThanOrEqual', '<='], | ||
| 'greaterThan': ['gt', 'greater', '>'], | ||
| 'greaterThanEqual': ['gte', 'greaterThanOrEqual', '>='], | ||
| // Bitwise operations | ||
| 'not': ['~'], | ||
| 'and': ['&'], | ||
| 'or': ['|'], | ||
| 'xor': ['^'], | ||
| 'shiftLeft': ['lsh', 'leftShift', '<<'], | ||
| 'shiftRight': ['rsh', 'rightShift', '>>'], | ||
| 'shiftRightUnsigned': ['rshu', 'rightShiftUnsigned', '>>>'], | ||
| // Arithmetic operations | ||
| 'add': ['plus', '+'], | ||
| 'negate': ['neg', '!'], | ||
| 'subtract': ['sub', 'minus', '-'], | ||
| 'absolute': ['abs', '||'], | ||
| 'multiply': ['mult', '*'], | ||
| 'divide': ['div', '/'], | ||
| 'modulo': ['mod', '%'] | ||
| } | ||
| }; | ||
| return makeIntN; | ||
| })(); | ||
| /* CommonJS */ if (typeof module !== 'undefined' && module["exports"]) | ||
| module["exports"] = makeIntN; | ||
| module["exports"] = IntN; | ||
| /* AMD */ else if (typeof define === 'function' && define["amd"]) | ||
| define(function() { return makeIntN; }); | ||
| define(function() { return IntN; }); | ||
| /* Global */ else | ||
| (global["dcodeIO"] = global["dcodeIO"] || {})["IntN"] = makeIntN; | ||
| (global["dcodeIO"] = global["dcodeIO"] || {})["IntN"] = IntN; | ||
| })(this); |
+18
-17
@@ -6,18 +6,19 @@ /* | ||
| */ | ||
| (function(p){function n(k){function b(a,b){this.bytes=Array(f);for(var d=0,e=a.length;d<e;++d)this.bytes[d]=a[d]&255;for(;d<f;++d)this.bytes[d]=0;this.unsigned=!!b}if(0>=k||0!==k%8)throw Error("illegal number of bits: "+k+" (not a positive multiple of 8)");if(r[k])return r[k];b.BITS=k|0;var f=k/8|0;b.BYTES=f;var l=f-1,q=Array(f);(function(){for(var a=0;a<f;++a)q[a]=0})();var n=Array(f);(function(){for(var a=0;a<f;++a)n[a]=255})();b.isIntN=function(a){return!0===(a&&Array.isArray(a.bytes)&&a.bytes.length=== | ||
| f&&"boolean"===typeof a.unsigned)};b.valueOf=function(a){return"number"===typeof a?b.fromNumber(a):"string"===typeof a?b.fromString(a):a&&a instanceof b&&a.bytes.length==f?a:new b(a.bytes,a.unsigned)};b.prototype.cast=function(a,b){b="boolean"===typeof b?b:this.unsigned;var d=this.isNegative(),e=d?this.not():this,e=new a(e.bytes,b);return d?e.not():e};b.ZERO=new b([],!1);b.UZERO=new b([],!0);b.ONE=new b([1],!1);b.UONE=new b([1],!0);b.MIN_VALUE=new b(q.slice(0,f));b.MIN_VALUE.bytes[l]|=128;b.MAX_VALUE= | ||
| new b(n.slice(0,f));b.MAX_VALUE.bytes[l]&=127;b.MAX_UNSIGNED_VALUE=new b(n.slice(0,f),!0);b.prototype.isSigned=function(){return!this.unsigned};b.prototype.isUnsigned=function(){return this.unsigned};b.prototype.toSigned=function(){return this.unsigned?new b(this.bytes,!1):this};b.prototype.toUnsigned=function(){return this.unsigned?this:new b(this.bytes,!0)};b.prototype.isNegative=function(){return!this.unsigned&&128===(this.bytes[l]&128)};b.prototype.isPositive=function(){return this.unsigned|| | ||
| 0===(this.bytes[l]&128)};b.prototype.isEven=function(){return 0===(this.bytes[0]&1)};b.prototype.isOdd=function(){return 1===(this.bytes[0]&1)};b.prototype.isZero=function(){for(var a=0;a<f;++a)if(0!==this.bytes[a])return!1;return!0};b.prototype.compare=function(a){b.isIntN(a)||(a=b.valueOf(a));if(this.isNegative()&&!a.isNegative())return-1;if(!this.isNegative()&&a.isNegative())return 1;for(var c=l;0<=c;--c){if(this.bytes[c]<a.bytes[c])return-1;if(this.bytes[c]>a.bytes[c])return 1}return 0};b.prototype.equals= | ||
| function(a){return 0===this.compare(a)};b.prototype.notEquals=function(a){return 0!==this.compare(a)};b.prototype.lessThan=function(a){return-1===this.compare(a)};b.prototype.lessThanEqual=function(a){return 0>=this.compare(a)};b.prototype.greaterThan=function(a){return 1===this.compare(a)};b.prototype.greaterThanEqual=function(a){return 0<=this.compare(a)};b.fromInt=function(a,c){a|=0;var d;if(0>a)return-2147483648===a?b.MIN_VALUE:d=b.fromInt(-a,c).negate();d=Array(f);for(var e=0;e<f;++e)d[e]=a>>> | ||
| 8*e&255;return d=new b(d,c)};b.prototype.toInt=function(a){a="boolean"===typeof a?a:this.unsigned;for(var b=this.isNegative(),d=b?this.not():this,e=0,g=0;e<Math.min(4,d.bytes.length);++e)g|=d.bytes[e]<<8*e;b&&(g=~g);return a?g>>>0:g};b.fromNumber=function(a,c){if("number"!==typeof a)throw TypeError("illegal arguments: "+typeof a);if(a!==a||!isFinite(a)||0===a)return c?b.UZERO:b.ZERO;if(0>a)return b.fromNumber(-a,c).negate();for(var d=0,e=Array(f);d<f;++d)e[d]=a%256&255,a=Math.floor(a/256);return new b(e, | ||
| c)};b.prototype.toNumber=function(){if(this.isZero())return 0;if(this.isNegative())return this.equals(b.MIN_VALUE)?-2147483648:-this.negate().toNumber();for(var a=0,c=0,d=Math.min(f,7);a<d;++a)c+=this.bytes[a]*t[a];return c};b.prototype.not=function(){for(var a=0,c=Array(f);a<f;++a)c[a]=~this.bytes[a];return new b(c,this.unsigned)};b.prototype.and=function(a){b.isIntN(a)||(a=b.valueOf(a));for(var c=0,d=Array(f);c<f;++c)d[c]=this.bytes[c]&a.bytes[c];return new b(d,this.unsigned)};b.prototype.or=function(a){b.isIntN(a)|| | ||
| (a=b.valueOf(a));for(var c=0,d=Array(f);c<f;++c)d[c]=this.bytes[c]|a.bytes[c];return new b(d,this.unsigned)};b.prototype.xor=function(a){b.isIntN(a)||(a=b.valueOf(a));for(var c=0,d=Array(f);c<f;++c)d[c]=this.bytes[c]^a.bytes[c];return new b(d,this.unsigned)};b.prototype.shiftLeft=function(a){b.isIntN(a)&&(a=a.toInt());a&=k-1;if(0===a)return this;var c=a/8|0;a%=8;for(var d=0,e=q.slice(0,f),g;d<f&&!((g=d+c)>=f);++d)e[g]|=this.bytes[d]<<a&255,++g<f&&(e[g]|=this.bytes[d]<<a>>>8&255);return new b(e,this.unsigned)}; | ||
| b.prototype.shiftRight=function(a,c){b.isIntN(a)&&(a=a.toInt());a&=k-1;if(0===a)return this;var d=a/8|0;a%=8;var e=q.slice(0,f),g;if(!c&&128===(this.bytes[l]&128)){var s;g=f-1;for(s=f-d-1;g>=s;--g)e[g]=255;e[++g]=e[g]<<7-a&255}var h;for(g=0;g<f;++g)0<=(h=g-d)&&(e[h]|=this.bytes[g]>>>a&255),0<=--h&&(e[h]|=this.bytes[g]<<8>>>a&255);return new b(e,this.unsigned)};b.prototype.shiftRightUnsigned=function(a){return this.shiftRight(a,!0)};b.prototype.add=function(a){b.isIntN(a)||(a=b.valueOf(a));if(a.isZero())return this; | ||
| if(this.isZero())return this.unsigned?a.toUnsigned():a.toSigned();var c=this.and(a);a=this.xor(a);for(var d;!c.isZero();)d=c.shiftLeft(1),c=a.and(d),a=a.xor(d);return a};b.prototype.negate=function(){return this.not().add(b.ONE)};b.NEG_ONE=b.ONE.negate();b.prototype.subtract=function(a){b.isIntN(a)||(a=b.valueOf(a));return this.add(a.negate())};b.prototype.absolute=function(){return this.unsigned?this:(this.isNegative()?this.negate():this).toUnsigned()};b.prototype.multiply=function(a){b.isIntN(a)|| | ||
| (a=b.valueOf(a));if(this.isZero())return this;var c=this.isNegative()!==a.isNegative(),d=this.absolute();a=a.absolute();for(var e=this.unsigned?b.UZERO:b.ZERO;!a.isZero();d=d.shiftLeft(1),a=a.shiftRight(1,!0))1===(a.bytes[0]&1)&&(e=e.add(d));return c?e.negate():e};b.divide=function(a,c){if(c.isZero())throw Error("division by zero");if(a.isZero())return{quotient:a.unsigned?b.UZERO:b.ZERO,remainder:a};for(var d=a.isNegative()!==c.isNegative(),e=a.unsigned?b.UZERO:b.ZERO,g=a.absolute(),f=c.absolute(), | ||
| h=b.UONE,k=b.MIN_VALUE.toUnsigned();h.lessThan(k)&&f.lessThan(g);)f=f.shiftLeft(1),h=h.shiftLeft(1);for(;h.greaterThanEqual(b.UONE);)f.lessThanEqual(g)&&(e=e.add(h),g=g.subtract(f)),f=f.shiftRight(1,!0),h=h.shiftRight(1,!0);return{quotient:d?e.negate():e,remainder:g}};b.prototype.divide=function(a){b.isIntN(a)||(a=b.valueOf(a));return b.divide(this,a).quotient};b.prototype.modulo=function(a){b.isIntN(a)||(a=b.valueOf(a));return b.divide(this,a).remainder};b.prototype.toDebug=function(a){for(var b= | ||
| l,d,e="";0<=b;--b){for(d=this.bytes[b].toString(2);8>d.length;)d="0"+d;e+=d;a&&0<b&&(e+=" ")}this.unsigned&&(e+=a?" U":"U");return e};var p=b.fromInt(2),u=b.fromInt(36);b.fromString=function(a,c,d){"number"===typeof c&&(d=c,c=!1);a=(a+"").toLowerCase();d=d||10;if(2>d||36<d)throw RangeError("radix out of range: "+d+" (2-36)");if("-"===a.charAt(0))return b.fromString(a.substring(1),c,d).negate();"+"===a.charAt(0)&&(a=a.substring(1));if("0"===a||"NaN"===a||"Infinity"===a)return c?b.UZERO:b.ZERO;c=c? | ||
| b.UZERO:b.ZERO;for(var e=2===d?function(a){return 1<<a}:Math.pow.bind(Math,d),f=0,k=a.length,h,l;f<k;++f){h=a.charAt(k-f-1);l="0123456789abcdefghijklmnopqrstuvwxyz".indexOf(h);if(0>l||l>d)throw Error("illegal interior character: "+h);c=c.add(b.fromInt(l).multiply(b.fromInt(e(f))))}return c};b.prototype.toString=function(a){a=a||10;b.isIntN(a)||(a=b.valueOf(a));if(a.lessThan(p)||a.greaterThan(u))throw RangeError("radix out of range: "+a.toInt()+" (2-36)");var c=this.unsigned?b.UZERO:b.ZERO;if(this.equals(c))return"0"; | ||
| if(this.isNegative()){if(this.equals(b.MIN_VALUE)){var c=b.divide(this,a).quotient,d=c.multiply(a).subtract(this);return c.toString(a)+d.toInt().toString(a.toInt())}return"-"+this.negate().toString(a)}var d=this,e=[],f;do f=d.modulo(a),e.unshift("0123456789abcdefghijklmnopqrstuvwxyz".charAt(f.toInt())),d=b.divide(d,a).quotient;while(!d.equals(c));return e.join("")};(function(){var a,c;b["isInt"+k]=b.isIntN;for(a in m.a)if(m.a.hasOwnProperty(a))for(c=0;c<m.a[a].length;++c)b[m.a[a][c]]=b[a];for(a in m.prototype)if(m.prototype.hasOwnProperty(a))for(c= | ||
| 0;c<m.prototype[a].length;++c)b.prototype[m.prototype[a][c]]=b.prototype[a]})();return r[k]=b}var r={},t=[1,256,65536,16777216,4294967296,1099511627776,281474976710656],m={a:{},prototype:{compare:["comp"],equals:["eq","equal","=="],notEquals:["ne","notEqual","!="],lessThan:["lt","less","lesser","<"],lessThanEqual:["lte","lessThanOrEqual","<="],greaterThan:["gt","greater",">"],greaterThanEqual:["gte","greaterThanOrEqual",">="],not:["~"],and:["&"],or:["|"],xor:["^"],shiftLeft:["lsh","leftShift","<<"], | ||
| shiftRight:["rsh","rightShift",">>"],shiftRightUnsigned:["rshu","rightShiftUnsigned",">>>"],add:["plus","+"],negate:["neg","!"],subtract:["sub","minus","-"],absolute:["abs","||"],multiply:["mult","*"],divide:["div","/"],modulo:["mod","%"]}};"undefined"!==typeof module&&module.exports?module.exports=n:"function"===typeof define&&define.amd?define(function(){return n}):(p.dcodeIO=p.dcodeIO||{}).IntN=n})(this); | ||
| (function(r){var q=function(){var q={},r=[1,256,65536,16777216,4294967296,1099511627776,281474976710656],s={},t={compare:["comp"],equals:["eq","equal","=="],notEquals:["ne","notEqual","!="],lessThan:["lt","less","lesser","<"],lessThanEqual:["lte","lessThanOrEqual","<="],greaterThan:["gt","greater",">"],greaterThanEqual:["gte","greaterThanOrEqual",">="],not:["~"],and:["&"],or:["|"],xor:["^"],shiftLeft:["lsh","leftShift","<<"],shiftRight:["rsh","rightShift",">>"],shiftRightUnsigned:["rshu","rightShiftUnsigned", | ||
| ">>>"],add:["plus","+"],negate:["neg","!"],subtract:["sub","minus","-"],absolute:["abs","||"],multiply:["mult","*"],divide:["div","/"],modulo:["mod","%"]};return function(m){function b(a,b){this.bytes=Array(f);for(var c=0,e=a.length;c<e;++c)this.bytes[c]=a[c]&255;for(;c<f;++c)this.bytes[c]=0;this.unsigned=!!b}if(0>=m||0!==m%8)throw Error("illegal number of bits: "+m+" (not a positive multiple of 8)");if(q[m])return q[m];for(var f=m/8|0,n=f-1,u=Array(f),h=0;h<f;++h)u[h]=0;for(var v=Array(f),h=0;h< | ||
| f;++h)v[h]=255;b.BITS=m|0;b.BYTES=f;b.isIntN=function(a){return!0===(a&&Array.isArray(a.bytes)&&a.bytes.length===f&&"boolean"===typeof a.unsigned)};b.valueOf=function(a){return"number"===typeof a?b.fromNumber(a):"string"===typeof a?b.fromString(a):a&&a instanceof b&&a.bytes.length==f?a:new b(a.bytes,a.unsigned)};b.prototype.cast=function(a,b){b="boolean"===typeof b?b:this.unsigned;var c=this.isNegative(),e=c?this.not():this,e=new a(e.bytes,b);return c?e.not():e};b.ZERO=new b([],!1);b.UZERO=new b([], | ||
| !0);b.ONE=new b([1],!1);b.UONE=new b([1],!0);b.MIN_VALUE=new b(u.slice(0,f));b.MIN_VALUE.bytes[n]|=128;b.MAX_VALUE=new b(v.slice(0,f));b.MAX_VALUE.bytes[n]&=127;b.MAX_UNSIGNED_VALUE=new b(v.slice(0,f),!0);b.prototype.isSigned=function(){return!this.unsigned};b.prototype.isUnsigned=function(){return this.unsigned};b.prototype.toSigned=function(){return this.unsigned?new b(this.bytes,!1):this};b.prototype.toUnsigned=function(){return this.unsigned?this:new b(this.bytes,!0)};b.prototype.isNegative=function(){return!this.unsigned&& | ||
| 128===(this.bytes[n]&128)};b.prototype.isPositive=function(){return this.unsigned||0===(this.bytes[n]&128)};b.prototype.isEven=function(){return 0===(this.bytes[0]&1)};b.prototype.isOdd=function(){return 1===(this.bytes[0]&1)};b.prototype.isZero=function(){for(var a=0;a<f;++a)if(0!==this.bytes[a])return!1;return!0};b.prototype.compare=function(a){b.isIntN(a)||(a=b.valueOf(a));if(this.isNegative()&&!a.isNegative())return-1;if(!this.isNegative()&&a.isNegative())return 1;for(var d=n;0<=d;--d){if(this.bytes[d]< | ||
| a.bytes[d])return-1;if(this.bytes[d]>a.bytes[d])return 1}return 0};b.prototype.equals=function(a){return 0===this.compare(a)};b.prototype.notEquals=function(a){return 0!==this.compare(a)};b.prototype.lessThan=function(a){return-1===this.compare(a)};b.prototype.lessThanEqual=function(a){return 0>=this.compare(a)};b.prototype.greaterThan=function(a){return 1===this.compare(a)};b.prototype.greaterThanEqual=function(a){return 0<=this.compare(a)};b.fromInt=function(a,d){a|=0;var c;if(0>a)return-2147483648=== | ||
| a?b.MIN_VALUE:c=b.fromInt(-a,d).negate();c=Array(f);for(var e=0;e<f;++e)c[e]=a>>>8*e&255;return c=new b(c,d)};b.prototype.toInt=function(a){a="boolean"===typeof a?a:this.unsigned;for(var b=this.isNegative(),c=b?this.not():this,e=0,g=0;e<Math.min(4,c.bytes.length);++e)g|=c.bytes[e]<<8*e;b&&(g=~g);return a?g>>>0:g};b.fromInts=function(a,d){for(var c=b.ZERO,e=0,g=Math.min(a.length,Math.ceil(f/4)),l;e<g;++e)l=a[e],c=c.or((new b([l&255,l>>>8&255,l>>>16&255,l>>>24&255])).shiftLeft(32*e));return d?c.toUnsigned(): | ||
| c};b.prototype.toInts=function(){for(var a=Math.ceil(f/4),b=Array(a),c=0,e=0,g;c<a;e=4*++c){for(var l=g=0,k=Math.min(4,f-e);l<k;++l)g|=this.bytes[e+l]<<8*l;b[c]=g}return b};b.fromNumber=function(a,d){if("number"!==typeof a)throw TypeError("illegal arguments: "+typeof a);if(a!==a||!isFinite(a)||0===a)return d?b.UZERO:b.ZERO;if(0>a)return b.fromNumber(-a,d).negate();for(var c=0,e=Array(f);c<f;++c)e[c]=a%256&255,a=Math.floor(a/256);return new b(e,d)};b.prototype.toNumber=function(){if(this.isZero())return 0; | ||
| if(this.isNegative())return this.equals(b.MIN_VALUE)?-2147483648:-this.negate().toNumber();for(var a=0,d=0,c=Math.min(f,7);a<c;++a)d+=this.bytes[a]*r[a];return d};b.prototype.not=function(){for(var a=0,d=Array(f);a<f;++a)d[a]=~this.bytes[a];return new b(d,this.unsigned)};b.prototype.and=function(a){b.isIntN(a)||(a=b.valueOf(a));for(var d=0,c=Array(f);d<f;++d)c[d]=this.bytes[d]&a.bytes[d];return new b(c,this.unsigned)};b.prototype.or=function(a){b.isIntN(a)||(a=b.valueOf(a));for(var d=0,c=Array(f);d< | ||
| f;++d)c[d]=this.bytes[d]|a.bytes[d];return new b(c,this.unsigned)};b.prototype.xor=function(a){b.isIntN(a)||(a=b.valueOf(a));for(var d=0,c=Array(f);d<f;++d)c[d]=this.bytes[d]^a.bytes[d];return new b(c,this.unsigned)};b.prototype.shiftLeft=function(a){b.isIntN(a)&&(a=a.toInt());a&=m-1;if(0===a)return this;var d=a/8|0;a%=8;for(var c=0,e=u.slice(0,f),g;c<f&&!((g=c+d)>=f);++c)e[g]|=this.bytes[c]<<a&255,++g<f&&(e[g]|=this.bytes[c]<<a>>>8&255);return new b(e,this.unsigned)};b.prototype.shiftRight=function(a, | ||
| d){b.isIntN(a)&&(a=a.toInt());a&=m-1;if(0===a)return this;var c=a/8|0;a%=8;var e=u.slice(0,f),g;if(!d&&128===(this.bytes[n]&128)){var l;g=f-1;for(l=f-c-1;g>=l;--g)e[g]=255;e[++g]=e[g]<<7-a&255}var k;for(g=0;g<f;++g)0<=(k=g-c)&&(e[k]|=this.bytes[g]>>>a&255),0<=--k&&(e[k]|=this.bytes[g]<<8>>>a&255);return new b(e,this.unsigned)};b.prototype.shiftRightUnsigned=function(a){return this.shiftRight(a,!0)};b.prototype.add=function(a){b.isIntN(a)||(a=b.valueOf(a));if(a.isZero())return this;if(this.isZero())return this.unsigned? | ||
| a.toUnsigned():a.toSigned();var d=this.and(a);a=this.xor(a);for(var c;!d.isZero();)c=d.shiftLeft(1),d=a.and(c),a=a.xor(c);return a};b.prototype.negate=function(){return this.not().add(b.ONE)};b.NEG_ONE=b.ONE.negate();b.prototype.subtract=function(a){b.isIntN(a)||(a=b.valueOf(a));return this.add(a.negate())};b.prototype.absolute=function(){return this.unsigned?this:(this.isNegative()?this.negate():this).toUnsigned()};b.prototype.multiply=function(a){b.isIntN(a)||(a=b.valueOf(a));if(this.isZero())return this; | ||
| var d=this.isNegative()!==a.isNegative(),c=this.absolute();a=a.absolute();for(var e=this.unsigned?b.UZERO:b.ZERO;!a.isZero();c=c.shiftLeft(1),a=a.shiftRight(1,!0))1===(a.bytes[0]&1)&&(e=e.add(c));return d?e.negate():e};b.divide=function(a,d){if(d.isZero())throw Error("division by zero");if(a.isZero())return{quotient:a.unsigned?b.UZERO:b.ZERO,remainder:a};for(var c=a.isNegative()!==d.isNegative(),e=a.unsigned?b.UZERO:b.ZERO,g=a.absolute(),f=d.absolute(),k=b.UONE,h=b.MIN_VALUE.toUnsigned();k.lessThan(h)&& | ||
| f.lessThan(g);)f=f.shiftLeft(1),k=k.shiftLeft(1);for(;k.greaterThanEqual(b.UONE);)f.lessThanEqual(g)&&(e=e.add(k),g=g.subtract(f)),f=f.shiftRight(1,!0),k=k.shiftRight(1,!0);return{quotient:c?e.negate():e,remainder:g}};b.prototype.divide=function(a){b.isIntN(a)||(a=b.valueOf(a));return b.divide(this,a).quotient};b.prototype.modulo=function(a){b.isIntN(a)||(a=b.valueOf(a));return b.divide(this,a).remainder};b.prototype.toDebug=function(a){for(var b=n,c,e="";0<=b;--b){for(c=this.bytes[b].toString(2);8> | ||
| c.length;)c="0"+c;e+=c;a&&0<b&&(e+=" ")}this.unsigned&&(e+=a?" U":"U");return e};var w=b.fromInt(2),x=b.fromInt(36);b.fromString=function(a,d,c){"number"===typeof d&&(c=d,d=!1);a=(a+"").toLowerCase();c=c||10;if(2>c||36<c)throw RangeError("radix out of range: "+c+" (2-36)");if("-"===a.charAt(0))return b.fromString(a.substring(1),d,c).negate();"+"===a.charAt(0)&&(a=a.substring(1));if("0"===a||"NaN"===a||"Infinity"===a)return d?b.UZERO:b.ZERO;d=d?b.UZERO:b.ZERO;for(var e=2===c?function(a){return 1<< | ||
| a}:Math.pow.bind(Math,c),g=0,f=a.length,k,h;g<f;++g){k=a.charAt(f-g-1);h="0123456789abcdefghijklmnopqrstuvwxyz".indexOf(k);if(0>h||h>c)throw Error("illegal interior character: "+k);d=d.add(b.fromInt(h).multiply(b.fromInt(e(g))))}return d};b.prototype.toString=function(a){a=a||10;b.isIntN(a)||(a=b.valueOf(a));if(a.lessThan(w)||a.greaterThan(x))throw RangeError("radix out of range: "+a.toInt()+" (2-36)");var d=this.unsigned?b.UZERO:b.ZERO;if(this.equals(d))return"0";if(this.isNegative()){if(this.equals(b.MIN_VALUE)){var d= | ||
| b.divide(this,a).quotient,c=d.multiply(a).subtract(this);return d.toString(a)+c.toInt().toString(a.toInt())}return"-"+this.negate().toString(a)}var c=this,e=[],f;do f=c.modulo(a),e.unshift("0123456789abcdefghijklmnopqrstuvwxyz".charAt(f.toInt())),c=b.divide(c,a).quotient;while(!c.equals(d));return e.join("")};b["isInt"+m]=b.isIntN;for(var p in s)if(s.hasOwnProperty(p))for(h=0;h<s[p].length;++h)b[s[p][h]]=b[p];for(p in t)if(t.hasOwnProperty(p))for(h=0;h<t[p].length;++h)b.prototype[t[p][h]]=b.prototype[p]; | ||
| return q[m]=b}}();"undefined"!==typeof module&&module.exports?module.exports=q:"function"===typeof define&&define.amd?define(function(){return q}):(r.dcodeIO=r.dcodeIO||{}).IntN=q})(this); |
| { | ||
| "version":3, | ||
| "file":"", | ||
| "lineCount":22, | ||
| "mappings":"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", | ||
| "lineCount":23, | ||
| "mappings":"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", | ||
| "sources":["dist/IntN.js"], | ||
| "names":["global","makeIntN","nBits","IntN","bytes","unsigned","Array","nBytes","i","k","length","Error","classes","BITS","BYTES","maxIndex","zeroes","ones","isIntN","IntN.isIntN","obj","isArray","valueOf","IntN.valueOf","val","fromNumber","fromString","prototype","cast","IntN.prototype.cast","TargetIntN","retainMsb","isNegative","not","ZERO","UZERO","ONE","UONE","MIN_VALUE","slice","MAX_VALUE","MAX_UNSIGNED_VALUE","isSigned","IntN.prototype.isSigned","isUnsigned","IntN.prototype.isUnsigned","toSigned","IntN.prototype.toSigned","toUnsigned","IntN.prototype.toUnsigned","IntN.prototype.isNegative","isPositive","IntN.prototype.isPositive","isEven","IntN.prototype.isEven","isOdd","IntN.prototype.isOdd","isZero","IntN.prototype.isZero","compare","IntN.prototype.compare","other","equals","IntN.prototype.equals","notEquals","IntN.prototype.notEquals","lessThan","IntN.prototype.lessThan","lessThanEqual","IntN.prototype.lessThanEqual","greaterThan","IntN.prototype.greaterThan","greaterThanEqual","IntN.prototype.greaterThanEqual","fromInt","IntN.fromInt","value","int32_min_value","negate","toInt","IntN.prototype.toInt","result","Math","min","IntN.fromNumber","TypeError","isFinite","floor","toNumber","IntN.prototype.toNumber","double_256_pwr","IntN.prototype.not","and","IntN.prototype.and","or","IntN.prototype.or","xor","IntN.prototype.xor","shiftLeft","IntN.prototype.shiftLeft","numBits","numBytes","idx","shiftRight","IntN.prototype.shiftRight","logical","shiftRightUnsigned","IntN.prototype.shiftRightUnsigned","add","IntN.prototype.add","carry","shifted","IntN.prototype.negate","NEG_ONE","subtract","IntN.prototype.subtract","absolute","IntN.prototype.absolute","multiply","IntN.prototype.multiply","a","b","divide","IntN.divide","dividend","divisor","quotient","remainder","product","term","maxTerm","IntN.prototype.divide","modulo","IntN.prototype.modulo","toDebug","IntN.prototype.toDebug","spaces","byt","out","toString","IntN_2","IntN_36","IntN.fromString","radix","toLowerCase","RangeError","charAt","substring","radixToPower","pow","bind","ch","chars","indexOf","IntN.prototype.toString","zero","div","rem","digits","mod","unshift","join","key","aliases","statics","hasOwnProperty","module","define"] | ||
| "names":["global","IntN","classes","double_256_pwr","makeIntN","nBits","bytes","unsigned","Array","nBytes","i","k","length","Error","maxIndex","zeroes","ones","BITS","BYTES","isIntN","IntN.isIntN","obj","isArray","valueOf","IntN.valueOf","val","fromNumber","fromString","prototype","cast","IntN.prototype.cast","TargetIntN","retainMsb","isNegative","not","ZERO","UZERO","ONE","UONE","MIN_VALUE","slice","MAX_VALUE","MAX_UNSIGNED_VALUE","isSigned","IntN.prototype.isSigned","isUnsigned","IntN.prototype.isUnsigned","toSigned","IntN.prototype.toSigned","toUnsigned","IntN.prototype.toUnsigned","IntN.prototype.isNegative","isPositive","IntN.prototype.isPositive","isEven","IntN.prototype.isEven","isOdd","IntN.prototype.isOdd","isZero","IntN.prototype.isZero","compare","IntN.prototype.compare","other","equals","IntN.prototype.equals","notEquals","IntN.prototype.notEquals","lessThan","IntN.prototype.lessThan","lessThanEqual","IntN.prototype.lessThanEqual","greaterThan","IntN.prototype.greaterThan","greaterThanEqual","IntN.prototype.greaterThanEqual","fromInt","IntN.fromInt","value","int32_min_value","negate","toInt","IntN.prototype.toInt","result","Math","min","fromInts","IntN.fromInts","ints","ceil","or","shiftLeft","toInts","IntN.prototype.toInts","numChunks","arr","offset","j","l","IntN.fromNumber","TypeError","isFinite","floor","toNumber","IntN.prototype.toNumber","IntN.prototype.not","and","IntN.prototype.and","IntN.prototype.or","xor","IntN.prototype.xor","IntN.prototype.shiftLeft","numBits","numBytes","idx","shiftRight","IntN.prototype.shiftRight","logical","shiftRightUnsigned","IntN.prototype.shiftRightUnsigned","add","IntN.prototype.add","carry","carryPwr2","IntN.prototype.negate","NEG_ONE","subtract","IntN.prototype.subtract","absolute","IntN.prototype.absolute","multiply","IntN.prototype.multiply","a","b","divide","IntN.divide","dividend","divisor","quotient","remainder","product","term","maxTerm","IntN.prototype.divide","modulo","IntN.prototype.modulo","toDebug","IntN.prototype.toDebug","spaces","byt","out","toString","IntN_2","IntN_36","IntN.fromString","radix","toLowerCase","RangeError","charAt","substring","radixToPower","pow","bind","ch","chars","indexOf","IntN.prototype.toString","zero","div","rem","digits","mod","unshift","join","key","statics","hasOwnProperty","module","define"] | ||
| } |
+3
-0
@@ -15,1 +15,4 @@ Distributions | ||
| is the source map generated by Closure Compiler. | ||
| * **[IntN-embeddable.js](https://raw.githubusercontent.com/dcodeIO/IntN.js/master/dist/IntN-embeddable.js)** | ||
| is an embeddable library. |
+0
-3
| ### Class [IntN](IntN.md) | ||
| A class for representing arbitrary size integers, both signed and unsigned. | ||
| ### Class [IntN](IntN.md) | ||
| A class for representing arbitrary size integers, both signed and unsigned. | ||
| --- | ||
| *Generated with [doco](https://github.com/dcodeIO/doco) v0.3.0* |
+20
-2
@@ -13,3 +13,3 @@ ## Class IntN | ||
| |-----------------|-----------------|--------------- | ||
| | bytes | *!Array.<number>* | Byte values, least significant first | ||
| | bytes | *!Array.<number> | number* | Byte values, least significant first | ||
| | unsigned | *boolean* | Whether unsigned or signed, defaults to `false` for signed | ||
@@ -130,2 +130,12 @@ | ||
| #### IntN.fromInts(ints, unsigned=) | ||
| Reassembles an IntN from an array of 32bit integers, least significant first. | ||
| | Parameter | Type | Description | ||
| |-----------------|-----------------|--------------- | ||
| | ints | *!Array.<number>* | Array of 32bit integers | ||
| | unsigned | *boolean* | Whether unsigned or not, defaults to `false` for signed | ||
| | **@returns** | *!IntN* | | ||
| #### IntN.fromNumber(value, unsigned=) | ||
@@ -446,3 +456,3 @@ | ||
| Converts this IntN to a 32bit integer value. | ||
| Converts this IntN to a 32bit integer. | ||
@@ -454,2 +464,10 @@ | Parameter | Type | Description | ||
| #### IntN#toInts() | ||
| Disassembles this IntN into an array of 32bit integers, least significant first. | ||
| | Parameter | Type | Description | ||
| |-----------------|-----------------|--------------- | ||
| | **@returns** | *!Array.<number>* | | ||
| #### IntN#toNumber() | ||
@@ -456,0 +474,0 @@ |
+4
-3
| { | ||
| "name": "intn", | ||
| "version": "0.8.0", | ||
| "version": "0.9.0", | ||
| "author": "Daniel Wirtz <dcode@dcode.io>", | ||
| "description": "A class for representing arbitrary byte size integers, signed and unsigned.", | ||
| "description": "A library for representing and working with arbitrary byte size two's complement integers, signed and unsigned.", | ||
| "main": "index.js", | ||
@@ -16,2 +16,3 @@ "repository": { | ||
| "testjs": "latest", | ||
| "metascript": "~0", | ||
| "closurecompiler": "latest" | ||
@@ -25,3 +26,3 @@ }, | ||
| "test": "node node_modules/testjs/bin/testjs tests/suite.js", | ||
| "build": "cp src/IntN.js dist/IntN.js", | ||
| "build": "node node_modules/metascript/bin/metascript src/IntN.js >dist/IntN.js && node node_modules/metascript/bin/metascript src/IntN-embeddable.js >dist/IntN-embeddable.js", | ||
| "compile": "ccjs dist/IntN.js --compilation_level=ADVANCED_OPTIMIZATIONS --create_source_map=dist/IntN.min.map --source_map_format=V3 --externs=externs/minimal-env.js > dist/IntN.min.js", | ||
@@ -28,0 +29,0 @@ "compress": "gzip -c -9 dist/IntN.min.js > dist/IntN.min.js.gz", |
+24
-5
@@ -1,5 +0,6 @@ | ||
|  | ||
|  | ||
| ======= | ||
| **IntN.js** is a library to represent and work with arbitrary byte size integers in JavaScript, both signed and | ||
| unsigned. | ||
| **IntN.js** is a library for representing and working with arbitrary byte size two's complement integers in JavaScript, | ||
| both signed and unsigned. Its main goal is to provide a robust and convenient way to work with data types that are not | ||
| available in JavaScript natively, like 64 bit `long`s. | ||
@@ -37,3 +38,3 @@ Usage | ||
| |-----------------|-----------------|--------------- | ||
| | bytes | *!Array.<number>* | Byte values, least significant first | ||
| | bytes | *!Array.<number> | number* | Byte values, least significant first | ||
| | unsigned | *boolean* | Whether unsigned or signed, defaults to `false` for signed | ||
@@ -154,2 +155,12 @@ | ||
| #### IntN.fromInts(ints, unsigned=) | ||
| Reassembles an IntN from an array of 32bit integers, least significant first. | ||
| | Parameter | Type | Description | ||
| |-----------------|-----------------|--------------- | ||
| | ints | *!Array.<number>* | Array of 32bit integers | ||
| | unsigned | *boolean* | Whether unsigned or not, defaults to `false` for signed | ||
| | **@returns** | *!IntN* | | ||
| #### IntN.fromNumber(value, unsigned=) | ||
@@ -470,3 +481,3 @@ | ||
| Converts this IntN to a 32bit integer value. | ||
| Converts this IntN to a 32bit integer. | ||
@@ -478,2 +489,10 @@ | Parameter | Type | Description | ||
| #### IntN#toInts() | ||
| Disassembles this IntN into an array of 32bit integers, least significant first. | ||
| | Parameter | Type | Description | ||
| |-----------------|-----------------|--------------- | ||
| | **@returns** | *!Array.<number>* | | ||
| #### IntN#toNumber() | ||
@@ -480,0 +499,0 @@ |
+6
-967
@@ -16,2 +16,3 @@ /* | ||
| */ | ||
| //? INTN_STANDALONE = true; | ||
@@ -24,974 +25,12 @@ /** | ||
| (function(global) { | ||
| //? include("lib.js"); | ||
| /** | ||
| * Creates a class for representing `nBits` bit integers. | ||
| * @param {number} nBits Number of bits (must be a positive multiple of 8) | ||
| * @returns {!Function} | ||
| * @inner | ||
| */ | ||
| function makeIntN(nBits) { | ||
| if (nBits <= 0 || (nBits%8) !== 0) | ||
| throw Error("illegal number of bits: "+nBits+" (not a positive multiple of 8)"); | ||
| // Make sure to return singleton classes | ||
| if (classes[nBits]) | ||
| return classes[nBits]; | ||
| /** | ||
| * Number of bits represented by this IntN class. | ||
| * @type {number} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.BITS = nBits|0; | ||
| /** | ||
| * Number of bytes. | ||
| * @type {number} | ||
| * @inner | ||
| */ | ||
| var nBytes = (nBits/8)|0; | ||
| /** | ||
| * Number of bytes represented by this IntN class. | ||
| * @type {number} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.BYTES = nBytes; | ||
| /** | ||
| * Maximum byte index. | ||
| * @type {number} | ||
| * @inner | ||
| */ | ||
| var maxIndex = nBytes-1; | ||
| /** | ||
| * Array of binary zeroes. | ||
| * @type {!Array.<number>} | ||
| * @inner | ||
| */ | ||
| var zeroes = new Array(nBytes); | ||
| (function() { | ||
| for (var i=0; i<nBytes; ++i) | ||
| zeroes[i] = 0; | ||
| })(); | ||
| /** | ||
| * Array of binary ones. | ||
| * @type {!Array.<number>} | ||
| * @inner | ||
| */ | ||
| var ones = new Array(nBytes); | ||
| (function() { | ||
| for (var i=0; i<nBytes; ++i) | ||
| ones[i] = 0xff; | ||
| })(); | ||
| /** | ||
| * Constructs a new IntN, where N is the number of bits represented by this class. | ||
| * @class A class for representing arbitrary size integers, both signed and unsigned. | ||
| * @exports IntN | ||
| * @param {!Array.<number>} bytes Byte values, least significant first | ||
| * @param {boolean=} unsigned Whether unsigned or signed, defaults to `false` for signed | ||
| * @constructor | ||
| */ | ||
| function IntN(bytes, unsigned) { | ||
| /** | ||
| * Represented byte values, least significant first. | ||
| * @type {!Array.<number>} | ||
| * @expose | ||
| */ | ||
| this.bytes = new Array(nBytes); | ||
| for (var i=0, k=bytes.length; i<k; ++i) | ||
| this.bytes[i] = bytes[i] & 0xff; | ||
| for (; i<nBytes; ++i) | ||
| this.bytes[i] = 0; | ||
| /** | ||
| * Whether unsigned or otherwise signed. | ||
| * @type {boolean} | ||
| * @expose | ||
| */ | ||
| this.unsigned = !!unsigned; | ||
| // ++IntN.NEW_COUNT; | ||
| } | ||
| /** | ||
| * Number of so far created instances for performance analysis. | ||
| * @type {number} | ||
| * @private | ||
| * @expose | ||
| */ | ||
| // IntN.NEW_COUNT = 0; | ||
| // General utility | ||
| /** | ||
| * Tests if an object is an N bit integer, where N is this class's number of bits. | ||
| * @param {*} obj Object to test | ||
| * @returns {boolean} `true` if it is an N bit integer, otherwise `false` | ||
| * @expose | ||
| */ | ||
| IntN.isIntN = function(obj) { | ||
| return (obj && Array.isArray(obj.bytes) && obj.bytes.length === nBytes && typeof obj.unsigned === 'boolean') | ||
| === true; | ||
| }; | ||
| /** | ||
| * Converts the specified value to an IntN. | ||
| * @param {number|string|!{bytes: !Array.<number>, unsigned: boolean}} val Value | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.valueOf = function(val) { | ||
| if (typeof val === 'number') | ||
| return IntN.fromNumber(val); | ||
| else if (typeof val === 'string') | ||
| return IntN.fromString(val); | ||
| else if (val && val instanceof IntN && val.bytes.length == nBytes) | ||
| return val; | ||
| // Throws for not an object (undefined, null) bytes not an array (in constructor), | ||
| // fills smaller, truncates larger N (does not respect sign if differing): | ||
| return new IntN(val.bytes, val.unsigned); | ||
| }; | ||
| /** | ||
| * Casts this IntN of size N to the specified target IntN of size M. | ||
| * @param {!Function} TargetIntN Target IntN class | ||
| * @param {boolean=} unsigned Whether unsigned or not, defaults to this' {@link IntN#unsigned} | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.cast = function(TargetIntN, unsigned) { | ||
| unsigned = typeof unsigned === 'boolean' ? unsigned : this.unsigned; | ||
| var retainMsb = this.isNegative(), | ||
| val = retainMsb ? this.not() : this; | ||
| val = new TargetIntN(val.bytes, unsigned); | ||
| return retainMsb ? val.not() : val; | ||
| }; | ||
| // Basic constants | ||
| /** | ||
| * Signed zero. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.ZERO = new IntN([], false); | ||
| /** | ||
| * Unsigned zero. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.UZERO = new IntN([], true); | ||
| /** | ||
| * Signed one. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.ONE = new IntN([1], false); | ||
| /** | ||
| * Unsigned one. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.UONE = new IntN([1], true); | ||
| /** | ||
| * Minimum signed value. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.MIN_VALUE = new IntN(zeroes.slice(0, nBytes)); | ||
| IntN.MIN_VALUE.bytes[maxIndex] |= 0x80; | ||
| /** | ||
| * Maximum signed value. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.MAX_VALUE = new IntN(ones.slice(0, nBytes)); | ||
| IntN.MAX_VALUE.bytes[maxIndex] &= 0x7f; | ||
| /** | ||
| * Maximum unsigned value. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.MAX_UNSIGNED_VALUE = new IntN(ones.slice(0, nBytes), true); | ||
| // Signed evaluation | ||
| /** | ||
| * Tests if this IntN is signed. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isSigned = function() { | ||
| return !this.unsigned; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is unsigned. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isUnsigned = function() { | ||
| return this.unsigned; | ||
| }; | ||
| // Signed conversion | ||
| /** | ||
| * Converts this IntN to signed and returns the result. | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toSigned = function() { | ||
| if (!this.unsigned) | ||
| return this; | ||
| return new IntN(this.bytes, false); | ||
| }; | ||
| /** | ||
| * Converts this IntN to unsigned and returns the result. | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toUnsigned = function() { | ||
| if (this.unsigned) | ||
| return this; | ||
| return new IntN(this.bytes, true); | ||
| }; | ||
| // Arithmetic evalutation | ||
| /** | ||
| * Tests if this IntN is (signed and) negative. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isNegative = function() { | ||
| return !this.unsigned && (this.bytes[maxIndex] & 0x80) === 0x80; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is (unsigned or) positive. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isPositive = function() { | ||
| return this.unsigned || (this.bytes[maxIndex] & 0x80) === 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is even. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isEven = function() { | ||
| return (this.bytes[0] & 1) === 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is odd. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isOdd = function() { | ||
| return (this.bytes[0] & 1) === 1; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is zero. | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.isZero = function() { | ||
| for (var i=0; i<nBytes; ++i) | ||
| if (this.bytes[i] !== 0) | ||
| return false; | ||
| return true; | ||
| }; | ||
| /** | ||
| * Compares this IntN with the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {number} `0` if both are the same, `1` if this is greater and `-1` if the specified is greater | ||
| * @expose | ||
| */ | ||
| IntN.prototype.compare = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| if (this.isNegative() && !other.isNegative()) | ||
| return -1; | ||
| if (!this.isNegative() && other.isNegative()) | ||
| return 1; | ||
| for (var i=maxIndex; i>=0; --i) | ||
| if (this.bytes[i] < other.bytes[i]) | ||
| return -1; | ||
| else if (this.bytes[i] > other.bytes[i]) | ||
| return 1; | ||
| return 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN equals the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.equals = function(other) { | ||
| return this.compare(other) === 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN does not equal the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.notEquals = function(other) { | ||
| return this.compare(other) !== 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is less than (<) the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.lessThan = function(other) { | ||
| return this.compare(other) === -1; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is less than or equal (<=) the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.lessThanEqual = function(other) { | ||
| return this.compare(other) <= 0; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is greater than (>) the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.greaterThan = function(other) { | ||
| return this.compare(other) === 1; | ||
| }; | ||
| /** | ||
| * Tests if this IntN is greater than or equal (>=) the specified. | ||
| * @param {!IntN|number|string} other Other value | ||
| * @returns {boolean} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.greaterThanEqual = function(other) { | ||
| return this.compare(other) >= 0; | ||
| }; | ||
| // Integer conversion | ||
| /** | ||
| * Constructs an IntN from a 32bit integer value. | ||
| * @param {number} value Integer value | ||
| * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.fromInt = function(value, unsigned) { | ||
| value = value|0; | ||
| var val; | ||
| if (value < 0) { | ||
| if (value === int32_min_value) // -MIN_VALUE = MIN_VALUE | ||
| return IntN.MIN_VALUE; | ||
| val = IntN.fromInt(-value, unsigned).negate(); | ||
| return val; | ||
| } | ||
| var bytes = new Array(nBytes); | ||
| for (var i=0; i<nBytes; ++i) | ||
| bytes[i] = (value >>> (i*8)) & 0xff; | ||
| val = new IntN(bytes, unsigned); | ||
| return val; | ||
| }; | ||
| /** | ||
| * Converts this IntN to a 32bit integer value. | ||
| * @param {boolean=} unsigned Whether unsigned or not, defaults to this' {@link IntN#unsigned} | ||
| * @returns {number} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toInt = function(unsigned) { | ||
| unsigned = typeof unsigned === 'boolean' ? unsigned : this.unsigned; | ||
| var retainMsb = this.isNegative(), | ||
| val = retainMsb ? this.not() : this; | ||
| for (var i=0, result=0; i<Math.min(4, val.bytes.length); ++i) | ||
| result |= val.bytes[i] << (i*8); | ||
| if (retainMsb) | ||
| result = ~result; | ||
| return unsigned ? result >>> 0 : result; | ||
| }; | ||
| // Number conversion | ||
| /** | ||
| * Constructs an IntN from a number (double, 52 bit mantissa) value. | ||
| * @param {number} value Number value | ||
| * @param {boolean=} unsigned Whether unsigned or not, defaults `false` for signed | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.fromNumber = function(value, unsigned) { | ||
| if (typeof value !== 'number') | ||
| throw TypeError("illegal arguments: "+typeof(value)); | ||
| if (value !== value || !isFinite(value) || value === 0) | ||
| return unsigned ? IntN.UZERO : IntN.ZERO; | ||
| if (value < 0) | ||
| return IntN.fromNumber(-value, unsigned).negate(); | ||
| // now always gt 0: | ||
| for (var i=0, bytes=new Array(nBytes); i<nBytes; ++i) | ||
| bytes[i] = (value % 256) & 0xff, // bytes[maxIndex] may overflow the sign bit | ||
| value = Math.floor(value / 256); | ||
| return new IntN(bytes, unsigned); | ||
| }; | ||
| /** | ||
| * Converts this IntN to a number (double, 52 bit mantissa) value. | ||
| * @returns {number} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toNumber = function() { | ||
| if (this.isZero()) | ||
| return 0; | ||
| if (this.isNegative()) | ||
| return this.equals(IntN.MIN_VALUE) ? +int32_min_value : -this.negate().toNumber(); // -MIN_VALUE = MIN_VALUE | ||
| // now always gt 0: | ||
| for (var i=0, result=0, k=Math.min(nBytes, 7); i<k; ++i) // 7 bytes = 56 bits | ||
| result += this.bytes[i] * double_256_pwr[i]; | ||
| return result; | ||
| }; | ||
| // Bitwise operations | ||
| /** | ||
| * Performs a bitwise not (~) operation and returns the result. | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.not = function() { | ||
| for (var i=0, bytes=new Array(nBytes); i<nBytes; ++i) | ||
| bytes[i] = ~this.bytes[i]; // & 0xff not necessary, see test | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| /** | ||
| * Performs a bitwise and (&) operation and returns the resulting Int. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.and = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| for (var i=0, bytes=new Array(nBytes); i<nBytes; ++i) | ||
| bytes[i] = this.bytes[i] & other.bytes[i]; | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| /** | ||
| * Performs a bitwise or (|) operation and returns the resulting Int. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.or = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| for (var i=0, bytes=new Array(nBytes); i<nBytes; ++i) | ||
| bytes[i] = this.bytes[i] | other.bytes[i]; | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| /** | ||
| * Performs a bitwise xor (^) operation and returns the result. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.xor = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| for (var i=0, bytes=new Array(nBytes); i<nBytes; ++i) | ||
| bytes[i] = this.bytes[i] ^ other.bytes[i]; | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| /** | ||
| * Performs a shift left (<<) operation and returns the result. | ||
| * @param {!IntN|number} numBits Number of bits | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.shiftLeft = function(numBits) { | ||
| if (IntN.isIntN(numBits)) | ||
| numBits = numBits.toInt(); | ||
| numBits &= nBits-1; // << 0 ^= << n | ||
| if (numBits === 0) | ||
| return this; | ||
| var numBytes = (numBits/8)|0; // Full byte skips | ||
| numBits %= 8; // Byte level bit skips | ||
| for (var i=0, bytes=zeroes.slice(0, nBytes), idx; i<nBytes; ++i) { | ||
| if ((idx = i+numBytes) >= nBytes) | ||
| break; | ||
| bytes[idx] |= (this.bytes[i] << numBits) & 0xff; | ||
| if (++idx < nBytes) | ||
| bytes[idx] |= (this.bytes[i] << numBits >>> 8) & 0xff; | ||
| } | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| /** | ||
| * Performs a shift right (>>, >>>) operation and returns the result. | ||
| * @param {!IntN|number} numBits Number of bits | ||
| * @param {boolean=} logical Whether to perform a logical (>>>) shift right, defaults to `false` for an arithmetic | ||
| * shift right (>>) | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.shiftRight = function(numBits, logical) { | ||
| if (IntN.isIntN(numBits)) | ||
| numBits = numBits.toInt(); | ||
| numBits &= nBits-1; // >> 0 ^= >> n | ||
| if (numBits === 0) | ||
| return this; | ||
| var numBytes = (numBits/8)|0; // Full byte skips | ||
| numBits %= 8; // Byte level bit skips | ||
| var bytes = zeroes.slice(0, nBytes), i; | ||
| if (!logical && (this.bytes[maxIndex] & 0x80) === 0x80) { | ||
| var k; for (i=nBytes-1, k=nBytes-numBytes-1; i>=k; --i) | ||
| bytes[i] = 0xff; | ||
| bytes[++i /* !k */] = (bytes[i] << (7-numBits)) & 0xff; | ||
| } | ||
| var idx; | ||
| for (i=0; i<nBytes; ++i) { | ||
| if ((idx = i-numBytes) >= 0) | ||
| bytes[idx] |= (this.bytes[i] >>> numBits) & 0xff; | ||
| if (--idx >= 0) | ||
| bytes[idx] |= (this.bytes[i] << 8 >>> numBits) & 0xff; | ||
| } | ||
| return new IntN(bytes, this.unsigned); | ||
| }; | ||
| /** | ||
| * Performs an unsigned shift right (>>>) operation and returns the result. | ||
| * @param {!IntN|number} numBits Number of bits | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.shiftRightUnsigned = function(numBits) { | ||
| return this.shiftRight(numBits, true); | ||
| }; | ||
| // Arithmetic operations | ||
| /** | ||
| * Adds the specified to this IntN and returns the result. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.add = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| if (other.isZero()) | ||
| return this; | ||
| if (this.isZero()) | ||
| return this.unsigned ? other.toUnsigned() : other.toSigned(); | ||
| var carry = this.and(other), | ||
| result = this.xor(other), | ||
| shifted; | ||
| while (!carry.isZero()) | ||
| shifted = carry.shiftLeft(1), | ||
| carry = result.and(shifted), | ||
| result = result.xor(shifted); | ||
| return result; | ||
| }; | ||
| /** | ||
| * Negates this IntN (*-1) and returns the result. | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.negate = function() { | ||
| return this.not().add(IntN.ONE); | ||
| }; | ||
| /** | ||
| * Negative signed one. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @expose | ||
| */ | ||
| IntN.NEG_ONE = IntN.ONE.negate(); | ||
| /** | ||
| * Subtracts the specified from this IntN and returns the result. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.subtract = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| return this.add(other.negate()); | ||
| }; | ||
| /** | ||
| * Returns this IntN's absolute value as an unsigned IntN. | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.absolute = function() { | ||
| if (this.unsigned) | ||
| return this; | ||
| return (this.isNegative() ? this.negate() : this).toUnsigned(); | ||
| }; | ||
| /** | ||
| * Multiplies this IntN with the specified and returns the result. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.multiply = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| if (this.isZero()) // other == 0 will break the loop below early while this == 0 will not | ||
| return this; | ||
| var isNegative = this.isNegative() !== other.isNegative(), | ||
| a = this.absolute(), | ||
| b = other.absolute(), | ||
| result = this.unsigned ? IntN.UZERO : IntN.ZERO; | ||
| for(;!b.isZero(); a=a.shiftLeft(1), b=b.shiftRight(1, true)) | ||
| if ((b.bytes[0] & 1) === 1) | ||
| result = result.add(a); | ||
| return isNegative ? result.negate() : result; | ||
| }; | ||
| /** | ||
| * Divides the specified dividend by the specified divisor. This method is used internally by {@link IntN#divide} | ||
| * and {@link IntN#modulo} and is exposed statically in case both the result and the remainder are required. | ||
| * @param {!IntN} dividend | ||
| * @param {!IntN} divisor | ||
| * @returns {!{quotient: !IntN, remainder: !IntN}} | ||
| * @expose | ||
| */ | ||
| IntN.divide = function(dividend, divisor) { | ||
| if (divisor.isZero()) | ||
| throw Error("division by zero"); | ||
| if (dividend.isZero()) | ||
| return { | ||
| "quotient": dividend.unsigned ? IntN.UZERO : IntN.ZERO, | ||
| "remainder": dividend | ||
| }; | ||
| var isNegative = dividend.isNegative() !== divisor.isNegative(), | ||
| quotient = dividend.unsigned ? IntN.UZERO : IntN.ZERO, | ||
| remainder = dividend.absolute(), | ||
| product = divisor.absolute(), | ||
| term = IntN.UONE, | ||
| maxTerm = IntN.MIN_VALUE.toUnsigned(); | ||
| while (term.lessThan(maxTerm) && product.lessThan(remainder)) | ||
| product = product.shiftLeft(1), | ||
| term = term.shiftLeft(1); | ||
| while (term.greaterThanEqual(IntN.UONE)) { | ||
| if (product.lessThanEqual(remainder)) | ||
| quotient = quotient.add(term), | ||
| remainder = remainder.subtract(product); | ||
| product = product.shiftRight(1, true); | ||
| term = term.shiftRight(1, true); | ||
| } | ||
| return { | ||
| "quotient": isNegative ? quotient.negate() : quotient, | ||
| "remainder": remainder | ||
| }; | ||
| }; | ||
| /** | ||
| * Divides this IntN by the specified and returns the result. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.divide = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| return IntN.divide(this, other)['quotient']; | ||
| }; | ||
| /** | ||
| * Returns the remainder of the division of this IntN by the specified. | ||
| * @param {!IntN|number|string} other Other number | ||
| * @returns {!IntN} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.modulo = function(other) { | ||
| if (!IntN.isIntN(other)) | ||
| other = IntN.valueOf(other); | ||
| return IntN.divide(this, other)['remainder']; | ||
| }; | ||
| /** | ||
| * Converts this IntN to its full binary representation. This returns N (number of bits) binary digits for | ||
| * testing and debugging, followed by the character `U` if unsigned. | ||
| * @param {boolean=} spaces Whether to insert spaces between bytes, defaults to `false` | ||
| * @returns {string} | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toDebug = function(spaces) { | ||
| for (var i=maxIndex, byt, out=""; i>=0; --i) { | ||
| byt = this.bytes[i].toString(2); | ||
| while (byt.length < 8) | ||
| byt = '0'+byt; | ||
| out += byt; | ||
| if (spaces && i > 0) | ||
| out += ' '; | ||
| } | ||
| if (this.unsigned) | ||
| out += spaces ? " U" : 'U'; | ||
| return out; | ||
| }; | ||
| // String conversion | ||
| /** | ||
| * IntN representing 2. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var IntN_2 = IntN.fromInt(2); | ||
| /** | ||
| * IntN representing 36. | ||
| * @type {!IntN} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var IntN_36 = IntN.fromInt(36); | ||
| /** | ||
| * Converts a string using the specified radix to an IntN. | ||
| * @param {string} value String | ||
| * @param {(boolean|number)=} unsigned Whether unsigned or not, defaults to `false` for signed (omittable) | ||
| * @param {number=} radix Radix (2-36), defaults to 10 | ||
| * @returns {!IntN} | ||
| * @throws {RangeError} If `radix` is out of range | ||
| * @throws {Error} If `value` contains illegal characters | ||
| * @expose | ||
| */ | ||
| IntN.fromString = function(value, unsigned, radix) { | ||
| if (typeof unsigned === 'number') | ||
| radix = unsigned, | ||
| unsigned = false; | ||
| value = (value+"").toLowerCase(); | ||
| radix = radix || 10; | ||
| if (radix < 2 || radix > 36) | ||
| throw RangeError("radix out of range: "+radix+" (2-36)"); | ||
| if (value.charAt(0) === '-') | ||
| return IntN.fromString(value.substring(1), unsigned, radix).negate(); | ||
| if (value.charAt(0) === '+') | ||
| value = value.substring(1); | ||
| // now always gte 0: | ||
| if (value === '0' || value === 'NaN' || value === 'Infinity') | ||
| return unsigned ? IntN.UZERO : IntN.ZERO; | ||
| // now always gt 0: | ||
| var result = unsigned ? IntN.UZERO : IntN.ZERO, | ||
| radixToPower = (radix === 2) | ||
| ? function(i) { return 1 << i; } | ||
| : Math.pow.bind(Math, radix); | ||
| for (var i=0, k=value.length, ch, val; i<k; ++i) { | ||
| ch = value.charAt(k-i-1); | ||
| val = chars.indexOf(ch); | ||
| if (val < 0 || val > radix) | ||
| throw Error("illegal interior character: "+ch); | ||
| result = result.add(IntN.fromInt(val).multiply(IntN.fromInt(radixToPower(i)))); | ||
| } | ||
| return result; | ||
| }; | ||
| /** | ||
| * Converts this IntN to a string of the specified radix. | ||
| * @param {!IntN|number|string} radix Radix (2-36), defaults to 10 | ||
| * @returns {string} | ||
| * @throws {RangeError} If `radix` is out of range | ||
| * @expose | ||
| */ | ||
| IntN.prototype.toString = function(radix) { | ||
| radix = radix || 10; | ||
| if (!IntN.isIntN(radix)) | ||
| radix = IntN.valueOf(radix); | ||
| if (radix.lessThan(IntN_2) || radix.greaterThan(IntN_36)) | ||
| throw RangeError("radix out of range: "+radix.toInt()+" (2-36)"); | ||
| var zero = this.unsigned ? IntN.UZERO : IntN.ZERO; | ||
| if (this.equals(zero)) | ||
| return '0'; | ||
| if (this.isNegative()) { | ||
| if (this.equals(IntN.MIN_VALUE)) { // -MIN_VALUE = MIN_VALUE | ||
| var div = IntN.divide(this, radix)['quotient'], | ||
| rem = div.multiply(radix).subtract(this); | ||
| return div.toString(radix) + rem.toInt().toString(radix.toInt()); | ||
| } | ||
| return '-'+this.negate().toString(radix); | ||
| } | ||
| // now always gt 0: | ||
| var result = this, | ||
| digits = [], | ||
| mod; | ||
| do | ||
| mod = result.modulo(radix), | ||
| digits.unshift(chars.charAt(mod.toInt())), | ||
| result = IntN.divide(result, radix)['quotient']; | ||
| while (!result.equals(zero)); | ||
| return digits.join(''); | ||
| }; | ||
| // Setup aliases | ||
| (function() { | ||
| var key, i; | ||
| IntN['isInt'+nBits] = IntN.isIntN; | ||
| for (key in aliases.statics) | ||
| if (aliases.statics.hasOwnProperty(key)) | ||
| for (i=0; i<aliases.statics[key].length; ++i) | ||
| IntN[aliases.statics[key][i]] = IntN[key]; | ||
| for (key in aliases.prototype) | ||
| if (aliases.prototype.hasOwnProperty(key)) | ||
| for (i=0; i<aliases.prototype[key].length; ++i) | ||
| IntN.prototype[aliases.prototype[key][i]] = IntN.prototype[key]; | ||
| })(); | ||
| return classes[nBits] = IntN; | ||
| } // makeIntN | ||
| /** | ||
| * Classes cache. | ||
| * @type {!Object.<number,!Function>} | ||
| * @inner | ||
| */ | ||
| var classes = {}; | ||
| /** | ||
| * Minimum 32bit signed integer value. | ||
| * @type {number} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var int32_min_value = 0x80000000|0; | ||
| /** | ||
| * Maximum 32bit signed integer value. | ||
| * @type {number} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var int32_max_value = 0x7fffffff|0; | ||
| /** | ||
| * Maximum 32bit unsigned integer value. | ||
| * @type {number} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var int32_max_unsigned_value = 0xffffffff>>>0; | ||
| /** | ||
| * Relevant powers (0-7) of 256 for number conversion. | ||
| * @type {!Array.<number>} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var double_256_pwr = [ | ||
| 1, | ||
| 256, | ||
| 65536, | ||
| 16777216, | ||
| 4294967296, | ||
| 1099511627776, | ||
| 281474976710656 | ||
| // >= ^7 is inexact | ||
| ]; | ||
| /** | ||
| * Valid characters for string conversion. | ||
| * @type {string} | ||
| * @const | ||
| * @inner | ||
| */ | ||
| var chars = "0123456789abcdefghijklmnopqrstuvwxyz"; | ||
| /** | ||
| * Alias names of static and prototype methods. | ||
| * @type {!{statics: !Object.<string,!Array.<string>>, prototype: !Object.<string,!Array.<string>>}} | ||
| * @inner | ||
| */ | ||
| var aliases = { | ||
| statics: { | ||
| // General utility | ||
| // 'isIntN': ['isInt'+nBits] // not known yet | ||
| }, | ||
| prototype: { | ||
| // Arithmetic evaluation | ||
| 'compare': ['comp'], | ||
| 'equals': ['eq', 'equal', '=='], | ||
| 'notEquals': ['ne', 'notEqual', '!='], | ||
| 'lessThan': ['lt', 'less', 'lesser', '<'], | ||
| 'lessThanEqual': ['lte', 'lessThanOrEqual', '<='], | ||
| 'greaterThan': ['gt', 'greater', '>'], | ||
| 'greaterThanEqual': ['gte', 'greaterThanOrEqual', '>='], | ||
| // Bitwise operations | ||
| 'not': ['~'], | ||
| 'and': ['&'], | ||
| 'or': ['|'], | ||
| 'xor': ['^'], | ||
| 'shiftLeft': ['lsh', 'leftShift', '<<'], | ||
| 'shiftRight': ['rsh', 'rightShift', '>>'], | ||
| 'shiftRightUnsigned': ['rshu', 'rightShiftUnsigned', '>>>'], | ||
| // Arithmetic operations | ||
| 'add': ['plus', '+'], | ||
| 'negate': ['neg', '!'], | ||
| 'subtract': ['sub', 'minus', '-'], | ||
| 'absolute': ['abs', '||'], | ||
| 'multiply': ['mult', '*'], | ||
| 'divide': ['div', '/'], | ||
| 'modulo': ['mod', '%'] | ||
| } | ||
| }; | ||
| /* CommonJS */ if (typeof module !== 'undefined' && module["exports"]) | ||
| module["exports"] = makeIntN; | ||
| module["exports"] = IntN; | ||
| /* AMD */ else if (typeof define === 'function' && define["amd"]) | ||
| define(function() { return makeIntN; }); | ||
| define(function() { return IntN; }); | ||
| /* Global */ else | ||
| (global["dcodeIO"] = global["dcodeIO"] || {})["IntN"] = makeIntN; | ||
| (global["dcodeIO"] = global["dcodeIO"] || {})["IntN"] = IntN; | ||
| })(this); |
+18
-0
@@ -308,2 +308,20 @@ var IntN = require("../dist/IntN.min.js"), | ||
| }, | ||
| "toInts/fromInts": function(test) { | ||
| var ints = Int32.MAX_VALUE.toInts(); | ||
| test.strictEqual(ints.length, 1); | ||
| test.deepEqual(ints, [0x7fffffff]); | ||
| test.deepEqual(Int32.fromInts(ints), Int32.MAX_VALUE); | ||
| var Int48 = IntN(48); | ||
| ints = Int48.MAX_VALUE.toInts(); | ||
| test.strictEqual(ints.length, 2); | ||
| test.deepEqual(ints, [0xffffffff|0, 0x7fff]); | ||
| test.deepEqual(Int48.fromInts(ints), Int48.MAX_VALUE); | ||
| var Int64 = IntN(64); | ||
| ints = Int64.MAX_VALUE.toInts(); | ||
| test.strictEqual(ints.length, 2); | ||
| test.deepEqual(ints, [0xffffffff|0, 0x7fffffff]); | ||
| test.deepEqual(Int64.fromInts(ints), Int64.MAX_VALUE); | ||
| test.done(); | ||
| }, | ||
@@ -310,0 +328,0 @@ // Number conversion |
Sorry, the diff of this file is not supported yet
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
225053
24.66%19
18.75%3395
39.71%594
3.3%3
50%6
200%