Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // A 0+ integer of unlimited size
- function Int(p) { // Takes a number like 5, a string of numerals like "789", a bignumber.js BigNumber, or another Int
- if (isType(p, "Int")) return p; // Return the given Int instead of making a new one, the value inside an Int can't change
- var o = {};
- o.v = _3type(p); // Parse the given parameter, keeping together v.s() numerals, and v.n() number and v.b() BigNumber once we have them or they are necessary
- o.inside = o.v.inside; // Point to function, see which types v has built up with text like "bns" or "--s" for testing
- o.add = function(q) { return _add(o.v, q); } // Math
- o.subtract = function(q) { return _sub(o.v, q); }
- o.multiply = function(q) { return _mul(o.v, q); }
- o.divide = function(q) { return _div(o.v, q); }
- o.modulo = function(q) { return _mod(o.v, q); }
- o.equals = function(q) { return _equ(o.v, q); }
- o.greaterThan = function(q) { return _gth(o.v, q); }
- o.greaterThanOrEqualTo = function(q) { return _gte(o.v, q); }
- o.lessThan = function(q) { return _lth(o.v, q); }
- o.lessThanOrEqualTo = function(q) { return _lte(o.v, q); }
- o.increment = function() { return _inc(o.v); }
- o.decrement = function() { return _dec(o.v); }
- o.is = function() { return _isp(o.v); }
- o._ = function(c, q) { return _calculate(o.v, c, q); }
- o.text = o.v.s();
- o.hasNumber = function() { return o.v.fit; } // True if our value is small enough to fit in a number as an integer, not a floating point number
- o.toNumber = o.v.n; // Point to function, throws if too big
- o.type = "Int";
- return freeze(o);
- }
- function _3type(p) { // Parse the parameter given to Int or a method on Int, keeping the same integer value in up to 3 different types
- var type = getType(p);
- if (type == "Int") return p.v; // We got an Int, return the value inside instead of making a new one
- // Hold the same integer value 1, 2 or 3 different ways, keeping the type we were given, only converting when necessary, and checking everything we can with the types we have
- var b = "none"; // Our integer value in a BigNumber object, or "none" before we have one
- var n = "none"; // Our integer value in a number type variable, or "none" before we have one, or if our value won't fit
- var s = "none"; // Our integer value as a string of numerals, we always have this type
- if (hasMethod(p, "dividedToIntegerBy")) { b = p; s = b.toFixed(0); checkNumerals(s); } // Given a BigNumber, make and check numerals
- else if (type == "number") { n = p; checkNumberMath(n); s = n+""; checkNumerals(s); checkNumeralsFit(s); } // Given a number, check it, make numerals, and check them
- else if (type == "string") { s = p; checkNumerals(s); } // Given numerals, check them
- else { toss("type"); } // Int(p).method(p) only accepts p as an Int, BigNumber, number, or string
- var o = {}; // Return, or make, check, keep, and return, our value in a BigNumber, number, or string ♫ There's three ways of saying, the very same thing
- o.b = function() { if (b !== "none") return b; b = new platformBigNumber(s); checkSame(s, b.toFixed(0)); return b; } // Make from numerals rather than number to avoid 15 digit limit
- o.n = function() { if (n !== "none") return n; n = numeralsToNumber(s); return n; }
- o.s = function() { return s; }
- o.fit = numeralsFit(s); // Small enough to fit
- o.bs = function() { return b !== "none" ? b : s; } // Our value in a BigNumber if we have one, numerals otherwise
- o.inside = function() { return "###".fill(b === "none" ? "-" : "b", n === "none" ? "-" : "n", s === "none" ? "-" : "s"); } // Show which types we've built up
- return o;
- }
- // Small values use number for speed Potentially large values use BigNumber instead
- function _add(v, q) { var w = _3type(q); return _bothFitProduct(v, w) ? Int(v.n() + w.n()) : Int(v.b().plus( w.bs())); }
- function _sub(v, q) { var w = _3type(q); _checkSubtract(v, w); return _bothFit(v, w) ? Int(v.n() - w.n()) : Int(v.b().minus( w.bs())); }
- function _mul(v, q) { var w = _3type(q); return _bothFitProduct(v, w) ? Int(v.n() * w.n()) : Int(v.b().times( w.bs())); }
- function _div(v, q) { var w = _3type(q); _checkDivide(v, w); return _bothFit(v, w) ? Int(Math.floor(v.n() / w.n())) : Int(v.b().dividedToIntegerBy(w.bs())); }
- function _mod(v, q) { var w = _3type(q); _checkDivide(v, w); return _bothFit(v, w) ? Int(v.n() % w.n()) : Int(v.b().mod( w.bs())); }
- function _equ(v, q) { var w = _3type(q); return _bothFit(v, w) ? v.n() == w.n() : v.b().equals( w.bs()); }
- function _gth(v, q) { var w = _3type(q); return _bothFit(v, w) ? v.n() > w.n() : v.b().greaterThan( w.bs()); }
- function _gte(v, q) { var w = _3type(q); return _bothFit(v, w) ? v.n() >= w.n() : v.b().greaterThanOrEqualTo( w.bs()); }
- function _lth(v, q) { var w = _3type(q); return _bothFit(v, w) ? v.n() < w.n() : v.b().lessThan( w.bs()); }
- function _lte(v, q) { var w = _3type(q); return _bothFit(v, w) ? v.n() <= w.n() : v.b().lessThanOrEqualTo( w.bs()); }
- function _inc(v) { return _add(v, 1); }
- function _dec(v) { return _sub(v, 1); }
- function _isp(v) { return _gth(v, 0); }
- function _checkSubtract(v, w) { if (compareCheckedNumerals(v.s(), w.s()) < 0) toss("bounds"); } // Make sure v - w will be 0+, as negative values aren't allowed
- function _checkDivide(v, w) { if (w.s() == "0") toss("math"); } // Who says you can't divide by zero? OH SHI-
- function _bothFit(v, w) { return v.fit && w.fit; } // True if both values will fit in numbers, so we can use minus, divide, and modulo
- function _bothFitProduct(v, w) { // True if adding or multipling the given two numbers can't produce an answer that's too big
- return _bothFit(v, w) && v.s().length + w.s().length < (Number.MAX_SAFE_INTEGER+"").length; // Even if v and w are all 9s, a*b will still be a digit shorter than max safe integer
- }
- function _calculate(v, c, q) { // Who says JavaScript can't do operator overloading?
- if (c == "+") { return _add(v, q); }
- else if (c == "-") { return _sub(v, q); }
- else if (c == "*") { return _mul(v, q); }
- else if (c == "/") { return _div(v, q); }
- else if (c == "%") { return _mod(v, q); }
- else if (c == "==") { return _equ(v, q); }
- else if (c == ">") { return _gth(v, q); }
- else if (c == ">=") { return _gte(v, q); }
- else if (c == "<") { return _lth(v, q); }
- else if (c == "<=") { return _lte(v, q); }
- else if (c == "++") { return _inc(v); }
- else if (c == "--") { return _dec(v); }
- else if (c == ">0") { return _isp(v); }
- else { toss("code"); }
- }
- exports.Int = Int;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement