diff options
Diffstat (limited to 'ethereal/assets/ext/big.js')
-rw-r--r-- | ethereal/assets/ext/big.js | 380 |
1 files changed, 380 insertions, 0 deletions
diff --git a/ethereal/assets/ext/big.js b/ethereal/assets/ext/big.js new file mode 100644 index 000000000..db633fd2f --- /dev/null +++ b/ethereal/assets/ext/big.js @@ -0,0 +1,380 @@ +var bigInt = (function () { + var base = 10000000, logBase = 7; + var sign = { + positive: false, + negative: true + }; + + var normalize = function (first, second) { + var a = first.value, b = second.value; + var length = a.length > b.length ? a.length : b.length; + for (var i = 0; i < length; i++) { + a[i] = a[i] || 0; + b[i] = b[i] || 0; + } + for (var i = length - 1; i >= 0; i--) { + if (a[i] === 0 && b[i] === 0) { + a.pop(); + b.pop(); + } else break; + } + if (!a.length) a = [0], b = [0]; + first.value = a; + second.value = b; + }; + + var parse = function (text, first) { + if (typeof text === "object") return text; + text += ""; + var s = sign.positive, value = []; + if (text[0] === "-") { + s = sign.negative; + text = text.slice(1); + } + var base = 10; + if (text.slice(0, 2) == "0x") { + base = 16; + text = text.slice(2); + } + else { + var texts = text.split("e"); + if (texts.length > 2) throw new Error("Invalid integer"); + if (texts[1]) { + var exp = texts[1]; + if (exp[0] === "+") exp = exp.slice(1); + exp = parse(exp); + if (exp.lesser(0)) throw new Error("Cannot include negative exponent part for integers"); + while (exp.notEquals(0)) { + texts[0] += "0"; + exp = exp.prev(); + } + } + text = texts[0]; + } + if (text === "-0") text = "0"; + text = text.toUpperCase(); + var isValid = (base == 16 ? /^[0-9A-F]*$/ : /^[0-9]+$/).test(text); + if (!isValid) throw new Error("Invalid integer"); + if (base == 16) { + var val = bigInt(0); + while (text.length) { + v = text.charCodeAt(0) - 48; + if (v > 9) + v -= 7; + text = text.slice(1); + val = val.times(16).plus(v); + } + return val; + } + else { + while (text.length) { + var divider = text.length > logBase ? text.length - logBase : 0; + value.push(+text.slice(divider)); + text = text.slice(0, divider); + } + var val = bigInt(value, s); + if (first) normalize(first, val); + return val; + } + }; + + var goesInto = function (a, b) { + var a = bigInt(a, sign.positive), b = bigInt(b, sign.positive); + if (a.equals(0)) throw new Error("Cannot divide by 0"); + var n = 0; + do { + var inc = 1; + var c = bigInt(a.value, sign.positive), t = c.times(10); + while (t.lesser(b)) { + c = t; + inc *= 10; + t = t.times(10); + } + while (c.lesserOrEquals(b)) { + b = b.minus(c); + n += inc; + } + } while (a.lesserOrEquals(b)); + + return { + remainder: b.value, + result: n + }; + }; + + var bigInt = function (value, s) { + var self = { + value: value, + sign: s + }; + var o = { + value: value, + sign: s, + negate: function (m) { + var first = m || self; + return bigInt(first.value, !first.sign); + }, + abs: function (m) { + var first = m || self; + return bigInt(first.value, sign.positive); + }, + add: function (n, m) { + var s, first = self, second; + if (m) (first = parse(n)) && (second = parse(m)); + else second = parse(n, first); + s = first.sign; + if (first.sign !== second.sign) { + first = bigInt(first.value, sign.positive); + second = bigInt(second.value, sign.positive); + return s === sign.positive ? + o.subtract(first, second) : + o.subtract(second, first); + } + normalize(first, second); + var a = first.value, b = second.value; + var result = [], + carry = 0; + for (var i = 0; i < a.length || carry > 0; i++) { + var sum = (a[i] || 0) + (b[i] || 0) + carry; + carry = sum >= base ? 1 : 0; + sum -= carry * base; + result.push(sum); + } + return bigInt(result, s); + }, + plus: function (n, m) { + return o.add(n, m); + }, + subtract: function (n, m) { + var first = self, second; + if (m) (first = parse(n)) && (second = parse(m)); + else second = parse(n, first); + if (first.sign !== second.sign) return o.add(first, o.negate(second)); + if (first.sign === sign.negative) return o.subtract(o.negate(second), o.negate(first)); + if (o.compare(first, second) === -1) return o.negate(o.subtract(second, first)); + var a = first.value, b = second.value; + var result = [], + borrow = 0; + for (var i = 0; i < a.length; i++) { + var tmp = a[i] - borrow; + borrow = tmp < b[i] ? 1 : 0; + var minuend = (borrow * base) + tmp - b[i]; + result.push(minuend); + } + return bigInt(result, sign.positive); + }, + minus: function (n, m) { + return o.subtract(n, m); + }, + multiply: function (n, m) { + var s, first = self, second; + if (m) (first = parse(n)) && (second = parse(m)); + else second = parse(n, first); + s = first.sign !== second.sign; + var a = first.value, b = second.value; + var resultSum = []; + for (var i = 0; i < a.length; i++) { + resultSum[i] = []; + var j = i; + while (j--) { + resultSum[i].push(0); + } + } + var carry = 0; + for (var i = 0; i < a.length; i++) { + var x = a[i]; + for (var j = 0; j < b.length || carry > 0; j++) { + var y = b[j]; + var product = y ? (x * y) + carry : carry; + carry = product > base ? Math.floor(product / base) : 0; + product -= carry * base; + resultSum[i].push(product); + } + } + var max = -1; + for (var i = 0; i < resultSum.length; i++) { + var len = resultSum[i].length; + if (len > max) max = len; + } + var result = [], carry = 0; + for (var i = 0; i < max || carry > 0; i++) { + var sum = carry; + for (var j = 0; j < resultSum.length; j++) { + sum += resultSum[j][i] || 0; + } + carry = sum > base ? Math.floor(sum / base) : 0; + sum -= carry * base; + result.push(sum); + } + return bigInt(result, s); + }, + times: function (n, m) { + return o.multiply(n, m); + }, + divmod: function (n, m) { + var s, first = self, second; + if (m) (first = parse(n)) && (second = parse(m)); + else second = parse(n, first); + s = first.sign !== second.sign; + if (bigInt(first.value, first.sign).equals(0)) return { + quotient: bigInt([0], sign.positive), + remainder: bigInt([0], sign.positive) + }; + if (second.equals(0)) throw new Error("Cannot divide by zero"); + var a = first.value, b = second.value; + var result = [], remainder = []; + for (var i = a.length - 1; i >= 0; i--) { + var n = [a[i]].concat(remainder); + var quotient = goesInto(b, n); + result.push(quotient.result); + remainder = quotient.remainder; + } + result.reverse(); + return { + quotient: bigInt(result, s), + remainder: bigInt(remainder, first.sign) + }; + }, + divide: function (n, m) { + return o.divmod(n, m).quotient; + }, + over: function (n, m) { + return o.divide(n, m); + }, + mod: function (n, m) { + return o.divmod(n, m).remainder; + }, + pow: function (n, m) { + var first = self, second; + if (m) (first = parse(n)) && (second = parse(m)); + else second = parse(n, first); + var a = first, b = second; + if (b.lesser(0)) return ZERO; + if (b.equals(0)) return ONE; + var result = bigInt(a.value, a.sign); + + if (b.mod(2).equals(0)) { + var c = result.pow(b.over(2)); + return c.times(c); + } else { + return result.times(result.pow(b.minus(1))); + } + }, + next: function (m) { + var first = m || self; + return o.add(first, 1); + }, + prev: function (m) { + var first = m || self; + return o.subtract(first, 1); + }, + compare: function (n, m) { + var first = self, second; + if (m) (first = parse(n)) && (second = parse(m, first)); + else second = parse(n, first); + normalize(first, second); + if (first.value.length === 1 && second.value.length === 1 && first.value[0] === 0 && second.value[0] === 0) return 0; + if (second.sign !== first.sign) return first.sign === sign.positive ? 1 : -1; + var multiplier = first.sign === sign.positive ? 1 : -1; + var a = first.value, b = second.value; + for (var i = a.length - 1; i >= 0; i--) { + if (a[i] > b[i]) return 1 * multiplier; + if (b[i] > a[i]) return -1 * multiplier; + } + return 0; + }, + compareAbs: function (n, m) { + var first = self, second; + if (m) (first = parse(n)) && (second = parse(m, first)); + else second = parse(n, first); + first.sign = second.sign = sign.positive; + return o.compare(first, second); + }, + equals: function (n, m) { + return o.compare(n, m) === 0; + }, + notEquals: function (n, m) { + return !o.equals(n, m); + }, + lesser: function (n, m) { + return o.compare(n, m) < 0; + }, + greater: function (n, m) { + return o.compare(n, m) > 0; + }, + greaterOrEquals: function (n, m) { + return o.compare(n, m) >= 0; + }, + lesserOrEquals: function (n, m) { + return o.compare(n, m) <= 0; + }, + isPositive: function (m) { + var first = m || self; + return first.sign === sign.positive; + }, + isNegative: function (m) { + var first = m || self; + return first.sign === sign.negative; + }, + isEven: function (m) { + var first = m || self; + return first.value[0] % 2 === 0; + }, + isOdd: function (m) { + var first = m || self; + return first.value[0] % 2 === 1; + }, + toString: function (m) { + var first = m || self; + var str = "", len = first.value.length; + while (len--) { + if (first.value[len].toString().length === 8) str += first.value[len]; + else str += (base.toString() + first.value[len]).slice(-logBase); + } + while (str[0] === "0") { + str = str.slice(1); + } + if (!str.length) str = "0"; + var s = (first.sign === sign.positive || str == "0") ? "" : "-"; + return s + str; + }, + toHex: function (m) { + var first = m || self; + var str = ""; + var l = this.abs(); + while (l > 0) { + var qr = l.divmod(256); + var b = qr.remainder.toJSNumber(); + str = (b >> 4).toString(16) + (b & 15).toString(16) + str; + l = qr.quotient; + } + return (this.isNegative() ? "-" : "") + "0x" + str; + }, + toJSNumber: function (m) { + return +o.toString(m); + }, + valueOf: function (m) { + return o.toJSNumber(m); + } + }; + return o; + }; + + var ZERO = bigInt([0], sign.positive); + var ONE = bigInt([1], sign.positive); + var MINUS_ONE = bigInt([1], sign.negative); + + var fnReturn = function (a) { + if (typeof a === "undefined") return ZERO; + return parse(a); + }; + fnReturn.zero = ZERO; + fnReturn.one = ONE; + fnReturn.minusOne = MINUS_ONE; + return fnReturn; +})(); + +if (typeof module !== "undefined") { + module.exports = bigInt; +} + |