UNPKG

eligendiexercitationem

Version:

Yet another class for arbitrary-precision integers in pure JavaScript. Small. Well tested.

122 lines (115 loc) 3.09 kB
<script src="libs/http___www_cs_students_stanford_edu__tjw_jsbn_.js"></script> <script> function LiteralNode(value) { this.value = value; } LiteralNode.prototype.toString = function () { return this.value; }; LiteralNode.prototype.evaluate = function () { return new BigInteger(this.value, 10); }; function BinaryOperatorNode(operator, a, b) { this.operator = operator; this.a = a; this.b = b; } BinaryOperatorNode.prototype.toString = function () { function precedence(operator) { switch (operator) { case "<=>": return 0; case "+": return 1; case "-": return 1; case "*": return 2; case "/": return 2; case "%": return 2; } throw new Error(); } function fence(e, operator, isStart) { if (isStart) { return precedence(operator) > (e instanceof LiteralNode ? 42 : precedence(e.operator)) ? "(" + e.toString() + ")" : e.toString(); } return precedence(operator) >= (e instanceof LiteralNode ? 42 : precedence(e.operator)) ? "(" + e.toString() + ")" : e.toString(); } return fence(this.a, this.operator, true) + this.operator + fence(this.b, this.operator, false); }; BinaryOperatorNode.prototype.evaluate = function () { var operator = this.operator; var a = this.a.evaluate(); var b = this.b.evaluate(); if (a == null || b == null) { return null; } if (typeof a === "number" || typeof b === "number") { return null; } if (operator === "+") { return a.add(b); } if (operator === "-") { return a.subtract(b); } if (operator === "*") { return a.multiply(b); } if (operator === "/") { if (b.compareTo(BigInteger.ZERO) === 0) { return null; } return a.divide(b); } if (operator === "%") { if (b.compareTo(BigInteger.ZERO) === 0) { return null; } return a.remainder(b); } if (operator === "<=>") { return Math.min(Math.max(a.compareTo(b), -1), +1); } throw new Error(); }; var operators = ["+", "-", "*", "/", "%", "<=>"]; function* generateNode(operatorsCount, possibleOperators, possibleValues) { if (operatorsCount === 0) { for (var value of possibleValues) { yield new LiteralNode(value); } } else { for (var i = 0; i < operatorsCount; i += 1) { for (var a of generateNode(i, possibleOperators, possibleValues)) { for (var b of generateNode(operatorsCount - 1 - i, possibleOperators, possibleValues)) { for (var operator of possibleOperators) { yield new BinaryOperatorNode(operator, a, b); } } } } } }; function generateSomeTests() { var values = [ "0", "1", "2", "3", "9", "67108864", //2**26 "9007199254740992", //2**53 "65536", "4294967296", "18446744073709551616", "10000000" ]; var result = []; for (var node of generateNode(2, operators, values)) { var x = node.evaluate(); if (x != null) { result.push(node.toString() + "=" + x.toString()); } } return result; } console.log(JSON.stringify(generateSomeTests(), null, 2)); </script>