diff --git a/js-assembler/runtime-src/js-numbers.js b/js-assembler/runtime-src/js-numbers.js index 0192b47..db8df45 100644 --- a/js-assembler/runtime-src/js-numbers.js +++ b/js-assembler/runtime-src/js-numbers.js @@ -1,4092 +1,90 @@ -// Scheme numbers. - - -var __PLTNUMBERS_TOP__; -if (typeof(exports) !== 'undefined') { - __PLTNUMBERS_TOP__ = exports; -} else { - if (! this['jsnums']) { - this['jsnums'] = {}; - } - __PLTNUMBERS_TOP__ = this['jsnums']; -} - -//var jsnums = {}; - - -// The numeric tower has the following levels: -// integers -// rationals -// floats -// complex numbers -// -// with the representations: -// integers: fixnum or BigInteger [level=0] -// rationals: Rational [level=1] -// floats: FloatPoint [level=2] -// complex numbers: Complex [level=3] - -// We try to stick with the unboxed fixnum representation for -// integers, since that's what scheme programs commonly deal with, and -// we want that common type to be lightweight. - - -// A boxed-scheme-number is either BigInteger, Rational, FloatPoint, or Complex. -// An integer-scheme-number is either fixnum or BigInteger. - - -(function() { - // Abbreviation - var Numbers = __PLTNUMBERS_TOP__; - //var Numbers = jsnums; - - - // makeNumericBinop: (fixnum fixnum -> any) (scheme-number scheme-number -> any) -> (scheme-number scheme-number) X - // Creates a binary function that works either on fixnums or boxnums. - // Applies the appropriate binary function, ensuring that both scheme numbers are - // lifted to the same level. - var makeNumericBinop = function(onFixnums, onBoxednums, options) { - options = options || {}; - return function(x, y) { - if (options.isXSpecialCase && options.isXSpecialCase(x)) - return options.onXSpecialCase(x, y); - if (options.isYSpecialCase && options.isYSpecialCase(y)) - return options.onYSpecialCase(x, y); - - if (typeof(x) === 'number' && - typeof(y) === 'number') { - return onFixnums(x, y); - } - if (typeof(x) === 'number') { - x = liftFixnumInteger(x, y); - } - if (typeof(y) === 'number') { - y = liftFixnumInteger(y, x); - } - - if (x.level < y.level) x = x.liftTo(y); - if (y.level < x.level) y = y.liftTo(x); - return onBoxednums(x, y); - }; - } - - - // fromFixnum: fixnum -> scheme-number - var fromFixnum = function(x) { - if (isNaN(x) || (! isFinite(x))) { - return FloatPoint.makeInstance(x); - } - var nf = Math.floor(x); - if (nf === x) { - if (isOverflow(nf)) { - return makeBignum(expandExponent(x+'')); - } else { - return nf; - } - } else { - return FloatPoint.makeInstance(x); - } - }; - - var expandExponent = function(s) { - var match = s.match(scientificPattern), mantissaChunks, exponent; - if (match) { - mantissaChunks = match[1].match(/^([^.]*)(.*)$/); - exponent = Number(match[2]); - - if (mantissaChunks[2].length === 0) { - return mantissaChunks[1] + zfill(exponent); - } - - if (exponent >= mantissaChunks[2].length - 1) { - return (mantissaChunks[1] + - mantissaChunks[2].substring(1) + - zfill(exponent - (mantissaChunks[2].length - 1))); - } else { - return (mantissaChunks[1] + - mantissaChunks[2].substring(1, 1+exponent)); - } - } else { - return s; - } - }; - - // zfill: integer -> string - // builds a string of "0"'s of length n. - var zfill = function(n) { - var buffer = []; - buffer.length = n; - for (var i = 0; i < n; i++) { - buffer[i] = '0'; - } - return buffer.join(''); - }; - - - - // liftFixnumInteger: fixnum-integer boxed-scheme-number -> boxed-scheme-number - // Lifts up fixnum integers to a boxed type. - var liftFixnumInteger = function(x, other) { - switch(other.level) { - case 0: // BigInteger - return makeBignum(x); - case 1: // Rational - return new Rational(x, 1); - case 2: // FloatPoint - return new FloatPoint(x); - case 3: // Complex - return new Complex(x, 0); - default: - throwRuntimeError("IMPOSSIBLE: cannot lift fixnum integer to " + other.toString(), x, other); - } - }; - - - // throwRuntimeError: string (scheme-number | undefined) (scheme-number | undefined) -> void - // Throws a runtime error with the given message string. - var throwRuntimeError = function(msg, x, y) { - Numbers['onThrowRuntimeError'](msg, x, y); - }; - - - - // onThrowRuntimeError: string (scheme-number | undefined) (scheme-number | undefined) -> void - // By default, will throw a new Error with the given message. - // Override Numbers['onThrowRuntimeError'] if you need to do something special. - var onThrowRuntimeError = function(msg, x, y) { - throw new Error(msg); - }; - - - // isSchemeNumber: any -> boolean - // Returns true if the thing is a scheme number. - var isSchemeNumber = function(thing) { - return (typeof(thing) === 'number' - || (thing instanceof Rational || - thing instanceof FloatPoint || - thing instanceof Complex || - thing instanceof BigInteger)); - }; - - - // isRational: scheme-number -> boolean - var isRational = function(n) { - return (typeof(n) === 'number' || - (isSchemeNumber(n) && n.isRational())); - }; - - // isReal: scheme-number -> boolean - var isReal = function(n) { - return (typeof(n) === 'number' || - (isSchemeNumber(n) && n.isReal())); - }; - - // isExact: scheme-number -> boolean - var isExact = function(n) { - return (typeof(n) === 'number' || - (isSchemeNumber(n) && n.isExact())); - }; - - // isExact: scheme-number -> boolean - var isInexact = function(n) { - if (typeof(n) === 'number') { - return false; - } else { - return (isSchemeNumber(n) && n.isInexact()); - } - }; - - // isInteger: scheme-number -> boolean - var isInteger = function(n) { - return (typeof(n) === 'number' || - (isSchemeNumber(n) && n.isInteger())); - }; - - // isExactInteger: scheme-number -> boolean - var isExactInteger = function(n) { - return (typeof(n) === 'number' || - (isSchemeNumber(n) && - n.isInteger() && - n.isExact())); - } - - - - // toFixnum: scheme-number -> javascript-number - var toFixnum = function(n) { - if (typeof(n) === 'number') - return n; - return n.toFixnum(); - }; - - // toExact: scheme-number -> scheme-number - var toExact = function(n) { - if (typeof(n) === 'number') - return n; - return n.toExact(); - }; - - - // toExact: scheme-number -> scheme-number - var toInexact = function(n) { - if (typeof(n) === 'number') - return FloatPoint.makeInstance(n); - return n.toInexact(); - }; - - - - ////////////////////////////////////////////////////////////////////// - - - // add: scheme-number scheme-number -> scheme-number - var add = makeNumericBinop( - function(x, y) { - var sum = x + y; - if (isOverflow(sum)) { - return (makeBignum(x)).add(makeBignum(y)); - } else { - return sum; - } - }, - function(x, y) { - return x.add(y); - }, - {isXSpecialCase: function(x) { - return isExactInteger(x) && _integerIsZero(x) }, - onXSpecialCase: function(x, y) { return y; }, - isYSpecialCase: function(y) { - return isExactInteger(y) && _integerIsZero(y) }, - onYSpecialCase: function(x, y) { return x; } - }); - - - // subtract: scheme-number scheme-number -> scheme-number - var subtract = makeNumericBinop( - function(x, y) { - var diff = x - y; - if (isOverflow(diff)) { - return (makeBignum(x)).subtract(makeBignum(y)); - } else { - return diff; - } - }, - function(x, y) { - return x.subtract(y); - }, - {isXSpecialCase: function(x) { - return isExactInteger(x) && _integerIsZero(x) }, - onXSpecialCase: function(x, y) { return negate(y); }, - isYSpecialCase: function(y) { - return isExactInteger(y) && _integerIsZero(y) }, - onYSpecialCase: function(x, y) { return x; } - }); - - - // mulitply: scheme-number scheme-number -> scheme-number - var multiply = makeNumericBinop( - function(x, y) { - var prod = x * y; - if (isOverflow(prod)) { - return (makeBignum(x)).multiply(makeBignum(y)); - } else { - return prod; - } - }, - function(x, y) { - return x.multiply(y); - }, - {isXSpecialCase: function(x) { - return (isExactInteger(x) && - (_integerIsZero(x) || _integerIsOne(x) || _integerIsNegativeOne(x))) }, - onXSpecialCase: function(x, y) { - if (_integerIsZero(x)) - return 0; - if (_integerIsOne(x)) - return y; - if (_integerIsNegativeOne(x)) - return negate(y); - }, - isYSpecialCase: function(y) { - return (isExactInteger(y) && - (_integerIsZero(y) || _integerIsOne(y) || _integerIsNegativeOne(y)))}, - onYSpecialCase: function(x, y) { - if (_integerIsZero(y)) - return 0; - if (_integerIsOne(y)) - return x; - if (_integerIsNegativeOne(y)) - return negate(x); - } - }); - - - // divide: scheme-number scheme-number -> scheme-number - var divide = makeNumericBinop( - function(x, y) { - if (_integerIsZero(y)) - throwRuntimeError("/: division by zero", x, y); - var div = x / y; - if (isOverflow(div)) { - return (makeBignum(x)).divide(makeBignum(y)); - } else if (Math.floor(div) !== div) { - return Rational.makeInstance(x, y); - } else { - return div; - } - }, - function(x, y) { - return x.divide(y); - }, - { isXSpecialCase: function(x) { - return (eqv(x, 0)); - }, - onXSpecialCase: function(x, y) { - if (eqv(y, 0)) { - throwRuntimeError("/: division by zero", x, y); - } - return 0; - }, - isYSpecialCase: function(y) { - return (eqv(y, 0)); }, - onYSpecialCase: function(x, y) { - throwRuntimeError("/: division by zero", x, y); - } - }); - - - // equals: scheme-number scheme-number -> boolean - var equals = makeNumericBinop( - function(x, y) { - return x === y; - }, - function(x, y) { - return x.equals(y); - }); - - - // eqv: scheme-number scheme-number -> boolean - var eqv = function(x, y) { - if (x === y) - return true; - if (typeof(x) === 'number' && typeof(y) === 'number') - return x === y; - if (x === NEGATIVE_ZERO || y === NEGATIVE_ZERO) - return x === y; - if (x instanceof Complex || y instanceof Complex) { - return (eqv(realPart(x), realPart(y)) && - eqv(imaginaryPart(x), imaginaryPart(y))); - } - var ex = isExact(x), ey = isExact(y); - return (((ex && ey) || (!ex && !ey)) && equals(x, y)); - }; - - // approxEqual: scheme-number scheme-number scheme-number -> boolean - var approxEquals = function(x, y, delta) { - return lessThan(abs(subtract(x, y)), - delta); - }; - - // greaterThanOrEqual: scheme-number scheme-number -> boolean - var greaterThanOrEqual = makeNumericBinop( - function(x, y) { - return x >= y; - }, - function(x, y) { - if (!(isReal(x) && isReal(y))) - throwRuntimeError( - ">=: couldn't be applied to complex number", x, y); - return x.greaterThanOrEqual(y); - }); - - - // lessThanOrEqual: scheme-number scheme-number -> boolean - var lessThanOrEqual = makeNumericBinop( - function(x, y){ - - return x <= y; - }, - function(x, y) { - if (!(isReal(x) && isReal(y))) - throwRuntimeError("<=: couldn't be applied to complex number", x, y); - return x.lessThanOrEqual(y); - }); - - - // greaterThan: scheme-number scheme-number -> boolean - var greaterThan = makeNumericBinop( - function(x, y){ - return x > y; - }, - function(x, y) { - if (!(isReal(x) && isReal(y))) - throwRuntimeError(">: couldn't be applied to complex number", x, y); - return x.greaterThan(y); - }); - - - // lessThan: scheme-number scheme-number -> boolean - var lessThan = makeNumericBinop( - function(x, y){ - - return x < y; - }, - function(x, y) { - if (!(isReal(x) && isReal(y))) - throwRuntimeError("<: couldn't be applied to complex number", x, y); - return x.lessThan(y); - }); - - - - // expt: scheme-number scheme-number -> scheme-number - var expt = (function() { - var _expt = makeNumericBinop( - function(x, y){ - var pow = Math.pow(x, y); - if (isOverflow(pow)) { - return (makeBignum(x)).expt(makeBignum(y)); - } else { - return pow; - } - }, - function(x, y) { - if (equals(y, 0)) { - return add(y, 1); - } else { - return x.expt(y); - } - }); - return function(x, y) { - if (equals(y, 0)) - return add(y, 1); - if (isReal(y) && lessThan(y, 0)) { - return _expt(divide(1, x), negate(y)); - } - return _expt(x, y); - }; - })(); - - - // exp: scheme-number -> scheme-number - var exp = function(n) { - if ( eqv(n, 0) ) { - return 1; - } - if (typeof(n) === 'number') { - return FloatPoint.makeInstance(Math.exp(n)); - } - return n.exp(); - }; - - - // modulo: scheme-number scheme-number -> scheme-number - var modulo = function(m, n) { - if (! isInteger(m)) { - throwRuntimeError('modulo: the first argument ' - + m + " is not an integer.", m, n); - } - if (! isInteger(n)) { - throwRuntimeError('modulo: the second argument ' - + n + " is not an integer.", m, n); - } - var result; - if (typeof(m) === 'number') { - result = m % n; - if (n < 0) { - if (result <= 0) - return result; - else - return result + n; - } else { - if (result < 0) - return result + n; - else - return result; - } - } - result = _integerModulo(floor(m), floor(n)); - // The sign of the result should match the sign of n. - if (lessThan(n, 0)) { - if (lessThanOrEqual(result, 0)) { - return result; - } - return add(result, n); - - } else { - if (lessThan(result, 0)) { - return add(result, n); - } - return result; - } - }; - - - - // numerator: scheme-number -> scheme-number - var numerator = function(n) { - if (typeof(n) === 'number') - return n; - return n.numerator(); - }; - - - // denominator: scheme-number -> scheme-number - var denominator = function(n) { - if (typeof(n) === 'number') - return 1; - return n.denominator(); - }; - - // sqrt: scheme-number -> scheme-number - var sqrt = function(n) { - if (typeof(n) === 'number') { - if (n >= 0) { - var result = Math.sqrt(n); - if (Math.floor(result) === result) { - return result; - } else { - return FloatPoint.makeInstance(result); - } - } else { - return (Complex.makeInstance(0, sqrt(-n))); - } - } - return n.sqrt(); - }; - - // abs: scheme-number -> scheme-number - var abs = function(n) { - if (typeof(n) === 'number') { - return Math.abs(n); - } - return n.abs(); - }; - - // floor: scheme-number -> scheme-number - var floor = function(n) { - if (typeof(n) === 'number') - return n; - return n.floor(); - }; - - // ceiling: scheme-number -> scheme-number - var ceiling = function(n) { - if (typeof(n) === 'number') - return n; - return n.ceiling(); - }; - - // conjugate: scheme-number -> scheme-number - var conjugate = function(n) { - if (typeof(n) === 'number') - return n; - return n.conjugate(); - }; - - // magnitude: scheme-number -> scheme-number - var magnitude = function(n) { - if (typeof(n) === 'number') - return Math.abs(n); - return n.magnitude(); - }; - - - // log: scheme-number -> scheme-number - var log = function(n) { - if ( eqv(n, 1) ) { - return 0; - } - if (typeof(n) === 'number') { - return FloatPoint.makeInstance(Math.log(n)); - } - return n.log(); - }; - - // angle: scheme-number -> scheme-number - var angle = function(n) { - if (typeof(n) === 'number') { - if (n > 0) - return 0; - else - return FloatPoint.pi; - } - return n.angle(); - }; - - // tan: scheme-number -> scheme-number - var tan = function(n) { - if (eqv(n, 0)) { return 0; } - if (typeof(n) === 'number') { - return FloatPoint.makeInstance(Math.tan(n)); - } - return n.tan(); - }; - - // atan: scheme-number -> scheme-number - var atan = function(n) { - if (eqv(n, 0)) { return 0; } - if (typeof(n) === 'number') { - return FloatPoint.makeInstance(Math.atan(n)); - } - return n.atan(); - }; - - // cos: scheme-number -> scheme-number - var cos = function(n) { - if (eqv(n, 0)) { return 1; } - if (typeof(n) === 'number') { - return FloatPoint.makeInstance(Math.cos(n)); - } - return n.cos(); - }; - - // sin: scheme-number -> scheme-number - var sin = function(n) { - if (eqv(n, 0)) { return 0; } - if (typeof(n) === 'number') { - return FloatPoint.makeInstance(Math.sin(n)); - } - return n.sin(); - }; - - // acos: scheme-number -> scheme-number - var acos = function(n) { - if (eqv(n, 1)) { return 0; } - if (typeof(n) === 'number') { - return FloatPoint.makeInstance(Math.acos(n)); - } - return n.acos(); - }; - - // asin: scheme-number -> scheme-number - var asin = function(n) { - if (eqv(n, 0)) { return 0; } - if (typeof(n) === 'number') { - return FloatPoint.makeInstance(Math.asin(n)); - } - return n.asin(); - }; - - // imaginaryPart: scheme-number -> scheme-number - var imaginaryPart = function(n) { - if (typeof(n) === 'number') { - return 0; - } - return n.imaginaryPart(); - }; - - // realPart: scheme-number -> scheme-number - var realPart = function(n) { - if (typeof(n) === 'number') { - return n; - } - return n.realPart(); - }; - - // round: scheme-number -> scheme-number - var round = function(n) { - if (typeof(n) === 'number') { - return n; - } - return n.round(); - }; - - - - // sqr: scheme-number -> scheme-number - var sqr = function(x) { - return multiply(x, x); - }; - - - // integerSqrt: scheme-number -> scheme-number - var integerSqrt = function(x) { - if (! isInteger(x)) { - throwRuntimeError('integer-sqrt: the argument ' + x.toString() + - " is not an integer.", x); - } - if (typeof (x) === 'number') { - if(x < 0) { - return Complex.makeInstance(0, - Math.floor(Math.sqrt(-x))) - } else { - return Math.floor(Math.sqrt(x)); - } - } - return x.integerSqrt(); - }; - - - // gcd: scheme-number [scheme-number ...] -> scheme-number - var gcd = function(first, rest) { - if (! isInteger(first)) { - throwRuntimeError('gcd: the argument ' + first.toString() + - " is not an integer.", first); - } - var a = abs(first), t, b; - for(var i = 0; i < rest.length; i++) { - b = abs(rest[i]); - if (! isInteger(b)) { - throwRuntimeError('gcd: the argument ' + b.toString() + - " is not an integer.", b); - } - while (! _integerIsZero(b)) { - t = a; - a = b; - b = _integerModulo(t, b); - } - } - return a; - }; - - // lcm: scheme-number [scheme-number ...] -> scheme-number - var lcm = function(first, rest) { - if (! isInteger(first)) { - throwRuntimeError('lcm: the argument ' + first.toString() + - " is not an integer.", first); - } - var result = abs(first); - if (_integerIsZero(result)) { return 0; } - for (var i = 0; i < rest.length; i++) { - if (! isInteger(rest[i])) { - throwRuntimeError('lcm: the argument ' + rest[i].toString() + - " is not an integer.", rest[i]); - } - var divisor = _integerGcd(result, rest[i]); - if (_integerIsZero(divisor)) { - return 0; - } - result = divide(multiply(result, rest[i]), divisor); - } - return result; - }; - - - var quotient = function(x, y) { - if (! isInteger(x)) { - throwRuntimeError('quotient: the first argument ' + x.toString() + - " is not an integer.", x); - } - if (! isInteger(y)) { - throwRuntimeError('quotient: the second argument ' + y.toString() + - " is not an integer.", y); - } - return _integerQuotient(x, y); - }; - - - var remainder = function(x, y) { - if (! isInteger(x)) { - throwRuntimeError('remainder: the first argument ' + x.toString() + - " is not an integer.", x); - } - if (! isInteger(y)) { - throwRuntimeError('remainder: the second argument ' + y.toString() + - " is not an integer.", y); - } - return _integerRemainder(x, y); - }; - - - // Implementation of the hyperbolic functions - // http://en.wikipedia.org/wiki/Hyperbolic_cosine - var cosh = function(x) { - if (eqv(x, 0)) { - return FloatPoint.makeInstance(1.0); - } - return divide(add(exp(x), exp(negate(x))), - 2); - }; - - var sinh = function(x) { - return divide(subtract(exp(x), exp(negate(x))), - 2); - }; - - - - var makeComplexPolar = function(r, theta) { - // special case: if theta is zero, just return - // the scalar. - if (eqv(theta, 0)) { - return r; - } - return Complex.makeInstance(multiply(r, cos(theta)), - multiply(r, sin(theta))); - }; - - - - ////////////////////////////////////////////////////////////////////// - - // Helpers - - - // IsFinite: scheme-number -> boolean - // Returns true if the scheme number is finite or not. - var isSchemeNumberFinite = function(n) { - if (typeof(n) === 'number') { - return isFinite(n); - } else { - return n.isFinite(); - } - }; - - // isOverflow: javascript-number -> boolean - // Returns true if we consider the number an overflow. - var MIN_FIXNUM = -(9e15); - var MAX_FIXNUM = (9e15); - var isOverflow = function(n) { - return (n < MIN_FIXNUM || MAX_FIXNUM < n); - }; - - - // negate: scheme-number -> scheme-number - // multiplies a number times -1. - var negate = function(n) { - if (typeof(n) === 'number') { - return -n; - } - return n.negate(); - }; - - - // halve: scheme-number -> scheme-number - // Divide a number by 2. - var halve = function(n) { - return divide(n, 2); - }; - - - // timesI: scheme-number scheme-number - // multiplies a number times i. - var timesI = function(x) { - return multiply(x, plusI); - }; - - - // fastExpt: computes n^k by squaring. - // n^k = (n^2)^(k/2) - // Assumes k is non-negative integer. - var fastExpt = function(n, k) { - var acc = 1; - while (true) { - if (_integerIsZero(k)) { - return acc; - } - if (equals(modulo(k, 2), 0)) { - n = multiply(n, n); - k = divide(k, 2); - } else { - acc = multiply(acc, n); - k = subtract(k, 1); - } - } - }; - - - - ////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - - - // Integer operations - // Integers are either represented as fixnums or as BigIntegers. - - // makeIntegerBinop: (fixnum fixnum -> X) (BigInteger BigInteger -> X) -> X - // Helper to collect the common logic for coersing integer fixnums or bignums to a - // common type before doing an operation. - var makeIntegerBinop = function(onFixnums, onBignums, options) { - options = options || {}; - return (function(m, n) { - if (m instanceof Rational) { - m = numerator(m); - } else if (m instanceof Complex) { - m = realPart(m); - } - - if (n instanceof Rational) { - n = numerator(n); - }else if (n instanceof Complex) { - n = realPart(n); - } - - if (typeof(m) === 'number' && typeof(n) === 'number') { - var result = onFixnums(m, n); - if (! isOverflow(result) || - (options.ignoreOverflow)) { - return result; - } - } - if (m instanceof FloatPoint || n instanceof FloatPoint) { - if (options.doNotCoerseToFloating) { - return onFixnums(toFixnum(m), toFixnum(n)); - } - else { - return FloatPoint.makeInstance( - onFixnums(toFixnum(m), toFixnum(n))); - } - } - if (typeof(m) === 'number') { - m = makeBignum(m); - } - if (typeof(n) === 'number') { - n = makeBignum(n); - } - return onBignums(m, n); - }); - }; - - - var makeIntegerUnOp = function(onFixnums, onBignums, options) { - options = options || {}; - return (function(m) { - if (m instanceof Rational) { - m = numerator(m); - } else if (m instanceof Complex) { - m = realPart(m); - } - - if (typeof(m) === 'number') { - var result = onFixnums(m); - if (! isOverflow(result) || - (options.ignoreOverflow)) { - return result; - } - } - if (m instanceof FloatPoint) { - return onFixnums(toFixnum(m)); - } - if (typeof(m) === 'number') { - m = makeBignum(m); - } - return onBignums(m); - }); - }; - - - - // _integerModulo: integer-scheme-number integer-scheme-number -> integer-scheme-number - var _integerModulo = makeIntegerBinop( - function(m, n) { - return m % n; - }, - function(m, n) { - return bnMod.call(m, n); - }); - - - // _integerGcd: integer-scheme-number integer-scheme-number -> integer-scheme-number - var _integerGcd = makeIntegerBinop( - function(a, b) { - var t; - while (b !== 0) { - t = a; - a = b; - b = t % b; - } - return a; - }, - function(m, n) { - return bnGCD.call(m, n); - }); - - - // _integerIsZero: integer-scheme-number -> boolean - // Returns true if the number is zero. - var _integerIsZero = makeIntegerUnOp( - function(n){ - return n === 0; - }, - function(n) { - return bnEquals.call(n, BigInteger.ZERO); - } - ); - - - // _integerIsOne: integer-scheme-number -> boolean - var _integerIsOne = makeIntegerUnOp( - function(n) { - return n === 1; - }, - function(n) { - return bnEquals.call(n, BigInteger.ONE); - }); - - - - // _integerIsNegativeOne: integer-scheme-number -> boolean - var _integerIsNegativeOne = makeIntegerUnOp( - function(n) { - return n === -1; - }, - function(n) { - return bnEquals.call(n, BigInteger.NEGATIVE_ONE); - }); - - - - // _integerAdd: integer-scheme-number integer-scheme-number -> integer-scheme-number - var _integerAdd = makeIntegerBinop( - function(m, n) { - return m + n; - }, - function(m, n) { - return bnAdd.call(m, n); - }); - - // _integerSubtract: integer-scheme-number integer-scheme-number -> integer-scheme-number - var _integerSubtract = makeIntegerBinop( - function(m, n) { - return m - n; - }, - function(m, n) { - return bnSubtract.call(m, n); - }); - - // _integerMultiply: integer-scheme-number integer-scheme-number -> integer-scheme-number - var _integerMultiply = makeIntegerBinop( - function(m, n) { - return m * n; - }, - function(m, n) { - return bnMultiply.call(m, n); - }); - - //_integerQuotient: integer-scheme-number integer-scheme-number -> integer-scheme-number - var _integerQuotient = makeIntegerBinop( - function(m, n) { - return ((m - (m % n))/ n); - }, - function(m, n) { - return bnDivide.call(m, n); - }); - - var _integerRemainder = makeIntegerBinop( - function(m, n) { - return m % n; - }, - function(m, n) { - return bnRemainder.call(m, n); - }); - - - // _integerDivideToFixnum: integer-scheme-number integer-scheme-number -> fixnum - var _integerDivideToFixnum = makeIntegerBinop( - function(m, n) { - return m / n; - }, - function(m, n) { - return toFixnum(m) / toFixnum(n); - }, - {ignoreOverflow: true, - doNotCoerseToFloating: true}); - - - // _integerEquals: integer-scheme-number integer-scheme-number -> boolean - var _integerEquals = makeIntegerBinop( - function(m, n) { - return m === n; - }, - function(m, n) { - return bnEquals.call(m, n); - }, - {doNotCoerseToFloating: true}); - - // _integerGreaterThan: integer-scheme-number integer-scheme-number -> boolean - var _integerGreaterThan = makeIntegerBinop( - function(m, n) { - return m > n; - }, - function(m, n) { - return bnCompareTo.call(m, n) > 0; - }, - {doNotCoerseToFloating: true}); - - // _integerLessThan: integer-scheme-number integer-scheme-number -> boolean - var _integerLessThan = makeIntegerBinop( - function(m, n) { - return m < n; - }, - function(m, n) { - return bnCompareTo.call(m, n) < 0; - }, - {doNotCoerseToFloating: true}); - - // _integerGreaterThanOrEqual: integer-scheme-number integer-scheme-number -> boolean - var _integerGreaterThanOrEqual = makeIntegerBinop( - function(m, n) { - return m >= n; - }, - function(m, n) { - return bnCompareTo.call(m, n) >= 0; - }, - {doNotCoerseToFloating: true}); - - // _integerLessThanOrEqual: integer-scheme-number integer-scheme-number -> boolean - var _integerLessThanOrEqual = makeIntegerBinop( - function(m, n) { - return m <= n; - }, - function(m, n) { - return bnCompareTo.call(m, n) <= 0; - }, - {doNotCoerseToFloating: true}); - - - - ////////////////////////////////////////////////////////////////////// - // The boxed number types are expected to implement the following - // interface. - // - // toString: -> string - - // level: number - - // liftTo: scheme-number -> scheme-number - - // isFinite: -> boolean - - // isInteger: -> boolean - // Produce true if this number can be coersed into an integer. - - // isRational: -> boolean - // Produce true if the number is rational. - - // isReal: -> boolean - // Produce true if the number is real. - - // isExact: -> boolean - // Produce true if the number is exact - - // toExact: -> scheme-number - // Produce an exact number. - - // toFixnum: -> javascript-number - // Produce a javascript number. - - // greaterThan: scheme-number -> boolean - // Compare against instance of the same type. - - // greaterThanOrEqual: scheme-number -> boolean - // Compare against instance of the same type. - - // lessThan: scheme-number -> boolean - // Compare against instance of the same type. - - // lessThanOrEqual: scheme-number -> boolean - // Compare against instance of the same type. - - // add: scheme-number -> scheme-number - // Add with an instance of the same type. - - // subtract: scheme-number -> scheme-number - // Subtract with an instance of the same type. - - // multiply: scheme-number -> scheme-number - // Multiply with an instance of the same type. - - // divide: scheme-number -> scheme-number - // Divide with an instance of the same type. - - // numerator: -> scheme-number - // Return the numerator. - - // denominator: -> scheme-number - // Return the denominator. - - // integerSqrt: -> scheme-number - // Produce the integer square root. - - // sqrt: -> scheme-number - // Produce the square root. - - // abs: -> scheme-number - // Produce the absolute value. - - // floor: -> scheme-number - // Produce the floor. - - // ceiling: -> scheme-number - // Produce the ceiling. - - // conjugate: -> scheme-number - // Produce the conjugate. - - // magnitude: -> scheme-number - // Produce the magnitude. - - // log: -> scheme-number - // Produce the log. - - // angle: -> scheme-number - // Produce the angle. - - // atan: -> scheme-number - // Produce the arc tangent. - - // cos: -> scheme-number - // Produce the cosine. - - // sin: -> scheme-number - // Produce the sine. - - // expt: scheme-number -> scheme-number - // Produce the power to the input. - - // exp: -> scheme-number - // Produce e raised to the given power. - - // acos: -> scheme-number - // Produce the arc cosine. - - // asin: -> scheme-number - // Produce the arc sine. - - // imaginaryPart: -> scheme-number - // Produce the imaginary part - - // realPart: -> scheme-number - // Produce the real part. - - // round: -> scheme-number - // Round to the nearest integer. - - // equals: scheme-number -> boolean - // Produce true if the given number of the same type is equal. - - - - ////////////////////////////////////////////////////////////////////// - - // Rationals - - - var Rational = function(n, d) { - this.n = n; - this.d = d; - }; - - - Rational.prototype.toString = function() { - if (_integerIsOne(this.d)) { - return this.n.toString() + ""; - } else { - return this.n.toString() + "/" + this.d.toString(); - } - }; - - - Rational.prototype.level = 1; - - - Rational.prototype.liftTo = function(target) { - if (target.level === 2) - return new FloatPoint( - _integerDivideToFixnum(this.n, this.d)); - if (target.level === 3) - return new Complex(this, 0); - return throwRuntimeError("invalid level of Number", this, target); - }; - - Rational.prototype.isFinite = function() { - return true; - }; - - Rational.prototype.equals = function(other) { - return (other instanceof Rational && - _integerEquals(this.n, other.n) && - _integerEquals(this.d, other.d)); - }; - - - - Rational.prototype.isInteger = function() { - return _integerIsOne(this.d); - }; - - Rational.prototype.isRational = function() { - return true; - }; - - Rational.prototype.isReal = function() { - return true; - }; - - - Rational.prototype.add = function(other) { - return Rational.makeInstance(_integerAdd(_integerMultiply(this.n, other.d), - _integerMultiply(this.d, other.n)), - _integerMultiply(this.d, other.d)); - }; - - Rational.prototype.subtract = function(other) { - return Rational.makeInstance(_integerSubtract(_integerMultiply(this.n, other.d), - _integerMultiply(this.d, other.n)), - _integerMultiply(this.d, other.d)); - }; - - Rational.prototype.negate = function() { - return Rational.makeInstance(-this.n, this.d) - }; - - Rational.prototype.multiply = function(other) { - return Rational.makeInstance(_integerMultiply(this.n, other.n), - _integerMultiply(this.d, other.d)); - }; - - Rational.prototype.divide = function(other) { - if (_integerIsZero(this.d) || _integerIsZero(other.n)) { - throwRuntimeError("/: division by zero", this, other); - } - return Rational.makeInstance(_integerMultiply(this.n, other.d), - _integerMultiply(this.d, other.n)); - }; - - - Rational.prototype.toExact = function() { - return this; - }; - - Rational.prototype.toInexact = function() { - return FloatPoint.makeInstance(this.toFixnum()); - }; - - - Rational.prototype.isExact = function() { - return true; - }; - - Rational.prototype.isInexact = function() { - return false; - }; - - - Rational.prototype.toFixnum = function() { - return _integerDivideToFixnum(this.n, this.d); - }; - - Rational.prototype.numerator = function() { - return this.n; - }; - - Rational.prototype.denominator = function() { - return this.d; - }; - - Rational.prototype.greaterThan = function(other) { - return _integerGreaterThan(_integerMultiply(this.n, other.d), - _integerMultiply(this.d, other.n)); - }; - - Rational.prototype.greaterThanOrEqual = function(other) { - return _integerGreaterThanOrEqual(_integerMultiply(this.n, other.d), - _integerMultiply(this.d, other.n)); - }; - - Rational.prototype.lessThan = function(other) { - return _integerLessThan(_integerMultiply(this.n, other.d), - _integerMultiply(this.d, other.n)); - }; - - Rational.prototype.lessThanOrEqual = function(other) { - return _integerLessThanOrEqual(_integerMultiply(this.n, other.d), - _integerMultiply(this.d, other.n)); - }; - - Rational.prototype.integerSqrt = function() { - var result = sqrt(this); - if (isRational(result)) { - return toExact(floor(result)); - } else if (isReal(result)) { - return toExact(floor(result)); - } else { - return Complex.makeInstance(toExact(floor(realPart(result))), - toExact(floor(imaginaryPart(result)))); - } - }; - - - Rational.prototype.sqrt = function() { - if (_integerGreaterThanOrEqual(this.n, 0)) { - var newN = sqrt(this.n); - var newD = sqrt(this.d); - if (equals(floor(newN), newN) && - equals(floor(newD), newD)) { - return Rational.makeInstance(newN, newD); - } else { - return FloatPoint.makeInstance(_integerDivideToFixnum(newN, newD)); - } - } else { - var newN = sqrt(negate(this.n)); - var newD = sqrt(this.d); - if (equals(floor(newN), newN) && - equals(floor(newD), newD)) { - return Complex.makeInstance( - 0, - Rational.makeInstance(newN, newD)); - } else { - return Complex.makeInstance( - 0, - FloatPoint.makeInstance(_integerDivideToFixnum(newN, newD))); - } - } - }; - - Rational.prototype.abs = function() { - return Rational.makeInstance(abs(this.n), - this.d); - }; - - - Rational.prototype.floor = function() { - var quotient = _integerQuotient(this.n, this.d); - if (_integerLessThan(this.n, 0)) { - return subtract(quotient, 1); - } else { - return quotient; - } - }; - - - Rational.prototype.ceiling = function() { - var quotient = _integerQuotient(this.n, this.d); - if (_integerLessThan(this.n, 0)) { - return quotient; - } else { - return add(quotient, 1); - } - }; - - Rational.prototype.conjugate = function() { - return this; - }; - - Rational.prototype.magnitude = Rational.prototype.abs; - - Rational.prototype.log = function(){ - return FloatPoint.makeInstance(Math.log(this.n / this.d)); - }; - - Rational.prototype.angle = function(){ - if (_integerIsZero(this.n)) - return 0; - if (_integerGreaterThan(this.n, 0)) - return 0; - else - return FloatPoint.pi; - }; - - Rational.prototype.tan = function(){ - return FloatPoint.makeInstance(Math.tan(_integerDivideToFixnum(this.n, this.d))); - }; - - Rational.prototype.atan = function(){ - return FloatPoint.makeInstance(Math.atan(_integerDivideToFixnum(this.n, this.d))); - }; - - Rational.prototype.cos = function(){ - return FloatPoint.makeInstance(Math.cos(_integerDivideToFixnum(this.n, this.d))); - }; - - Rational.prototype.sin = function(){ - return FloatPoint.makeInstance(Math.sin(_integerDivideToFixnum(this.n, this.d))); - }; - - Rational.prototype.expt = function(a){ - if (isExactInteger(a) && greaterThanOrEqual(a, 0)) { - return fastExpt(this, a); - } - return FloatPoint.makeInstance(Math.pow(_integerDivideToFixnum(this.n, this.d), - _integerDivideToFixnum(a.n, a.d))); - }; - - Rational.prototype.exp = function(){ - return FloatPoint.makeInstance(Math.exp(_integerDivideToFixnum(this.n, this.d))); - }; - - Rational.prototype.acos = function(){ - return FloatPoint.makeInstance(Math.acos(_integerDivideToFixnum(this.n, this.d))); - }; - - Rational.prototype.asin = function(){ - return FloatPoint.makeInstance(Math.asin(_integerDivideToFixnum(this.n, this.d))); - }; - - Rational.prototype.imaginaryPart = function(){ - return 0; - }; - - Rational.prototype.realPart = function(){ - return this; - }; - - - Rational.prototype.round = function() { - // FIXME: not correct when values are bignums - if (equals(this.d, 2)) { - // Round to even if it's a n/2 - var v = _integerDivideToFixnum(this.n, this.d); - var fl = Math.floor(v); - var ce = Math.ceil(v); - if (_integerIsZero(fl % 2)) { - return fl; - } - else { - return ce; - } - } else { - return Math.round(this.n / this.d); - } - }; - - - Rational.makeInstance = function(n, d) { - if (n === undefined) - throwRuntimeError("n undefined", n, d); - - if (d === undefined) { d = 1; } - - if (_integerLessThan(d, 0)) { - n = negate(n); - d = negate(d); - } - - var divisor = _integerGcd(abs(n), abs(d)); - n = _integerQuotient(n, divisor); - d = _integerQuotient(d, divisor); - - // Optimization: if we can get around construction the rational - // in favor of just returning n, do it: - if (_integerIsOne(d) || _integerIsZero(n)) { - return n; - } - - return new Rational(n, d); - }; - - - - // Floating Point numbers - var FloatPoint = function(n) { - this.n = n; - }; - FloatPoint = FloatPoint; - - - var NaN = new FloatPoint(Number.NaN); - var inf = new FloatPoint(Number.POSITIVE_INFINITY); - var neginf = new FloatPoint(Number.NEGATIVE_INFINITY); - - // We use these two constants to represent the floating-point coersion - // of bignums that can't be represented with fidelity. - var TOO_POSITIVE_TO_REPRESENT = new FloatPoint(Number.POSITIVE_INFINITY); - var TOO_NEGATIVE_TO_REPRESENT = new FloatPoint(Number.NEGATIVE_INFINITY); - - // Negative zero is a distinguished value representing -0.0. - // There should only be one instance for -0.0. - var NEGATIVE_ZERO = new FloatPoint(-0.0); - var INEXACT_ZERO = new FloatPoint(0.0); - - FloatPoint.pi = new FloatPoint(Math.PI); - FloatPoint.e = new FloatPoint(Math.E); - FloatPoint.nan = NaN; - FloatPoint.inf = inf; - FloatPoint.neginf = neginf; - - FloatPoint.makeInstance = function(n) { - if (isNaN(n)) { - return FloatPoint.nan; - } else if (n === Number.POSITIVE_INFINITY) { - return FloatPoint.inf; - } else if (n === Number.NEGATIVE_INFINITY) { - return FloatPoint.neginf; - } else if (n === 0) { - if ((1/n) === -Infinity) { - return NEGATIVE_ZERO; - } else { - return INEXACT_ZERO; - } - } - return new FloatPoint(n); - }; - - - FloatPoint.prototype.isExact = function() { - return false; - }; - - FloatPoint.prototype.isInexact = function() { - return true; - }; - - - FloatPoint.prototype.isFinite = function() { - return (isFinite(this.n) || - this === TOO_POSITIVE_TO_REPRESENT || - this === TOO_NEGATIVE_TO_REPRESENT); - }; - - - FloatPoint.prototype.toExact = function() { - // The precision of ieee is about 16 decimal digits, which we use here. - if (! isFinite(this.n) || isNaN(this.n)) { - throwRuntimeError("toExact: no exact representation for " + this, this); - } - - var stringRep = this.n.toString(); - var match = stringRep.match(/^(.*)\.(.*)$/); - if (match) { - var intPart = parseInt(match[1]); - var fracPart = parseInt(match[2]); - var tenToDecimalPlaces = Math.pow(10, match[2].length); - return Rational.makeInstance(Math.round(this.n * tenToDecimalPlaces), - tenToDecimalPlaces); - } - else { - return this.n; - } - }; - - FloatPoint.prototype.toInexact = function() { - return this; - }; - - FloatPoint.prototype.isInexact = function() { - return true; - }; - - - FloatPoint.prototype.level = 2; - - - FloatPoint.prototype.liftTo = function(target) { - if (target.level === 3) - return new Complex(this, 0); - return throwRuntimeError("invalid level of Number", this, target); - }; - - FloatPoint.prototype.toString = function() { - if (isNaN(this.n)) - return "+nan.0"; - if (this.n === Number.POSITIVE_INFINITY) - return "+inf.0"; - if (this.n === Number.NEGATIVE_INFINITY) - return "-inf.0"; - if (this === NEGATIVE_ZERO) - return "-0.0"; - var partialResult = this.n.toString(); - if (! partialResult.match('\\.')) { - return partialResult + ".0"; - } else { - return partialResult; - } - }; - - - FloatPoint.prototype.equals = function(other, aUnionFind) { - return ((other instanceof FloatPoint) && - ((this.n === other.n))); - }; - - - - FloatPoint.prototype.isRational = function() { - return this.isFinite(); - }; - - FloatPoint.prototype.isInteger = function() { - return this.isFinite() && this.n === Math.floor(this.n); - }; - - FloatPoint.prototype.isReal = function() { - return true; - }; - - - // sign: Number -> {-1, 0, 1} - var sign = function(n) { - if (lessThan(n, 0)) { - return -1; - } else if (greaterThan(n, 0)) { - return 1; - } else if (n === NEGATIVE_ZERO) { - return -1; - } else { - return 0; - } - }; - - - FloatPoint.prototype.add = function(other) { - if (this.isFinite() && other.isFinite()) { - return FloatPoint.makeInstance(this.n + other.n); - } else { - if (isNaN(this.n) || isNaN(other.n)) { - return NaN; - } else if (this.isFinite() && ! other.isFinite()) { - return other; - } else if (!this.isFinite() && other.isFinite()) { - return this; - } else { - return ((sign(this) * sign(other) === 1) ? - this : NaN); - }; - } - }; - - FloatPoint.prototype.subtract = function(other) { - if (this.isFinite() && other.isFinite()) { - return FloatPoint.makeInstance(this.n - other.n); - } else if (isNaN(this.n) || isNaN(other.n)) { - return NaN; - } else if (! this.isFinite() && ! other.isFinite()) { - if (sign(this) === sign(other)) { - return NaN; - } else { - return this; - } - } else if (this.isFinite()) { - return multiply(other, -1); - } else { // other.isFinite() - return this; - } - }; - - - FloatPoint.prototype.negate = function() { - return FloatPoint.makeInstance(-this.n); - }; - - FloatPoint.prototype.multiply = function(other) { - return FloatPoint.makeInstance(this.n * other.n); - }; - - FloatPoint.prototype.divide = function(other) { - return FloatPoint.makeInstance(this.n / other.n); - }; - - - FloatPoint.prototype.toFixnum = function() { - return this.n; - }; - - FloatPoint.prototype.numerator = function() { - var stringRep = this.n.toString(); - var match = stringRep.match(/^(.*)\.(.*)$/); - if (match) { - var afterDecimal = parseInt(match[2]); - var factorToInt = Math.pow(10, match[2].length); - var extraFactor = _integerGcd(factorToInt, afterDecimal); - var multFactor = factorToInt / extraFactor; - return FloatPoint.makeInstance( Math.round(this.n * multFactor) ); - } else { - return this; - } - }; - - FloatPoint.prototype.denominator = function() { - var stringRep = this.n.toString(); - var match = stringRep.match(/^(.*)\.(.*)$/); - if (match) { - var afterDecimal = parseInt(match[2]); - var factorToInt = Math.pow(10, match[2].length); - var extraFactor = _integerGcd(factorToInt, afterDecimal); - return FloatPoint.makeInstance( Math.round(factorToInt/extraFactor) ); - } else { - return FloatPoint.makeInstance(1); - } - }; - - - FloatPoint.prototype.floor = function() { - return FloatPoint.makeInstance(Math.floor(this.n)); - }; - - FloatPoint.prototype.ceiling = function() { - return FloatPoint.makeInstance(Math.ceil(this.n)); - }; - - - FloatPoint.prototype.greaterThan = function(other) { - return this.n > other.n; - }; - - FloatPoint.prototype.greaterThanOrEqual = function(other) { - return this.n >= other.n; - }; - - FloatPoint.prototype.lessThan = function(other) { - return this.n < other.n; - }; - - FloatPoint.prototype.lessThanOrEqual = function(other) { - return this.n <= other.n; - }; - - - FloatPoint.prototype.integerSqrt = function() { - if (this === NEGATIVE_ZERO) { return this; } - if (isInteger(this)) { - if(this.n >= 0) { - return FloatPoint.makeInstance(Math.floor(Math.sqrt(this.n))); - } else { - return Complex.makeInstance( - INEXACT_ZERO, - FloatPoint.makeInstance(Math.floor(Math.sqrt(-this.n)))); - } - } else { - throwRuntimeError("integerSqrt: can only be applied to an integer", this); - } - }; - - FloatPoint.prototype.sqrt = function() { - if (this.n < 0) { - var result = Complex.makeInstance( - 0, - FloatPoint.makeInstance(Math.sqrt(-this.n))); - return result; - } else { - return FloatPoint.makeInstance(Math.sqrt(this.n)); - } - }; - - FloatPoint.prototype.abs = function() { - return FloatPoint.makeInstance(Math.abs(this.n)); - }; - - - - FloatPoint.prototype.log = function(){ - if (this.n < 0) - return (new Complex(this, 0)).log(); - else - return FloatPoint.makeInstance(Math.log(this.n)); - }; - - FloatPoint.prototype.angle = function(){ - if (0 === this.n) - return 0; - if (this.n > 0) - return 0; - else - return FloatPoint.pi; - }; - - FloatPoint.prototype.tan = function(){ - return FloatPoint.makeInstance(Math.tan(this.n)); - }; - - FloatPoint.prototype.atan = function(){ - return FloatPoint.makeInstance(Math.atan(this.n)); - }; - - FloatPoint.prototype.cos = function(){ - return FloatPoint.makeInstance(Math.cos(this.n)); - }; - - FloatPoint.prototype.sin = function(){ - return FloatPoint.makeInstance(Math.sin(this.n)); - }; - - FloatPoint.prototype.expt = function(a){ - if (this.n === 1) { - if (a.isFinite()) { - return this; - } else if (isNaN(a.n)){ - return this; - } else { - return this; - } - } else { - return FloatPoint.makeInstance(Math.pow(this.n, a.n)); - } - }; - - FloatPoint.prototype.exp = function(){ - return FloatPoint.makeInstance(Math.exp(this.n)); - }; - - FloatPoint.prototype.acos = function(){ - return FloatPoint.makeInstance(Math.acos(this.n)); - }; - - FloatPoint.prototype.asin = function(){ - return FloatPoint.makeInstance(Math.asin(this.n)); - }; - - FloatPoint.prototype.imaginaryPart = function(){ - return 0; - }; - - FloatPoint.prototype.realPart = function(){ - return this; - }; - - - FloatPoint.prototype.round = function(){ - if (isFinite(this.n)) { - if (this === NEGATIVE_ZERO) { - return this; - } - if (Math.abs(Math.floor(this.n) - this.n) === 0.5) { - if (Math.floor(this.n) % 2 === 0) - return FloatPoint.makeInstance(Math.floor(this.n)); - return FloatPoint.makeInstance(Math.ceil(this.n)); - } else { - return FloatPoint.makeInstance(Math.round(this.n)); - } - } else { - return this; - } - }; - - - FloatPoint.prototype.conjugate = function() { - return this; - }; - - FloatPoint.prototype.magnitude = FloatPoint.prototype.abs; - - - - ////////////////////////////////////////////////////////////////////// - // Complex numbers - ////////////////////////////////////////////////////////////////////// - - var Complex = function(r, i){ - this.r = r; - this.i = i; - }; - - // Constructs a complex number from two basic number r and i. r and i can - // either be plt.type.Rational or plt.type.FloatPoint. - Complex.makeInstance = function(r, i){ - if (i === undefined) { i = 0; } - if (isExact(i) && isInteger(i) && _integerIsZero(i)) { - return r; - } - if (isInexact(r) || isInexact(i)) { - r = toInexact(r); - i = toInexact(i); - } - return new Complex(r, i); - }; - - Complex.prototype.toString = function() { - var realPart = this.r.toString(), imagPart = this.i.toString(); - if (imagPart[0] === '-' || imagPart[0] === '+') { - return realPart + imagPart + 'i'; - } else { - return realPart + "+" + imagPart + 'i'; - } - }; - - - Complex.prototype.isFinite = function() { - return isSchemeNumberFinite(this.r) && isSchemeNumberFinite(this.i); - }; - - - Complex.prototype.isRational = function() { - return isRational(this.r) && eqv(this.i, 0); - }; - - Complex.prototype.isInteger = function() { - return (isInteger(this.r) && - eqv(this.i, 0)); - }; - - Complex.prototype.toExact = function() { - return Complex.makeInstance( toExact(this.r), toExact(this.i) ); - }; - - Complex.prototype.toInexact = function() { - return Complex.makeInstance(toInexact(this.r), - toInexact(this.i)); - }; - - - Complex.prototype.isExact = function() { - return isExact(this.r) && isExact(this.i); - }; - - - Complex.prototype.isInexact = function() { - return isInexact(this.r) || isInexact(this.i); - }; - - - Complex.prototype.level = 3; - - - Complex.prototype.liftTo = function(target){ - throwRuntimeError("Don't know how to lift Complex number", this, target); - }; - - Complex.prototype.equals = function(other) { - var result = ((other instanceof Complex) && - (equals(this.r, other.r)) && - (equals(this.i, other.i))); - return result; - }; - - - - Complex.prototype.greaterThan = function(other) { - if (! this.isReal() || ! other.isReal()) { - throwRuntimeError(">: expects argument of type real number", this, other); - } - return greaterThan(this.r, other.r); - }; - - Complex.prototype.greaterThanOrEqual = function(other) { - if (! this.isReal() || ! other.isReal()) { - throwRuntimeError(">=: expects argument of type real number", this, other); - } - return greaterThanOrEqual(this.r, other.r); - }; - - Complex.prototype.lessThan = function(other) { - if (! this.isReal() || ! other.isReal()) { - throwRuntimeError("<: expects argument of type real number", this, other); - } - return lessThan(this.r, other.r); - }; - - Complex.prototype.lessThanOrEqual = function(other) { - if (! this.isReal() || ! other.isReal()) { - throwRuntimeError("<=: expects argument of type real number", this, other); - } - return lessThanOrEqual(this.r, other.r); - }; - - - Complex.prototype.abs = function(){ - if (!equals(this.i, 0).valueOf()) - throwRuntimeError("abs: expects argument of type real number", this); - return abs(this.r); - }; - - Complex.prototype.toFixnum = function(){ - if (!equals(this.i, 0).valueOf()) - throwRuntimeError("toFixnum: expects argument of type real number", this); - return toFixnum(this.r); - }; - - Complex.prototype.numerator = function() { - if (!this.isReal()) - throwRuntimeError("numerator: can only be applied to real number", this); - return numerator(this.n); - }; - - - Complex.prototype.denominator = function() { - if (!this.isReal()) - throwRuntimeError("floor: can only be applied to real number", this); - return denominator(this.n); - }; - - Complex.prototype.add = function(other){ - return Complex.makeInstance( - add(this.r, other.r), - add(this.i, other.i)); - }; - - Complex.prototype.subtract = function(other){ - return Complex.makeInstance( - subtract(this.r, other.r), - subtract(this.i, other.i)); - }; - - Complex.prototype.negate = function() { - return Complex.makeInstance(negate(this.r), - negate(this.i)); - }; - - - Complex.prototype.multiply = function(other){ - // If the other value is real, just do primitive division - if (other.isReal()) { - return Complex.makeInstance( - multiply(this.r, other.r), - multiply(this.i, other.r)); - } - var r = subtract( - multiply(this.r, other.r), - multiply(this.i, other.i)); - var i = add( - multiply(this.r, other.i), - multiply(this.i, other.r)); - return Complex.makeInstance(r, i); - }; - - - - - - Complex.prototype.divide = function(other){ - var a, b, c, d, r, x, y; - // If the other value is real, just do primitive division - if (other.isReal()) { - return Complex.makeInstance( - divide(this.r, other.r), - divide(this.i, other.r)); - } - - if (this.isInexact() || other.isInexact()) { - // http://portal.acm.org/citation.cfm?id=1039814 - // We currently use Smith's method, though we should - // probably switch over to Priest's method. - a = this.r; - b = this.i; - c = other.r; - d = other.i; - if (lessThanOrEqual(abs(d), abs(c))) { - r = divide(d, c); - x = divide(add(a, multiply(b, r)), - add(c, multiply(d, r))); - y = divide(subtract(b, multiply(a, r)), - add(c, multiply(d, r))); - } else { - r = divide(c, d); - x = divide(add(multiply(a, r), b), - add(multiply(c, r), d)); - y = divide(subtract(multiply(b, r), a), - add(multiply(c, r), d)); - } - return Complex.makeInstance(x, y); - } else { - var con = conjugate(other); - var up = multiply(this, con); - - // Down is guaranteed to be real by this point. - var down = realPart(multiply(other, con)); - - var result = Complex.makeInstance( - divide(realPart(up), down), - divide(imaginaryPart(up), down)); - return result; - } - }; - - Complex.prototype.conjugate = function(){ - var result = Complex.makeInstance( - this.r, - subtract(0, this.i)); - - return result; - }; - - Complex.prototype.magnitude = function(){ - var sum = add( - multiply(this.r, this.r), - multiply(this.i, this.i)); - return sqrt(sum); - }; - - Complex.prototype.isReal = function(){ - return eqv(this.i, 0); - }; - - Complex.prototype.integerSqrt = function() { - if (isInteger(this)) { - return integerSqrt(this.r); - } else { - throwRuntimeError("integerSqrt: can only be applied to an integer", this); - } - }; - - Complex.prototype.sqrt = function(){ - if (this.isReal()) - return sqrt(this.r); - // http://en.wikipedia.org/wiki/Square_root#Square_roots_of_negative_and_complex_numbers - var r_plus_x = add(this.magnitude(), this.r); - - var r = sqrt(halve(r_plus_x)); - - var i = divide(this.i, sqrt(multiply(r_plus_x, 2))); - - - return Complex.makeInstance(r, i); - }; - - Complex.prototype.log = function(){ - var m = this.magnitude(); - var theta = this.angle(); - var result = add( - log(m), - timesI(theta)); - return result; - }; - - Complex.prototype.angle = function(){ - if (this.isReal()) { - return angle(this.r); - } - if (equals(0, this.r)) { - var tmp = halve(FloatPoint.pi); - return greaterThan(this.i, 0) ? - tmp : negate(tmp); - } else { - var tmp = atan(divide(abs(this.i), abs(this.r))); - if (greaterThan(this.r, 0)) { - return greaterThan(this.i, 0) ? - tmp : negate(tmp); - } else { - return greaterThan(this.i, 0) ? - subtract(FloatPoint.pi, tmp) : subtract(tmp, FloatPoint.pi); - } - } - }; - - var plusI = Complex.makeInstance(0, 1); - var minusI = Complex.makeInstance(0, -1); - - - Complex.prototype.tan = function() { - return divide(this.sin(), this.cos()); - }; - - Complex.prototype.atan = function(){ - if (equals(this, plusI) || - equals(this, minusI)) { - return neginf; - } - return multiply( - plusI, - multiply( - FloatPoint.makeInstance(0.5), - log(divide( - add(plusI, this), - add( - plusI, - subtract(0, this)))))); - }; - - Complex.prototype.cos = function(){ - if (this.isReal()) - return cos(this.r); - var iz = timesI(this); - var iz_negate = negate(iz); - - return halve(add(exp(iz), exp(iz_negate))); - }; - - Complex.prototype.sin = function(){ - if (this.isReal()) - return sin(this.r); - var iz = timesI(this); - var iz_negate = negate(iz); - var z2 = Complex.makeInstance(0, 2); - var exp_negate = subtract(exp(iz), exp(iz_negate)); - var result = divide(exp_negate, z2); - return result; - }; - - - Complex.prototype.expt = function(y){ - if (isExactInteger(y) && greaterThanOrEqual(y, 0)) { - return fastExpt(this, y); - } - var expo = multiply(y, this.log()); - return exp(expo); - }; - - Complex.prototype.exp = function(){ - var r = exp(this.r); - var cos_a = cos(this.i); - var sin_a = sin(this.i); - - return multiply( - r, - add(cos_a, timesI(sin_a))); - }; - - Complex.prototype.acos = function(){ - if (this.isReal()) - return acos(this.r); - var pi_half = halve(FloatPoint.pi); - var iz = timesI(this); - var root = sqrt(subtract(1, sqr(this))); - var l = timesI(log(add(iz, root))); - return add(pi_half, l); - }; - - Complex.prototype.asin = function(){ - if (this.isReal()) - return asin(this.r); - - var oneNegateThisSq = - subtract(1, sqr(this)); - var sqrtOneNegateThisSq = sqrt(oneNegateThisSq); - return multiply(2, atan(divide(this, - add(1, sqrtOneNegateThisSq)))); - }; - - Complex.prototype.ceiling = function(){ - if (!this.isReal()) - throwRuntimeError("ceiling: can only be applied to real number", this); - return ceiling(this.r); - }; - - Complex.prototype.floor = function(){ - if (!this.isReal()) - throwRuntimeError("floor: can only be applied to real number", this); - return floor(this.r); - }; - - Complex.prototype.imaginaryPart = function(){ - return this.i; - }; - - Complex.prototype.realPart = function(){ - return this.r; - }; - - Complex.prototype.round = function(){ - if (!this.isReal()) - throwRuntimeError("round: can only be applied to real number", this); - return round(this.r); - }; - - - - var rationalRegexp = new RegExp("^([+-]?\\d+)/(\\d+)$"); - var complexRegexp = new RegExp("^([+-]?[\\d\\w/\\.]*)([+-])([\\d\\w/\\.]*)i$"); - var digitRegexp = new RegExp("^[+-]?\\d+$"); - var flonumRegexp = new RegExp("^([+-]?\\d*)\\.(\\d*)$"); - var scientificPattern = new RegExp("^([+-]?\\d*\\.?\\d*)[Ee](\\+?\\d+)$"); - - // fromString: string -> (scheme-number | false) - var fromString = function(x) { - var aMatch = x.match(rationalRegexp); - if (aMatch) { - return Rational.makeInstance(fromString(aMatch[1]), - fromString(aMatch[2])); - } - - var cMatch = x.match(complexRegexp); - if (cMatch) { - return Complex.makeInstance(fromString(cMatch[1] || "0"), - fromString(cMatch[2] + (cMatch[3] || "1"))); - } - - // Floating point tests - if (x === '+nan.0' || x === '-nan.0') - return FloatPoint.nan; - if (x === '+inf.0') - return FloatPoint.inf; - if (x === '-inf.0') - return FloatPoint.neginf; - if (x === "-0.0") { - return NEGATIVE_ZERO; - } - if (x.match(flonumRegexp) || x.match(scientificPattern)) { - return FloatPoint.makeInstance(Number(x)); - } - - // Finally, integer tests. - if (x.match(digitRegexp)) { - var n = Number(x); - if (isOverflow(n)) { - return makeBignum(x); - } else { - return n; - } - } else { - return false; - } - }; - - - - - - ////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - - // The code below comes from Tom Wu's BigInteger implementation: - - // Copyright (c) 2005 Tom Wu - // All Rights Reserved. - // See "LICENSE" for details. - - // Basic JavaScript BN library - subset useful for RSA encryption. - - // Bits per digit - var dbits; - - // JavaScript engine analysis - var canary = 0xdeadbeefcafe; - var j_lm = ((canary&0xffffff)==0xefcafe); - - // (public) Constructor - function BigInteger(a,b,c) { - if(a != null) - if("number" == typeof a) this.fromNumber(a,b,c); - else if(b == null && "string" != typeof a) this.fromString(a,256); - else this.fromString(a,b); - } - - // return new, unset BigInteger - function nbi() { return new BigInteger(null); } - - // am: Compute w_j += (x*this_i), propagate carries, - // c is initial carry, returns final carry. - // c < 3*dvalue, x < 2*dvalue, this_i < dvalue - // We need to select the fastest one that works in this environment. - - // am1: use a single mult and divide to get the high bits, - // max digit bits should be 26 because - // max internal value = 2*dvalue^2-2*dvalue (< 2^53) - function am1(i,x,w,j,c,n) { - while(--n >= 0) { - var v = x*this[i++]+w[j]+c; - c = Math.floor(v/0x4000000); - w[j++] = v&0x3ffffff; - } - return c; - } - // am2 avoids a big mult-and-extract completely. - // Max digit bits should be <= 30 because we do bitwise ops - // on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) - function am2(i,x,w,j,c,n) { - var xl = x&0x7fff, xh = x>>15; - while(--n >= 0) { - var l = this[i]&0x7fff; - var h = this[i++]>>15; - var m = xh*l+h*xl; - l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff); - c = (l>>>30)+(m>>>15)+xh*h+(c>>>30); - w[j++] = l&0x3fffffff; - } - return c; - } - // Alternately, set max digit bits to 28 since some - // browsers slow down when dealing with 32-bit numbers. - function am3(i,x,w,j,c,n) { - var xl = x&0x3fff, xh = x>>14; - while(--n >= 0) { - var l = this[i]&0x3fff; - var h = this[i++]>>14; - var m = xh*l+h*xl; - l = xl*l+((m&0x3fff)<<14)+w[j]+c; - c = (l>>28)+(m>>14)+xh*h; - w[j++] = l&0xfffffff; - } - return c; - } - if(j_lm && (typeof(navigator) !== 'undefined' && navigator.appName == "Microsoft Internet Explorer")) { - BigInteger.prototype.am = am2; - dbits = 30; - } - else if(j_lm && (typeof(navigator) !== 'undefined' && navigator.appName != "Netscape")) { - BigInteger.prototype.am = am1; - dbits = 26; - } - else { // Mozilla/Netscape seems to prefer am3 - BigInteger.prototype.am = am3; - dbits = 28; - } - - BigInteger.prototype.DB = dbits; - BigInteger.prototype.DM = ((1<= 0; --i) r[i] = this[i]; - r.t = this.t; - r.s = this.s; - } - - // (protected) set from integer value x, -DV <= x < DV - function bnpFromInt(x) { - this.t = 1; - this.s = (x<0)?-1:0; - if(x > 0) this[0] = x; - else if(x < -1) this[0] = x+DV; - else this.t = 0; - } - - // return bigint initialized to value - function nbv(i) { var r = nbi(); r.fromInt(i); return r; } - - // (protected) set from string and radix - function bnpFromString(s,b) { - var k; - if(b == 16) k = 4; - else if(b == 8) k = 3; - else if(b == 256) k = 8; // byte array - else if(b == 2) k = 1; - else if(b == 32) k = 5; - else if(b == 4) k = 2; - else { this.fromRadix(s,b); return; } - this.t = 0; - this.s = 0; - var i = s.length, mi = false, sh = 0; - while(--i >= 0) { - var x = (k==8)?s[i]&0xff:intAt(s,i); - if(x < 0) { - if(s.charAt(i) == "-") mi = true; - continue; - } - mi = false; - if(sh == 0) - this[this.t++] = x; - else if(sh+k > this.DB) { - this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<>(this.DB-sh)); - } - else - this[this.t-1] |= x<= this.DB) sh -= this.DB; - } - if(k == 8 && (s[0]&0x80) != 0) { - this.s = -1; - if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)< 0 && this[this.t-1] == c) --this.t; - } - - // (public) return string representation in given radix - function bnToString(b) { - if(this.s < 0) return "-"+this.negate().toString(b); - var k; - if(b == 16) k = 4; - else if(b == 8) k = 3; - else if(b == 2) k = 1; - else if(b == 32) k = 5; - else if(b == 4) k = 2; - else return this.toRadix(b); - var km = (1< 0) { - if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r.push(int2char(d)); } - while(i >= 0) { - if(p < k) { - d = (this[i]&((1<>(p+=this.DB-k); - } - else { - d = (this[i]>>(p-=k))&km; - if(p <= 0) { p += this.DB; --i; } - } - if(d > 0) m = true; - if(m) r.push(int2char(d)); - } - } - return m?r.join(""):"0"; - } - - // (public) -this - function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; } - - // (public) |this| - function bnAbs() { return (this.s<0)?this.negate():this; } - - // (public) return + if this > a, - if this < a, 0 if equal - function bnCompareTo(a) { - var r = this.s-a.s; - if(r != 0) return r; - var i = this.t; - if ( this.s < 0 ) { - r = a.t - i; - } - else { - r = i - a.t; - } - if(r != 0) return r; - while(--i >= 0) if((r=this[i]-a[i]) != 0) return r; - return 0; - } - - // returns bit length of the integer x - function nbits(x) { - var r = 1, t; - if((t=x>>>16) != 0) { x = t; r += 16; } - if((t=x>>8) != 0) { x = t; r += 8; } - if((t=x>>4) != 0) { x = t; r += 4; } - if((t=x>>2) != 0) { x = t; r += 2; } - if((t=x>>1) != 0) { x = t; r += 1; } - return r; - } - - // (public) return the number of bits in "this" - function bnBitLength() { - if(this.t <= 0) return 0; - return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM)); - } - - // (protected) r = this << n*DB - function bnpDLShiftTo(n,r) { - var i; - for(i = this.t-1; i >= 0; --i) r[i+n] = this[i]; - for(i = n-1; i >= 0; --i) r[i] = 0; - r.t = this.t+n; - r.s = this.s; - } - - // (protected) r = this >> n*DB - function bnpDRShiftTo(n,r) { - for(var i = n; i < this.t; ++i) r[i-n] = this[i]; - r.t = Math.max(this.t-n,0); - r.s = this.s; - } - - // (protected) r = this << n - function bnpLShiftTo(n,r) { - var bs = n%this.DB; - var cbs = this.DB-bs; - var bm = (1<= 0; --i) { - r[i+ds+1] = (this[i]>>cbs)|c; - c = (this[i]&bm)<= 0; --i) r[i] = 0; - r[ds] = c; - r.t = this.t+ds+1; - r.s = this.s; - r.clamp(); - } - - // (protected) r = this >> n - function bnpRShiftTo(n,r) { - r.s = this.s; - var ds = Math.floor(n/this.DB); - if(ds >= this.t) { r.t = 0; return; } - var bs = n%this.DB; - var cbs = this.DB-bs; - var bm = (1<>bs; - for(var i = ds+1; i < this.t; ++i) { - r[i-ds-1] |= (this[i]&bm)<>bs; - } - if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<>= this.DB; - } - if(a.t < this.t) { - c -= a.s; - while(i < this.t) { - c += this[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c += this.s; - } - else { - c += this.s; - while(i < a.t) { - c -= a[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c -= a.s; - } - r.s = (c<0)?-1:0; - if(c < -1) r[i++] = this.DV+c; - else if(c > 0) r[i++] = c; - r.t = i; - r.clamp(); - } - - // (protected) r = this * a, r != this,a (HAC 14.12) - // "this" should be the larger one if appropriate. - function bnpMultiplyTo(a,r) { - var x = this.abs(), y = a.abs(); - var i = x.t; - r.t = i+y.t; - while(--i >= 0) r[i] = 0; - for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t); - r.s = 0; - r.clamp(); - if(this.s != a.s) BigInteger.ZERO.subTo(r,r); - } - - // (protected) r = this^2, r != this (HAC 14.16) - function bnpSquareTo(r) { - var x = this.abs(); - var i = r.t = 2*x.t; - while(--i >= 0) r[i] = 0; - for(i = 0; i < x.t-1; ++i) { - var c = x.am(i,x[i],r,2*i,0,1); - if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) { - r[i+x.t] -= x.DV; - r[i+x.t+1] = 1; - } - } - if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1); - r.s = 0; - r.clamp(); - } - - - // (protected) divide this by m, quotient and remainder to q, r (HAC 14.20) - // r != q, this != m. q or r may be null. - function bnpDivRemTo(m,q,r) { - var pm = m.abs(); - if(pm.t <= 0) return; - var pt = this.abs(); - if(pt.t < pm.t) { - if(q != null) q.fromInt(0); - if(r != null) this.copyTo(r); - return; - } - if(r == null) r = nbi(); - var y = nbi(), ts = this.s, ms = m.s; - var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus - if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); } - else { pm.copyTo(y); pt.copyTo(r); } - var ys = y.t; - var y0 = y[ys-1]; - if(y0 == 0) return; - var yt = y0*(1<1)?y[ys-2]>>this.F2:0); - var d1 = this.FV/yt, d2 = (1<= 0) { - r[r.t++] = 1; - r.subTo(t,r); - } - BigInteger.ONE.dlShiftTo(ys,t); - t.subTo(y,y); // "negative" y so we can replace sub with am later - while(y.t < ys) y[y.t++] = 0; - while(--j >= 0) { - // Estimate quotient digit - var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2); - if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out - y.dlShiftTo(j,t); - r.subTo(t,r); - while(r[i] < --qd) r.subTo(t,r); - } - } - if(q != null) { - r.drShiftTo(ys,q); - if(ts != ms) BigInteger.ZERO.subTo(q,q); - } - r.t = ys; - r.clamp(); - if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder - if(ts < 0) BigInteger.ZERO.subTo(r,r); - } - - // (public) this mod a - function bnMod(a) { - var r = nbi(); - this.abs().divRemTo(a,null,r); - if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r); - return r; - } - - // Modular reduction using "classic" algorithm - function Classic(m) { this.m = m; } - function cConvert(x) { - if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m); - else return x; - } - function cRevert(x) { return x; } - function cReduce(x) { x.divRemTo(this.m,null,x); } - function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } - function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); } - - Classic.prototype.convert = cConvert; - Classic.prototype.revert = cRevert; - Classic.prototype.reduce = cReduce; - Classic.prototype.mulTo = cMulTo; - Classic.prototype.sqrTo = cSqrTo; - - // (protected) return "-1/this % 2^DB"; useful for Mont. reduction - // justification: - // xy == 1 (mod m) - // xy = 1+km - // xy(2-xy) = (1+km)(1-km) - // x[y(2-xy)] = 1-k^2m^2 - // x[y(2-xy)] == 1 (mod m^2) - // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 - // should reduce x and y(2-xy) by m^2 at each step to keep size bounded. - // JS multiply "overflows" differently from C/C++, so care is needed here. - function bnpInvDigit() { - if(this.t < 1) return 0; - var x = this[0]; - if((x&1) == 0) return 0; - var y = x&3; // y == 1/x mod 2^2 - y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4 - y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8 - y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16 - // last step - calculate inverse mod DV directly; - // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints - y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits - // we really want the negative inverse, and -DV < y < DV - return (y>0)?this.DV-y:-y; - } - - // Montgomery reduction - function Montgomery(m) { - this.m = m; - this.mp = m.invDigit(); - this.mpl = this.mp&0x7fff; - this.mph = this.mp>>15; - this.um = (1<<(m.DB-15))-1; - this.mt2 = 2*m.t; - } - - // xR mod m - function montConvert(x) { - var r = nbi(); - x.abs().dlShiftTo(this.m.t,r); - r.divRemTo(this.m,null,r); - if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r); - return r; - } - - // x/R mod m - function montRevert(x) { - var r = nbi(); - x.copyTo(r); - this.reduce(r); - return r; - } - - // x = x/R mod m (HAC 14.32) - function montReduce(x) { - while(x.t <= this.mt2) // pad x so am has enough room later - x[x.t++] = 0; - for(var i = 0; i < this.m.t; ++i) { - // faster way of calculating u0 = x[i]*mp mod DV - var j = x[i]&0x7fff; - var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM; - // use am to combine the multiply-shift-add into one call - j = i+this.m.t; - x[j] += this.m.am(0,u0,x,i,0,this.m.t); - // propagate carry - while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; } - } - x.clamp(); - x.drShiftTo(this.m.t,x); - if(x.compareTo(this.m) >= 0) x.subTo(this.m,x); - } - - // r = "x^2/R mod m"; x != r - function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); } - - // r = "xy/R mod m"; x,y != r - function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } - - Montgomery.prototype.convert = montConvert; - Montgomery.prototype.revert = montRevert; - Montgomery.prototype.reduce = montReduce; - Montgomery.prototype.mulTo = montMulTo; - Montgomery.prototype.sqrTo = montSqrTo; - - // (protected) true iff this is even - function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; } - - // (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79) - function bnpExp(e,z) { - if(e > 0xffffffff || e < 1) return BigInteger.ONE; - var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1; - g.copyTo(r); - while(--i >= 0) { - z.sqrTo(r,r2); - if((e&(1< 0) z.mulTo(r2,g,r); - else { var t = r; r = r2; r2 = t; } - } - return z.revert(r); - } - - // (public) this^e % m, 0 <= e < 2^32 - function bnModPowInt(e,m) { - var z; - if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m); - return this.exp(e,z); - } - - // protected - BigInteger.prototype.copyTo = bnpCopyTo; - BigInteger.prototype.fromInt = bnpFromInt; - BigInteger.prototype.fromString = bnpFromString; - BigInteger.prototype.clamp = bnpClamp; - BigInteger.prototype.dlShiftTo = bnpDLShiftTo; - BigInteger.prototype.drShiftTo = bnpDRShiftTo; - BigInteger.prototype.lShiftTo = bnpLShiftTo; - BigInteger.prototype.rShiftTo = bnpRShiftTo; - BigInteger.prototype.subTo = bnpSubTo; - BigInteger.prototype.multiplyTo = bnpMultiplyTo; - BigInteger.prototype.squareTo = bnpSquareTo; - BigInteger.prototype.divRemTo = bnpDivRemTo; - BigInteger.prototype.invDigit = bnpInvDigit; - BigInteger.prototype.isEven = bnpIsEven; - BigInteger.prototype.exp = bnpExp; - - // public - BigInteger.prototype.toString = bnToString; - BigInteger.prototype.negate = bnNegate; - BigInteger.prototype.abs = bnAbs; - BigInteger.prototype.compareTo = bnCompareTo; - BigInteger.prototype.bitLength = bnBitLength; - BigInteger.prototype.mod = bnMod; - BigInteger.prototype.modPowInt = bnModPowInt; - - // "constants" - BigInteger.ZERO = nbv(0); - BigInteger.ONE = nbv(1); - - // Copyright (c) 2005-2009 Tom Wu - // All Rights Reserved. - // See "LICENSE" for details. - - // Extended JavaScript BN functions, required for RSA private ops. - - // Version 1.1: new BigInteger("0", 10) returns "proper" zero - - // (public) - function bnClone() { var r = nbi(); this.copyTo(r); return r; } - - // (public) return value as integer - function bnIntValue() { - if(this.s < 0) { - if(this.t == 1) return this[0]-this.DV; - else if(this.t == 0) return -1; - } - else if(this.t == 1) return this[0]; - else if(this.t == 0) return 0; - // assumes 16 < DB < 32 - return ((this[1]&((1<<(32-this.DB))-1))<>24; } - - // (public) return value as short (assumes DB>=16) - function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; } - - // (protected) return x s.t. r^x < DV - function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); } - - // (public) 0 if this == 0, 1 if this > 0 - function bnSigNum() { - if(this.s < 0) return -1; - else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0; - else return 1; - } - - // (protected) convert to radix string - function bnpToRadix(b) { - if(b == null) b = 10; - if(this.signum() == 0 || b < 2 || b > 36) return "0"; - var cs = this.chunkSize(b); - var a = Math.pow(b,cs); - var d = nbv(a), y = nbi(), z = nbi(), r = ""; - this.divRemTo(d,y,z); - while(y.signum() > 0) { - r = (a+z.intValue()).toString(b).substr(1) + r; - y.divRemTo(d,y,z); - } - return z.intValue().toString(b) + r; - } - - // (protected) convert from radix string - function bnpFromRadix(s,b) { - this.fromInt(0); - if(b == null) b = 10; - var cs = this.chunkSize(b); - var d = Math.pow(b,cs), mi = false, j = 0, w = 0; - for(var i = 0; i < s.length; ++i) { - var x = intAt(s,i); - if(x < 0) { - if(s.charAt(i) == "-" && this.signum() == 0) mi = true; - continue; - } - w = b*w+x; - if(++j >= cs) { - this.dMultiply(d); - this.dAddOffset(w,0); - j = 0; - w = 0; - } - } - if(j > 0) { - this.dMultiply(Math.pow(b,j)); - this.dAddOffset(w,0); - } - if(mi) BigInteger.ZERO.subTo(this,this); - } - - // (protected) alternate constructor - function bnpFromNumber(a,b,c) { - if("number" == typeof b) { - // new BigInteger(int,int,RNG) - if(a < 2) this.fromInt(1); - else { - this.fromNumber(a,c); - if(!this.testBit(a-1)) // force MSB set - this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this); - if(this.isEven()) this.dAddOffset(1,0); // force odd - while(!this.isProbablePrime(b)) { - this.dAddOffset(2,0); - if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this); - } - } - } - else { - // new BigInteger(int,RNG) - var x = [], t = a&7; - x.length = (a>>3)+1; - b.nextBytes(x); - if(t > 0) x[0] &= ((1< 0) { - if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p) - r[k++] = d|(this.s<<(this.DB-p)); - while(i >= 0) { - if(p < 8) { - d = (this[i]&((1<>(p+=this.DB-8); - } - else { - d = (this[i]>>(p-=8))&0xff; - if(p <= 0) { p += this.DB; --i; } - } - if((d&0x80) != 0) d |= -256; - if(k == 0 && (this.s&0x80) != (d&0x80)) ++k; - if(k > 0 || d != this.s) r[k++] = d; - } - } - return r; - } - - function bnEquals(a) { return(this.compareTo(a)==0); } - function bnMin(a) { return(this.compareTo(a)<0)?this:a; } - function bnMax(a) { return(this.compareTo(a)>0)?this:a; } - - // (protected) r = this op a (bitwise) - function bnpBitwiseTo(a,op,r) { - var i, f, m = Math.min(a.t,this.t); - for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]); - if(a.t < this.t) { - f = a.s&this.DM; - for(i = m; i < this.t; ++i) r[i] = op(this[i],f); - r.t = this.t; - } - else { - f = this.s&this.DM; - for(i = m; i < a.t; ++i) r[i] = op(f,a[i]); - r.t = a.t; - } - r.s = op(this.s,a.s); - r.clamp(); - } - - // (public) this & a - function op_and(x,y) { return x&y; } - function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; } - - // (public) this | a - function op_or(x,y) { return x|y; } - function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; } - - // (public) this ^ a - function op_xor(x,y) { return x^y; } - function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; } - - // (public) this & ~a - function op_andnot(x,y) { return x&~y; } - function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; } - - // (public) ~this - function bnNot() { - var r = nbi(); - for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i]; - r.t = this.t; - r.s = ~this.s; - return r; - } - - // (public) this << n - function bnShiftLeft(n) { - var r = nbi(); - if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r); - return r; - } - - // (public) this >> n - function bnShiftRight(n) { - var r = nbi(); - if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r); - return r; - } - - // return index of lowest 1-bit in x, x < 2^31 - function lbit(x) { - if(x == 0) return -1; - var r = 0; - if((x&0xffff) == 0) { x >>= 16; r += 16; } - if((x&0xff) == 0) { x >>= 8; r += 8; } - if((x&0xf) == 0) { x >>= 4; r += 4; } - if((x&3) == 0) { x >>= 2; r += 2; } - if((x&1) == 0) ++r; - return r; - } - - // (public) returns index of lowest 1-bit (or -1 if none) - function bnGetLowestSetBit() { - for(var i = 0; i < this.t; ++i) - if(this[i] != 0) return i*this.DB+lbit(this[i]); - if(this.s < 0) return this.t*this.DB; - return -1; - } - - // return number of 1 bits in x - function cbit(x) { - var r = 0; - while(x != 0) { x &= x-1; ++r; } - return r; - } - - // (public) return number of set bits - function bnBitCount() { - var r = 0, x = this.s&this.DM; - for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x); - return r; - } - - // (public) true iff nth bit is set - function bnTestBit(n) { - var j = Math.floor(n/this.DB); - if(j >= this.t) return(this.s!=0); - return((this[j]&(1<<(n%this.DB)))!=0); - } - - // (protected) this op (1<>= this.DB; - } - if(a.t < this.t) { - c += a.s; - while(i < this.t) { - c += this[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c += this.s; - } - else { - c += this.s; - while(i < a.t) { - c += a[i]; - r[i++] = c&this.DM; - c >>= this.DB; - } - c += a.s; - } - r.s = (c<0)?-1:0; - if(c > 0) r[i++] = c; - else if(c < -1) r[i++] = this.DV+c; - r.t = i; - r.clamp(); - } - - // (public) this + a - function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; } - - // (public) this - a - function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; } - - // (public) this * a - function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; } - - // (public) this / a - function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; } - - // (public) this % a - function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; } - - // (public) [this/a,this%a] - function bnDivideAndRemainder(a) { - var q = nbi(), r = nbi(); - this.divRemTo(a,q,r); - return [q,r]; - } - - // (protected) this *= n, this >= 0, 1 < n < DV - function bnpDMultiply(n) { - this[this.t] = this.am(0,n-1,this,0,0,this.t); - ++this.t; - this.clamp(); - } - - // (protected) this += n << w words, this >= 0 - function bnpDAddOffset(n,w) { - if(n == 0) return; - while(this.t <= w) this[this.t++] = 0; - this[w] += n; - while(this[w] >= this.DV) { - this[w] -= this.DV; - if(++w >= this.t) this[this.t++] = 0; - ++this[w]; - } - } - - // A "null" reducer - function NullExp() {} - function nNop(x) { return x; } - function nMulTo(x,y,r) { x.multiplyTo(y,r); } - function nSqrTo(x,r) { x.squareTo(r); } - - NullExp.prototype.convert = nNop; - NullExp.prototype.revert = nNop; - NullExp.prototype.mulTo = nMulTo; - NullExp.prototype.sqrTo = nSqrTo; - - // (public) this^e - function bnPow(e) { return this.exp(e,new NullExp()); } - - // (protected) r = lower n words of "this * a", a.t <= n - // "this" should be the larger one if appropriate. - function bnpMultiplyLowerTo(a,n,r) { - var i = Math.min(this.t+a.t,n); - r.s = 0; // assumes a,this >= 0 - r.t = i; - while(i > 0) r[--i] = 0; - var j; - for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t); - for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i); - r.clamp(); - } - - // (protected) r = "this * a" without lower n words, n > 0 - // "this" should be the larger one if appropriate. - function bnpMultiplyUpperTo(a,n,r) { - --n; - var i = r.t = this.t+a.t-n; - r.s = 0; // assumes a,this >= 0 - while(--i >= 0) r[i] = 0; - for(i = Math.max(n-this.t,0); i < a.t; ++i) - r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n); - r.clamp(); - r.drShiftTo(1,r); - } - - // Barrett modular reduction - function Barrett(m) { - // setup Barrett - this.r2 = nbi(); - this.q3 = nbi(); - BigInteger.ONE.dlShiftTo(2*m.t,this.r2); - this.mu = this.r2.divide(m); - this.m = m; - } - - function barrettConvert(x) { - if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m); - else if(x.compareTo(this.m) < 0) return x; - else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; } - } - - function barrettRevert(x) { return x; } - - // x = x mod m (HAC 14.42) - function barrettReduce(x) { - x.drShiftTo(this.m.t-1,this.r2); - if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); } - this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3); - this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2); - while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1); - x.subTo(this.r2,x); - while(x.compareTo(this.m) >= 0) x.subTo(this.m,x); - } - - // r = x^2 mod m; x != r - function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); } - - // r = x*y mod m; x,y != r - function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); } - - Barrett.prototype.convert = barrettConvert; - Barrett.prototype.revert = barrettRevert; - Barrett.prototype.reduce = barrettReduce; - Barrett.prototype.mulTo = barrettMulTo; - Barrett.prototype.sqrTo = barrettSqrTo; - - // (public) this^e % m (HAC 14.85) - function bnModPow(e,m) { - var i = e.bitLength(), k, r = nbv(1), z; - if(i <= 0) return r; - else if(i < 18) k = 1; - else if(i < 48) k = 3; - else if(i < 144) k = 4; - else if(i < 768) k = 5; - else k = 6; - if(i < 8) - z = new Classic(m); - else if(m.isEven()) - z = new Barrett(m); - else - z = new Montgomery(m); - - // precomputation - var g = [], n = 3, k1 = k-1, km = (1< 1) { - var g2 = nbi(); - z.sqrTo(g[1],g2); - while(n <= km) { - g[n] = nbi(); - z.mulTo(g2,g[n-2],g[n]); - n += 2; - } - } - - var j = e.t-1, w, is1 = true, r2 = nbi(), t; - i = nbits(e[j])-1; - while(j >= 0) { - if(i >= k1) w = (e[j]>>(i-k1))&km; - else { - w = (e[j]&((1<<(i+1))-1))<<(k1-i); - if(j > 0) w |= e[j-1]>>(this.DB+i-k1); - } - - n = k; - while((w&1) == 0) { w >>= 1; --n; } - if((i -= n) < 0) { i += this.DB; --j; } - if(is1) { // ret == 1, don't bother squaring or multiplying it - g[w].copyTo(r); - is1 = false; - } - else { - while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; } - if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; } - z.mulTo(r2,g[w],r); - } - - while(j >= 0 && (e[j]&(1< 0) { - x.rShiftTo(g,x); - y.rShiftTo(g,y); - } - while(x.signum() > 0) { - if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x); - if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y); - if(x.compareTo(y) >= 0) { - x.subTo(y,x); - x.rShiftTo(1,x); - } - else { - y.subTo(x,y); - y.rShiftTo(1,y); - } - } - if(g > 0) y.lShiftTo(g,y); - return y; - } - - // (protected) this % n, n < 2^26 - function bnpModInt(n) { - if(n <= 0) return 0; - var d = this.DV%n, r = (this.s<0)?n-1:0; - if(this.t > 0) - if(d == 0) r = this[0]%n; - else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n; - return r; - } - - // (public) 1/this % m (HAC 14.61) - function bnModInverse(m) { - var ac = m.isEven(); - if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO; - var u = m.clone(), v = this.clone(); - var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1); - while(u.signum() != 0) { - while(u.isEven()) { - u.rShiftTo(1,u); - if(ac) { - if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); } - a.rShiftTo(1,a); - } - else if(!b.isEven()) b.subTo(m,b); - b.rShiftTo(1,b); - } - while(v.isEven()) { - v.rShiftTo(1,v); - if(ac) { - if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); } - c.rShiftTo(1,c); - } - else if(!d.isEven()) d.subTo(m,d); - d.rShiftTo(1,d); - } - if(u.compareTo(v) >= 0) { - u.subTo(v,u); - if(ac) a.subTo(c,a); - b.subTo(d,b); - } - else { - v.subTo(u,v); - if(ac) c.subTo(a,c); - d.subTo(b,d); - } - } - if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO; - if(d.compareTo(m) >= 0) return d.subtract(m); - if(d.signum() < 0) d.addTo(m,d); else return d; - if(d.signum() < 0) return d.add(m); else return d; - } - - var lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509]; - var lplim = (1<<26)/lowprimes[lowprimes.length-1]; - - // (public) test primality with certainty >= 1-.5^t - function bnIsProbablePrime(t) { - var i, x = this.abs(); - if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) { - for(i = 0; i < lowprimes.length; ++i) - if(x[0] == lowprimes[i]) return true; - return false; - } - if(x.isEven()) return false; - i = 1; - while(i < lowprimes.length) { - var m = lowprimes[i], j = i+1; - while(j < lowprimes.length && m < lplim) m *= lowprimes[j++]; - m = x.modInt(m); - while(i < j) if(m%lowprimes[i++] == 0) return false; - } - return x.millerRabin(t); - } - - // (protected) true if probably prime (HAC 4.24, Miller-Rabin) - function bnpMillerRabin(t) { - var n1 = this.subtract(BigInteger.ONE); - var k = n1.getLowestSetBit(); - if(k <= 0) return false; - var r = n1.shiftRight(k); - t = (t+1)>>1; - if(t > lowprimes.length) t = lowprimes.length; - var a = nbi(); - for(var i = 0; i < t; ++i) { - a.fromInt(lowprimes[i]); - var y = a.modPow(r,this); - if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) { - var j = 1; - while(j++ < k && y.compareTo(n1) != 0) { - y = y.modPowInt(2,this); - if(y.compareTo(BigInteger.ONE) == 0) return false; - } - if(y.compareTo(n1) != 0) return false; - } - } - return true; - } - - - - // protected - BigInteger.prototype.chunkSize = bnpChunkSize; - BigInteger.prototype.toRadix = bnpToRadix; - BigInteger.prototype.fromRadix = bnpFromRadix; - BigInteger.prototype.fromNumber = bnpFromNumber; - BigInteger.prototype.bitwiseTo = bnpBitwiseTo; - BigInteger.prototype.changeBit = bnpChangeBit; - BigInteger.prototype.addTo = bnpAddTo; - BigInteger.prototype.dMultiply = bnpDMultiply; - BigInteger.prototype.dAddOffset = bnpDAddOffset; - BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo; - BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo; - BigInteger.prototype.modInt = bnpModInt; - BigInteger.prototype.millerRabin = bnpMillerRabin; - - // public - BigInteger.prototype.clone = bnClone; - BigInteger.prototype.intValue = bnIntValue; - BigInteger.prototype.byteValue = bnByteValue; - BigInteger.prototype.shortValue = bnShortValue; - BigInteger.prototype.signum = bnSigNum; - BigInteger.prototype.toByteArray = bnToByteArray; - BigInteger.prototype.equals = bnEquals; - BigInteger.prototype.min = bnMin; - BigInteger.prototype.max = bnMax; - BigInteger.prototype.and = bnAnd; - BigInteger.prototype.or = bnOr; - BigInteger.prototype.xor = bnXor; - BigInteger.prototype.andNot = bnAndNot; - BigInteger.prototype.not = bnNot; - BigInteger.prototype.shiftLeft = bnShiftLeft; - BigInteger.prototype.shiftRight = bnShiftRight; - BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit; - BigInteger.prototype.bitCount = bnBitCount; - BigInteger.prototype.testBit = bnTestBit; - BigInteger.prototype.setBit = bnSetBit; - BigInteger.prototype.clearBit = bnClearBit; - BigInteger.prototype.flipBit = bnFlipBit; - BigInteger.prototype.add = bnAdd; - BigInteger.prototype.subtract = bnSubtract; - BigInteger.prototype.multiply = bnMultiply; - BigInteger.prototype.divide = bnDivide; - BigInteger.prototype.remainder = bnRemainder; - BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder; - BigInteger.prototype.modPow = bnModPow; - BigInteger.prototype.modInverse = bnModInverse; - BigInteger.prototype.pow = bnPow; - BigInteger.prototype.gcd = bnGCD; - BigInteger.prototype.isProbablePrime = bnIsProbablePrime; - - // BigInteger interfaces not implemented in jsbn: - - // BigInteger(int signum, byte[] magnitude) - // double doubleValue() - // float floatValue() - // int hashCode() - // long longValue() - // static BigInteger valueOf(long val) - - - - ////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////// - // END OF copy-and-paste of jsbn. - - - - BigInteger.NEGATIVE_ONE = BigInteger.ONE.negate(); - - - // Other methods we need to add for compatibilty with js-numbers numeric tower. - - // add is implemented above. - // subtract is implemented above. - // multiply is implemented above. - // equals is implemented above. - // abs is implemented above. - // negate is defined above. - - // makeBignum: string -> BigInteger - var makeBignum = function(s) { - if (typeof(s) === 'number') { s = s + ''; } - s = expandExponent(s); - return new BigInteger(s, 10); - }; - - var zerostring = function(n) { - var buf = []; - for (var i = 0; i < n; i++) { - buf.push('0'); - } - return buf.join(''); - }; - - - BigInteger.prototype.level = 0; - BigInteger.prototype.liftTo = function(target) { - if (target.level === 1) { - return new Rational(this, 1); - } - if (target.level === 2) { - var fixrep = this.toFixnum(); - if (fixrep === Number.POSITIVE_INFINITY) - return TOO_POSITIVE_TO_REPRESENT; - if (fixrep === Number.NEGATIVE_INFINITY) - return TOO_NEGATIVE_TO_REPRESENT; - return new FloatPoint(fixrep); - } - if (target.level === 3) { - return new Complex(this, 0); - } - return throwRuntimeError("invalid level for BigInteger lift", this, target); - }; - - BigInteger.prototype.isFinite = function() { - return true; - }; - - BigInteger.prototype.isInteger = function() { - return true; - }; - - BigInteger.prototype.isRational = function() { - return true; - }; - - BigInteger.prototype.isReal = function() { - return true; - }; - - BigInteger.prototype.isExact = function() { - return true; - }; - - BigInteger.prototype.isInexact = function() { - return false; - }; - - BigInteger.prototype.toExact = function() { - return this; - }; - - BigInteger.prototype.toInexact = function() { - return FloatPoint.makeInstance(this.toFixnum()); - }; - - BigInteger.prototype.toFixnum = function() { - var result = 0, str = this.toString(), i; - if (str[0] === '-') { - for (i=1; i < str.length; i++) { - result = result * 10 + Number(str[i]); - } - return -result; - } else { - for (i=0; i < str.length; i++) { - result = result * 10 + Number(str[i]); - } - return result; - } - }; - - - BigInteger.prototype.greaterThan = function(other) { - return this.compareTo(other) > 0; - }; - - BigInteger.prototype.greaterThanOrEqual = function(other) { - return this.compareTo(other) >= 0; - }; - - BigInteger.prototype.lessThan = function(other) { - return this.compareTo(other) < 0; - }; - - BigInteger.prototype.lessThanOrEqual = function(other) { - return this.compareTo(other) <= 0; - }; - - // divide: scheme-number -> scheme-number - // WARNING NOTE: we override the old version of divide. - BigInteger.prototype.divide = function(other) { - var quotientAndRemainder = bnDivideAndRemainder.call(this, other); - if (quotientAndRemainder[1].compareTo(BigInteger.ZERO) === 0) { - return quotientAndRemainder[0]; - } else { - var result = add(quotientAndRemainder[0], - Rational.makeInstance(quotientAndRemainder[1], other)); - return result; - } - }; - - BigInteger.prototype.numerator = function() { - return this; - }; - - BigInteger.prototype.denominator = function() { - return 1; - }; - - - (function() { - // Classic implementation of Newton-Ralphson square-root search, - // adapted for integer-sqrt. - // http://en.wikipedia.org/wiki/Newton's_method#Square_root_of_a_number - var searchIter = function(n, guess) { - while(!(lessThanOrEqual(sqr(guess),n) && - lessThan(n,sqr(add(guess, 1))))) { - guess = floor(divide(add(guess, - floor(divide(n, guess))), - 2)); - } - return guess; - }; - - // integerSqrt: -> scheme-number - BigInteger.prototype.integerSqrt = function() { - var n; - if(sign(this) >= 0) { - return searchIter(this, this); - } else { - n = this.negate(); - return Complex.makeInstance(0, searchIter(n, n)); - } - }; - })(); - - - (function() { - // Get an approximation using integerSqrt, and then start another - // Newton-Ralphson search if necessary. - BigInteger.prototype.sqrt = function() { - var approx = this.integerSqrt(), fix; - if (eqv(sqr(approx), this)) { - return approx; - } - fix = toFixnum(this); - if (isFinite(fix)) { - if (fix >= 0) { - return FloatPoint.makeInstance(Math.sqrt(fix)); - } else { - return Complex.makeInstance( - 0, - FloatPoint.makeInstance(Math.sqrt(-fix))); - } - } else { - return approx; - } - }; - })(); - - - - - - // sqrt: -> scheme-number - // http://en.wikipedia.org/wiki/Newton's_method#Square_root_of_a_number - // Produce the square root. - - // floor: -> scheme-number - // Produce the floor. - BigInteger.prototype.floor = function() { - return this; - } - - // ceiling: -> scheme-number - // Produce the ceiling. - BigInteger.prototype.ceiling = function() { - return this; - } - - // conjugate: -> scheme-number - // Produce the conjugate. - - // magnitude: -> scheme-number - // Produce the magnitude. - - // log: -> scheme-number - // Produce the log. - - // angle: -> scheme-number - // Produce the angle. - - // atan: -> scheme-number - // Produce the arc tangent. - - // cos: -> scheme-number - // Produce the cosine. - - // sin: -> scheme-number - // Produce the sine. - - - // expt: scheme-number -> scheme-number - // Produce the power to the input. - BigInteger.prototype.expt = function(n) { - return bnPow.call(this, n); - }; - - - - // exp: -> scheme-number - // Produce e raised to the given power. - - // acos: -> scheme-number - // Produce the arc cosine. - - // asin: -> scheme-number - // Produce the arc sine. - - BigInteger.prototype.imaginaryPart = function() { - return 0; - } - BigInteger.prototype.realPart = function() { - return this; - } - - // round: -> scheme-number - // Round to the nearest integer. - - - - - - ////////////////////////////////////////////////////////////////////// - // toRepeatingDecimal: jsnum jsnum {limit: number}? -> [string, string, string] - // - // Given the numerator and denominator parts of a rational, - // produces the repeating-decimal representation, where the first - // part are the digits before the decimal, the second are the - // non-repeating digits after the decimal, and the third are the - // remaining repeating decimals. - // - // An optional limit on the decimal expansion can be provided, in which - // case the search cuts off if we go past the limit. - // If this happens, the third argument returned becomes '...' to indicate - // that the search was prematurely cut off. - var toRepeatingDecimal = (function() { - var getResidue = function(r, d, limit) { - var digits = []; - var seenRemainders = {}; - seenRemainders[r] = true; - while(true) { - if (limit-- <= 0) { - return [digits.join(''), '...'] - } - - var nextDigit = quotient( - multiply(r, 10), d); - var nextRemainder = remainder( - multiply(r, 10), - d); - digits.push(nextDigit.toString()); - if (seenRemainders[nextRemainder]) { - r = nextRemainder; - break; - } else { - seenRemainders[nextRemainder] = true; - r = nextRemainder; - } - } - - var firstRepeatingRemainder = r; - var repeatingDigits = []; - while (true) { - var nextDigit = quotient(multiply(r, 10), d); - var nextRemainder = remainder( - multiply(r, 10), - d); - repeatingDigits.push(nextDigit.toString()); - if (equals(nextRemainder, firstRepeatingRemainder)) { - break; - } else { - r = nextRemainder; - } - }; - - var digitString = digits.join(''); - var repeatingDigitString = repeatingDigits.join(''); - - while (digitString.length >= repeatingDigitString.length && - (digitString.substring( - digitString.length - repeatingDigitString.length) - === repeatingDigitString)) { - digitString = digitString.substring( - 0, digitString.length - repeatingDigitString.length); - } - - return [digitString, repeatingDigitString]; - - }; - - return function(n, d, options) { - // default limit on decimal expansion; can be overridden - var limit = 512; - if (options && typeof(options.limit) !== 'undefined') { - limit = options.limit; - } - if (! isInteger(n)) { - throwRuntimeError('toRepeatingDecimal: n ' + n.toString() + - " is not an integer."); - } - if (! isInteger(d)) { - throwRuntimeError('toRepeatingDecimal: d ' + d.toString() + - " is not an integer."); - } - if (equals(d, 0)) { - throwRuntimeError('toRepeatingDecimal: d equals 0'); - } - if (lessThan(d, 0)) { - throwRuntimeError('toRepeatingDecimal: d < 0'); - } - var sign = (lessThan(n, 0) ? "-" : ""); - n = abs(n); - var beforeDecimalPoint = sign + quotient(n, d); - var afterDecimals = getResidue(remainder(n, d), d, limit); - return [beforeDecimalPoint].concat(afterDecimals); - }; - })(); - ////////////////////////////////////////////////////////////////////// - - - - - // External interface of js-numbers: - - Numbers['fromFixnum'] = fromFixnum; - Numbers['fromString'] = fromString; - Numbers['makeBignum'] = makeBignum; - Numbers['makeRational'] = Rational.makeInstance; - Numbers['makeFloat'] = FloatPoint.makeInstance; - Numbers['makeComplex'] = Complex.makeInstance; - Numbers['makeComplexPolar'] = makeComplexPolar; - - Numbers['pi'] = FloatPoint.pi; - Numbers['e'] = FloatPoint.e; - Numbers['nan'] = FloatPoint.nan; - Numbers['negative_inf'] = FloatPoint.neginf; - Numbers['inf'] = FloatPoint.inf; - Numbers['negative_one'] = -1; // Rational.NEGATIVE_ONE; - Numbers['zero'] = 0; // Rational.ZERO; - Numbers['one'] = 1; // Rational.ONE; - Numbers['i'] = plusI; - Numbers['negative_i'] = minusI; - Numbers['negative_zero'] = NEGATIVE_ZERO; - - Numbers['onThrowRuntimeError'] = onThrowRuntimeError; - Numbers['isSchemeNumber'] = isSchemeNumber; - Numbers['isRational'] = isRational; - Numbers['isReal'] = isReal; - Numbers['isExact'] = isExact; - Numbers['isInexact'] = isInexact; - Numbers['isInteger'] = isInteger; - - Numbers['toFixnum'] = toFixnum; - Numbers['toExact'] = toExact; - Numbers['toInexact'] = toInexact; - Numbers['add'] = add; - Numbers['subtract'] = subtract; - Numbers['multiply'] = multiply; - Numbers['divide'] = divide; - Numbers['equals'] = equals; - Numbers['eqv'] = eqv; - Numbers['approxEquals'] = approxEquals; - Numbers['greaterThanOrEqual'] = greaterThanOrEqual; - Numbers['lessThanOrEqual'] = lessThanOrEqual; - Numbers['greaterThan'] = greaterThan; - Numbers['lessThan'] = lessThan; - Numbers['expt'] = expt; - Numbers['exp'] = exp; - Numbers['modulo'] = modulo; - Numbers['numerator'] = numerator; - Numbers['denominator'] = denominator; - Numbers['integerSqrt'] = integerSqrt; - Numbers['sqrt'] = sqrt; - Numbers['abs'] = abs; - Numbers['quotient'] = quotient; - Numbers['remainder'] = remainder; - Numbers['floor'] = floor; - Numbers['ceiling'] = ceiling; - Numbers['conjugate'] = conjugate; - Numbers['magnitude'] = magnitude; - Numbers['log'] = log; - Numbers['angle'] = angle; - Numbers['tan'] = tan; - Numbers['atan'] = atan; - Numbers['cos'] = cos; - Numbers['sin'] = sin; - Numbers['tan'] = tan; - Numbers['acos'] = acos; - Numbers['asin'] = asin; - Numbers['cosh'] = cosh; - Numbers['sinh'] = sinh; - Numbers['imaginaryPart'] = imaginaryPart; - Numbers['realPart'] = realPart; - Numbers['round'] = round; - Numbers['sqr'] = sqr; - Numbers['gcd'] = gcd; - Numbers['lcm'] = lcm; - - Numbers['toRepeatingDecimal'] = toRepeatingDecimal; - - - - // The following exposes the class representations for easier - // integration with other projects. - Numbers['BigInteger'] = BigInteger; - Numbers['Rational'] = Rational; - Numbers['FloatPoint'] = FloatPoint; - Numbers['Complex'] = Complex; - - Numbers['MIN_FIXNUM'] = MIN_FIXNUM; - Numbers['MAX_FIXNUM'] = MAX_FIXNUM; - -})(); +var __PLTNUMBERS_TOP__;typeof exports!=="undefined"?__PLTNUMBERS_TOP__=exports:(this.jsnums||(this.jsnums={}),__PLTNUMBERS_TOP__=this.jsnums); +(function(){function f(a,b,c){a!=null&&("number"==typeof a?this.fromNumber(a,b,c):b==null&&"string"!=typeof a?this.fromString(a,256):this.fromString(a,b))}function p(){return new f(null)}function hb(a,b,c,e,j,d){for(;--d>=0;){var f=b*this[a++]+c[e]+j,j=Math.floor(f/67108864);c[e++]=f&67108863}return j}function ib(a,b,c,e,j,d){var f=b&32767;for(b>>=15;--d>=0;){var g=this[a]&32767,h=this[a++]>>15,i=b*g+h*f,g=f*g+((i&32767)<<15)+c[e]+(j&1073741823),j=(g>>>30)+(i>>>15)+b*h+(j>>>30);c[e++]=g&1073741823}return j} +function jb(a,b,c,e,j,d){var f=b&16383;for(b>>=14;--d>=0;){var g=this[a]&16383,h=this[a++]>>14,i=b*g+h*f,g=f*g+((i&16383)<<14)+c[e]+j,j=(g>>28)+(i>>14)+b*h;c[e++]=g&268435455}return j}function xa(a,b){var c=ja[a.charCodeAt(b)];return c==null?-1:c}function N(a){var b=p();b.fromInt(a);return b}function Y(a){var b=this.s-a.s;if(b!=0)return b;var c=this.t,b=this.s<0?a.t-c:c-a.t;if(b!=0)return b;for(;--c>=0;)if((b=this[c]-a[c])!=0)return b;return 0}function ka(a){var b=1,c;if((c=a>>>16)!=0)a=c,b+=16;if((c= +a>>8)!=0)a=c,b+=8;if((c=a>>4)!=0)a=c,b+=4;if((c=a>>2)!=0)a=c,b+=2;a>>1!=0&&(b+=1);return b}function ya(a){var b=p();this.abs().divRemTo(a,null,b);this.s<0&&b.compareTo(f.ZERO)>0&&a.subTo(b,b);return b}function P(a){this.m=a}function Q(a){this.m=a;this.mp=a.invDigit();this.mpl=this.mp&32767;this.mph=this.mp>>15;this.um=(1<0&&(b.rShiftTo(e,b),a.rShiftTo(e,a));for(;b.signum()>0;)(c=b.getLowestSetBit())>0&&b.rShiftTo(c,b),(c=a.getLowestSetBit())>0&&a.rShiftTo(c,a),b.compareTo(a)>=0?(b.subTo(a,b),b.rShiftTo(1,b)):(a.subTo(b,a),a.rShiftTo(1,a));e>0&&a.lShiftTo(e,a);return a}var h=__PLTNUMBERS_TOP__,H=function(a,b,c){c= +c||{};return function(e,j){if(c.isXSpecialCase&&c.isXSpecialCase(e))return c.onXSpecialCase(e,j);if(c.isYSpecialCase&&c.isYSpecialCase(j))return c.onYSpecialCase(e,j);if(typeof e==="number"&&typeof j==="number")return a(e,j);typeof e==="number"&&(e=Ka(e,j));typeof j==="number"&&(j=Ka(j,e));e.level=a[2].length- +1?a[1]+a[2].substring(1)+Ma(b-(a[2].length-1)):a[1]+a[2].substring(1,1+b)):a},Ma=function(a){var b=[];b.length=a;for(var c=0;c=b},function(a,b){(!E(a)||!E(b))&&l(">=: couldn't be applied to complex number",a,b);return a.greaterThanOrEqual(b)}),da=H(function(a,b){return a<=b},function(a,b){(!E(a)||!E(b))&&l("<=: couldn't be applied to complex number",a,b);return a.lessThanOrEqual(b)}),U=H(function(a,b){return a>b},function(a,b){(!E(a)|| +!E(b))&&l(">: couldn't be applied to complex number",a,b);return a.greaterThan(b)}),J=H(function(a,b){return a=0?(a=Math.sqrt(a),Math.floor(a)===a?a:d.makeInstance(a)): +g.makeInstance(0,D(-a)):a.sqrt()},A=function(a){return typeof a==="number"?Math.abs(a):a.abs()},z=function(a){return typeof a==="number"?a:a.floor()},Ra=function(a){return typeof a==="number"?a:a.ceiling()},Sa=function(a){return typeof a==="number"?a:a.conjugate()},na=function(a){return q(a,1)?0:typeof a==="number"?d.makeInstance(Math.log(a)):a.log()},Ta=function(a){return typeof a==="number"?a>0?0:d.pi:a.angle()},Ua=function(a){return q(a,0)?0:typeof a==="number"?d.makeInstance(Math.tan(a)):a.tan()}, +wa=function(a){return q(a,0)?0:typeof a==="number"?d.makeInstance(Math.atan(a)):a.atan()},oa=function(a){return q(a,0)?1:typeof a==="number"?d.makeInstance(Math.cos(a)):a.cos()},pa=function(a){return q(a,0)?0:typeof a==="number"?d.makeInstance(Math.sin(a)):a.sin()},Va=function(a){return q(a,1)?0:typeof a==="number"?d.makeInstance(Math.acos(a)):a.acos()},Wa=function(a){return q(a,0)?0:typeof a==="number"?d.makeInstance(Math.asin(a)):a.asin()},ca=function(a){return typeof a==="number"?0:a.imaginaryPart()}, +M=function(a){return typeof a==="number"?a:a.realPart()},Xa=function(a){return typeof a==="number"?a:a.round()},X=function(a){return k(a,a)},Ya=function(a){t(a)||l("integer-sqrt: the argument "+a.toString()+" is not an integer.",a);return typeof a==="number"?a<0?g.makeInstance(0,Math.floor(Math.sqrt(-a))):Math.floor(Math.sqrt(a)):a.integerSqrt()},qa=function(a,b){t(a)||l("quotient: the first argument "+a.toString()+" is not an integer.",a);t(b)||l("quotient: the second argument "+b.toString()+" is not an integer.", +b);return fa(a,b)},ra=function(a,b){t(a)||l("remainder: the first argument "+a.toString()+" is not an integer.",a);t(b)||l("remainder: the second argument "+b.toString()+" is not an integer.",b);return mb(a,b)},K=function(a){return a<-9E15||9E15 +b},function(a,b){return Y.call(a,b)>0},{doNotCoerseToFloating:!0}),ta=n(function(a,b){return a=b},function(a,b){return Y.call(a,b)>=0},{doNotCoerseToFloating:!0}),pb=n(function(a,b){return a<=b},function(a,b){return Y.call(a,b)<=0},{doNotCoerseToFloating:!0}),i=function(a,b){this.n=a;this.d=b};i.prototype.toString=function(){return T(this.d)?this.n.toString()+"":this.n.toString()+"/"+this.d.toString()}; +i.prototype.level=1;i.prototype.liftTo=function(a){return a.level===2?new d(B(this.n,this.d)):a.level===3?new g(this,0):l("invalid level of Number",this,a)};i.prototype.isFinite=function(){return!0};i.prototype.equals=function(a){return a instanceof i&&$a(this.n,a.n)&&$a(this.d,a.d)};i.prototype.isInteger=function(){return T(this.d)};i.prototype.isRational=function(){return!0};i.prototype.isReal=function(){return!0};i.prototype.add=function(a){return i.makeInstance(nb(u(this.n,a.d),u(this.d,a.n)), +u(this.d,a.d))};i.prototype.subtract=function(a){return i.makeInstance(ob(u(this.n,a.d),u(this.d,a.n)),u(this.d,a.d))};i.prototype.negate=function(){return i.makeInstance(-this.n,this.d)};i.prototype.multiply=function(a){return i.makeInstance(u(this.n,a.n),u(this.d,a.d))};i.prototype.divide=function(a){(r(this.d)||r(a.n))&&l("/: division by zero",this,a);return i.makeInstance(u(this.n,a.d),u(this.d,a.n))};i.prototype.toExact=function(){return this};i.prototype.toInexact=function(){return d.makeInstance(this.toFixnum())}; +i.prototype.isExact=function(){return!0};i.prototype.isInexact=function(){return!1};i.prototype.toFixnum=function(){return B(this.n,this.d)};i.prototype.numerator=function(){return this.n};i.prototype.denominator=function(){return this.d};i.prototype.greaterThan=function(a){return ab(u(this.n,a.d),u(this.d,a.n))};i.prototype.greaterThanOrEqual=function(a){return bb(u(this.n,a.d),u(this.d,a.n))};i.prototype.lessThan=function(a){return ta(u(this.n,a.d),u(this.d,a.n))};i.prototype.lessThanOrEqual=function(a){return pb(u(this.n, +a.d),u(this.d,a.n))};i.prototype.integerSqrt=function(){var a=D(this);return va(a)?S(z(a)):E(a)?S(z(a)):g.makeInstance(S(z(M(a))),S(z(ca(a))))};i.prototype.sqrt=function(){if(bb(this.n,0)){var a=D(this.n),b=D(this.d);return s(z(a),a)&&s(z(b),b)?i.makeInstance(a,b):d.makeInstance(B(a,b))}else return a=D(x(this.n)),b=D(this.d),s(z(a),a)&&s(z(b),b)?g.makeInstance(0,i.makeInstance(a,b)):g.makeInstance(0,d.makeInstance(B(a,b)))};i.prototype.abs=function(){return i.makeInstance(A(this.n),this.d)};i.prototype.floor= +function(){var a=fa(this.n,this.d);return ta(this.n,0)?w(a,1):a};i.prototype.ceiling=function(){var a=fa(this.n,this.d);return ta(this.n,0)?a:m(a,1)};i.prototype.conjugate=function(){return this};i.prototype.magnitude=i.prototype.abs;i.prototype.log=function(){return d.makeInstance(Math.log(this.n/this.d))};i.prototype.angle=function(){return r(this.n)?0:ab(this.n,0)?0:d.pi};i.prototype.tan=function(){return d.makeInstance(Math.tan(B(this.n,this.d)))};i.prototype.atan=function(){return d.makeInstance(Math.atan(B(this.n, +this.d)))};i.prototype.cos=function(){return d.makeInstance(Math.cos(B(this.n,this.d)))};i.prototype.sin=function(){return d.makeInstance(Math.sin(B(this.n,this.d)))};i.prototype.expt=function(a){return O(a)&&ma(a,0)?Za(this,a):d.makeInstance(Math.pow(B(this.n,this.d),B(a.n,a.d)))};i.prototype.exp=function(){return d.makeInstance(Math.exp(B(this.n,this.d)))};i.prototype.acos=function(){return d.makeInstance(Math.acos(B(this.n,this.d)))};i.prototype.asin=function(){return d.makeInstance(Math.asin(B(this.n, +this.d)))};i.prototype.imaginaryPart=function(){return 0};i.prototype.realPart=function(){return this};i.prototype.round=function(){if(s(this.d,2)){var a=B(this.n,this.d),b=Math.floor(a),a=Math.ceil(a);return r(b%2)?b:a}else return Math.round(this.n/this.d)};i.makeInstance=function(a,b){a===void 0&&l("n undefined",a,b);b===void 0&&(b=1);ta(b,0)&&(a=x(a),b=x(b));var c=sa(A(a),A(b)),a=fa(a,c),b=fa(b,c);return T(b)||r(a)?a:new i(a,b)};var d=function(a){this.n=a},ga=new d(Number.NaN),n=new d(Number.POSITIVE_INFINITY), +cb=new d(Number.NEGATIVE_INFINITY),db=new d(Number.POSITIVE_INFINITY),eb=new d(Number.NEGATIVE_INFINITY),L=new d(0),fb=new d(0);d.pi=new d(Math.PI);d.e=new d(Math.E);d.nan=ga;d.inf=n;d.neginf=cb;d.makeInstance=function(a){if(isNaN(a))return d.nan;else if(a===Number.POSITIVE_INFINITY)return d.inf;else if(a===Number.NEGATIVE_INFINITY)return d.neginf;else if(a===0)return 1/a===-Infinity?L:fb;return new d(a)};d.prototype.isExact=function(){return!1};d.prototype.isInexact=function(){return!0};d.prototype.isFinite= +function(){return isFinite(this.n)||this===db||this===eb};d.prototype.toExact=function(){(!isFinite(this.n)||isNaN(this.n))&&l("toExact: no exact representation for "+this,this);var a=this.n.toString().match(/^(.*)\.(.*)$/);return a?(parseInt(a[1]),parseInt(a[2]),a=Math.pow(10,a[2].length),i.makeInstance(Math.round(this.n*a),a)):this.n};d.prototype.toInexact=function(){return this};d.prototype.isInexact=function(){return!0};d.prototype.level=2;d.prototype.liftTo=function(a){return a.level===3?new g(this, +0):l("invalid level of Number",this,a)};d.prototype.toString=function(){if(isNaN(this.n))return"+nan.0";if(this.n===Number.POSITIVE_INFINITY)return"+inf.0";if(this.n===Number.NEGATIVE_INFINITY)return"-inf.0";if(this===L)return"-0.0";var a=this.n.toString();return a.match("\\.")?a:a+".0"};d.prototype.equals=function(a){return a instanceof d&&this.n===a.n};d.prototype.isRational=function(){return this.isFinite()};d.prototype.isInteger=function(){return this.isFinite()&&this.n===Math.floor(this.n)}; +d.prototype.isReal=function(){return!0};var ha=function(a){return J(a,0)?-1:U(a,0)?1:a===L?-1:0};d.prototype.add=function(a){return this.isFinite()&&a.isFinite()?d.makeInstance(this.n+a.n):isNaN(this.n)||isNaN(a.n)?ga:this.isFinite()&&!a.isFinite()?a:!this.isFinite()&&a.isFinite()?this:ha(this)*ha(a)===1?this:ga};d.prototype.subtract=function(a){return this.isFinite()&&a.isFinite()?d.makeInstance(this.n-a.n):isNaN(this.n)||isNaN(a.n)?ga:!this.isFinite()&&!a.isFinite()?ha(this)===ha(a)?ga:this:this.isFinite()? +k(a,-1):this};d.prototype.negate=function(){return d.makeInstance(-this.n)};d.prototype.multiply=function(a){return d.makeInstance(this.n*a.n)};d.prototype.divide=function(a){return d.makeInstance(this.n/a.n)};d.prototype.toFixnum=function(){return this.n};d.prototype.numerator=function(){var a=this.n.toString().match(/^(.*)\.(.*)$/);if(a){var b=parseInt(a[2]),a=Math.pow(10,a[2].length),b=sa(a,b);return d.makeInstance(Math.round(this.n*(a/b)))}else return this};d.prototype.denominator=function(){var a= +this.n.toString().match(/^(.*)\.(.*)$/);if(a){var b=parseInt(a[2]),a=Math.pow(10,a[2].length),b=sa(a,b);return d.makeInstance(Math.round(a/b))}else return d.makeInstance(1)};d.prototype.floor=function(){return d.makeInstance(Math.floor(this.n))};d.prototype.ceiling=function(){return d.makeInstance(Math.ceil(this.n))};d.prototype.greaterThan=function(a){return this.n>a.n};d.prototype.greaterThanOrEqual=function(a){return this.n>=a.n};d.prototype.lessThan=function(a){return this.n=0?d.makeInstance(Math.floor(Math.sqrt(this.n))):g.makeInstance(fb,d.makeInstance(Math.floor(Math.sqrt(-this.n))));else l("integerSqrt: can only be applied to an integer",this)};d.prototype.sqrt=function(){return this.n<0?g.makeInstance(0,d.makeInstance(Math.sqrt(-this.n))):d.makeInstance(Math.sqrt(this.n))};d.prototype.abs=function(){return d.makeInstance(Math.abs(this.n))};d.prototype.log= +function(){return this.n<0?(new g(this,0)).log():d.makeInstance(Math.log(this.n))};d.prototype.angle=function(){return 0===this.n?0:this.n>0?0:d.pi};d.prototype.tan=function(){return d.makeInstance(Math.tan(this.n))};d.prototype.atan=function(){return d.makeInstance(Math.atan(this.n))};d.prototype.cos=function(){return d.makeInstance(Math.cos(this.n))};d.prototype.sin=function(){return d.makeInstance(Math.sin(this.n))};d.prototype.expt=function(a){return this.n===1?(a.isFinite()||isNaN(a.n),this): +d.makeInstance(Math.pow(this.n,a.n))};d.prototype.exp=function(){return d.makeInstance(Math.exp(this.n))};d.prototype.acos=function(){return d.makeInstance(Math.acos(this.n))};d.prototype.asin=function(){return d.makeInstance(Math.asin(this.n))};d.prototype.imaginaryPart=function(){return 0};d.prototype.realPart=function(){return this};d.prototype.round=function(){return isFinite(this.n)?this===L?this:Math.abs(Math.floor(this.n)-this.n)===0.5?Math.floor(this.n)%2===0?d.makeInstance(Math.floor(this.n)): +d.makeInstance(Math.ceil(this.n)):d.makeInstance(Math.round(this.n)):this};d.prototype.conjugate=function(){return this};d.prototype.magnitude=d.prototype.abs;var g=function(a,b){this.r=a;this.i=b};g.makeInstance=function(a,b){b===void 0&&(b=0);if(W(b)&&t(b)&&r(b))return a;if(aa(a)||aa(b))a=ba(a),b=ba(b);return new g(a,b)};g.prototype.toString=function(){var a=this.r.toString(),b=this.i.toString();return b[0]==="-"||b[0]==="+"?a+b+"i":a+"+"+b+"i"};g.prototype.isFinite=function(){return(typeof this.r=== +"number"?isFinite(this.r):this.r.isFinite())&&(typeof this.i==="number"?isFinite(this.i):this.i.isFinite())};g.prototype.isRational=function(){return va(this.r)&&q(this.i,0)};g.prototype.isInteger=function(){return t(this.r)&&q(this.i,0)};g.prototype.toExact=function(){return g.makeInstance(S(this.r),S(this.i))};g.prototype.toInexact=function(){return g.makeInstance(ba(this.r),ba(this.i))};g.prototype.isExact=function(){return W(this.r)&&W(this.i)};g.prototype.isInexact=function(){return aa(this.r)|| +aa(this.i)};g.prototype.level=3;g.prototype.liftTo=function(a){l("Don't know how to lift Complex number",this,a)};g.prototype.equals=function(a){return a instanceof g&&s(this.r,a.r)&&s(this.i,a.i)};g.prototype.greaterThan=function(a){(!this.isReal()||!a.isReal())&&l(">: expects argument of type real number",this,a);return U(this.r,a.r)};g.prototype.greaterThanOrEqual=function(a){(!this.isReal()||!a.isReal())&&l(">=: expects argument of type real number",this,a);return ma(this.r,a.r)};g.prototype.lessThan= +function(a){(!this.isReal()||!a.isReal())&&l("<: expects argument of type real number",this,a);return J(this.r,a.r)};g.prototype.lessThanOrEqual=function(a){(!this.isReal()||!a.isReal())&&l("<=: expects argument of type real number",this,a);return da(this.r,a.r)};g.prototype.abs=function(){s(this.i,0).valueOf()||l("abs: expects argument of type real number",this);return A(this.r)};g.prototype.toFixnum=function(){s(this.i,0).valueOf()||l("toFixnum: expects argument of type real number",this);return I(this.r)}; +g.prototype.numerator=function(){this.isReal()||l("numerator: can only be applied to real number",this);return ea(this.n)};g.prototype.denominator=function(){this.isReal()||l("floor: can only be applied to real number",this);return Qa(this.n)};g.prototype.add=function(a){return g.makeInstance(m(this.r,a.r),m(this.i,a.i))};g.prototype.subtract=function(a){return g.makeInstance(w(this.r,a.r),w(this.i,a.i))};g.prototype.negate=function(){return g.makeInstance(x(this.r),x(this.i))};g.prototype.multiply= +function(a){if(a.isReal())return g.makeInstance(k(this.r,a.r),k(this.i,a.r));var b=w(k(this.r,a.r),k(this.i,a.i)),a=m(k(this.r,a.i),k(this.i,a.r));return g.makeInstance(b,a)};g.prototype.divide=function(a){var b,c,e,j,d;return a.isReal()?g.makeInstance(o(this.r,a.r),o(this.i,a.r)):this.isInexact()||a.isInexact()?(b=this.r,c=this.i,e=a.r,j=a.i,da(A(j),A(e))?(d=o(j,e),a=o(m(b,k(c,d)),m(e,k(j,d))),b=o(w(c,k(b,d)),m(e,k(j,d)))):(d=o(e,j),a=o(m(k(b,d),c),m(k(e,d),j)),b=o(w(k(c,d),b),m(k(e,d),j))),g.makeInstance(a, +b)):(c=Sa(a),b=k(this,c),c=M(k(a,c)),g.makeInstance(o(M(b),c),o(ca(b),c)))};g.prototype.conjugate=function(){return g.makeInstance(this.r,w(0,this.i))};g.prototype.magnitude=function(){var a=m(k(this.r,this.r),k(this.i,this.i));return D(a)};g.prototype.isReal=function(){return q(this.i,0)};g.prototype.integerSqrt=function(){if(t(this))return Ya(this.r);else l("integerSqrt: can only be applied to an integer",this)};g.prototype.sqrt=function(){if(this.isReal())return D(this.r);var a=m(this.magnitude(), +this.r),b=D(o(a,2)),a=o(this.i,D(k(a,2)));return g.makeInstance(b,a)};g.prototype.log=function(){var a=this.magnitude(),b=this.angle();return m(na(a),k(b,G))};g.prototype.angle=function(){if(this.isReal())return Ta(this.r);if(s(0,this.r)){var a=o(d.pi,2);return U(this.i,0)?a:x(a)}else return a=wa(o(A(this.i),A(this.r))),U(this.r,0)?U(this.i,0)?a:x(a):U(this.i,0)?w(d.pi,a):w(a,d.pi)};var G=g.makeInstance(0,1),gb=g.makeInstance(0,-1);g.prototype.tan=function(){return o(this.sin(),this.cos())};g.prototype.atan= +function(){return s(this,G)||s(this,gb)?cb:k(G,k(d.makeInstance(0.5),na(o(m(G,this),m(G,w(0,this))))))};g.prototype.cos=function(){if(this.isReal())return oa(this.r);var a=k(this,G),b=x(a),a=m(F(a),F(b));return o(a,2)};g.prototype.sin=function(){if(this.isReal())return pa(this.r);var a=k(this,G),b=x(a),c=g.makeInstance(0,2),a=w(F(a),F(b));return o(a,c)};g.prototype.expt=function(a){if(O(a)&&ma(a,0))return Za(this,a);a=k(a,this.log());return F(a)};g.prototype.exp=function(){var a=F(this.r),b=oa(this.i), +c=pa(this.i);return k(a,m(b,k(c,G)))};g.prototype.acos=function(){if(this.isReal())return Va(this.r);var a=o(d.pi,2),b=k(this,G),c=D(w(1,X(this))),b=na(m(b,c)),b=k(b,G);return m(a,b)};g.prototype.asin=function(){if(this.isReal())return Wa(this.r);var a=w(1,X(this)),a=D(a);return k(2,wa(o(this,m(1,a))))};g.prototype.ceiling=function(){this.isReal()||l("ceiling: can only be applied to real number",this);return Ra(this.r)};g.prototype.floor=function(){this.isReal()||l("floor: can only be applied to real number", +this);return z(this.r)};g.prototype.imaginaryPart=function(){return this.i};g.prototype.realPart=function(){return this.r};g.prototype.round=function(){this.isReal()||l("round: can only be applied to real number",this);return Xa(this.r)};var qb=/^([+-]?\d+)\/(\d+)$/,rb=/^([+-]?[\d\w/\.]*)([+-])([\d\w/\.]*)i$/,sb=/^[+-]?\d+$/,tb=/^([+-]?\d*)\.(\d*)$/,La=/^([+-]?\d*\.?\d*)[Ee](\+?\d+)$/,ia=function(a){var b=a.match(qb);if(b)return i.makeInstance(ia(b[1]),ia(b[2]));if(b=a.match(rb))return g.makeInstance(ia(b[1]|| +"0"),ia(b[2]+(b[3]||"1")));if(a==="+nan.0"||a==="-nan.0")return d.nan;if(a==="+inf.0")return d.inf;if(a==="-inf.0")return d.neginf;if(a==="-0.0")return L;return a.match(tb)||a.match(La)?d.makeInstance(Number(a)):a.match(sb)?(b=Number(a),K(b)?v(a):b):!1};typeof navigator!=="undefined"&&navigator.appName=="Microsoft Internet Explorer"?(f.prototype.am=ib,n=30):typeof navigator!=="undefined"&&navigator.appName!="Netscape"?(f.prototype.am=hb,n=26):(f.prototype.am=jb,n=28);f.prototype.DB=n;f.prototype.DM= +(1<=0?a.mod(this.m):a};P.prototype.revert=function(a){return a};P.prototype.reduce=function(a){a.divRemTo(this.m,null,a)};P.prototype.mulTo=function(a,b,c){a.multiplyTo(b,c);this.reduce(c)}; +P.prototype.sqrTo=function(a,b){a.squareTo(b);this.reduce(b)};Q.prototype.convert=function(a){var b=p();a.abs().dlShiftTo(this.m.t,b);b.divRemTo(this.m,null,b);a.s<0&&b.compareTo(f.ZERO)>0&&this.m.subTo(b,b);return b};Q.prototype.revert=function(a){var b=p();a.copyTo(b);this.reduce(b);return b};Q.prototype.reduce=function(a){for(;a.t<=this.mt2;)a[a.t++]=0;for(var b=0;b>15)*this.mpl&this.um)<<15)&a.DM,c=b+this.m.t;for(a[c]+=this.m.am(0, +e,a,b,0,this.m.t);a[c]>=a.DV;)a[c]-=a.DV,a[++c]++}a.clamp();a.drShiftTo(this.m.t,a);a.compareTo(this.m)>=0&&a.subTo(this.m,a)};Q.prototype.mulTo=function(a,b,c){a.multiplyTo(b,c);this.reduce(c)};Q.prototype.sqrTo=function(a,b){a.squareTo(b);this.reduce(b)};f.prototype.copyTo=function(a){for(var b=this.t-1;b>=0;--b)a[b]=this[b];a.t=this.t;a.s=this.s};f.prototype.fromInt=function(a){this.t=1;this.s=a<0?-1:0;a>0?this[0]=a:a<-1?this[0]=a+DV:this.t=0};f.prototype.fromString=function(a,b){var c;if(b==16)c= +4;else if(b==8)c=3;else if(b==256)c=8;else if(b==2)c=1;else if(b==32)c=5;else if(b==4)c=2;else{this.fromRadix(a,b);return}this.s=this.t=0;for(var e=a.length,j=!1,d=0;--e>=0;){var g=c==8?a[e]&255:xa(a,e);g<0?a.charAt(e)=="-"&&(j=!0):(j=!1,d==0?this[this.t++]=g:d+c>this.DB?(this[this.t-1]|=(g&(1<>this.DB-d):this[this.t-1]|=g<=this.DB&&(d-=this.DB))}if(c==8&&(a[0]&128)!=0)this.s=-1,d>0&&(this[this.t-1]|=(1<0&&this[this.t-1]==a;)--this.t};f.prototype.dlShiftTo=function(a,b){var c;for(c=this.t-1;c>=0;--c)b[c+a]=this[c];for(c=a-1;c>=0;--c)b[c]=0;b.t=this.t+a;b.s=this.s};f.prototype.drShiftTo=function(a,b){for(var c=a;c=0;--h)b[h+f+1]=this[h]>> +e|g,g=(this[h]&d)<=0;--h)b[h]=0;b[f]=g;b.t=this.t+f+1;b.s=this.s;b.clamp()};f.prototype.rShiftTo=function(a,b){b.s=this.s;var c=Math.floor(a/this.DB);if(c>=this.t)b.t=0;else{var e=a%this.DB,d=this.DB-e,f=(1<>e;for(var g=c+1;g>e;e>0&&(b[this.t-c-1]|=(this.s&f)<>=this.DB;if(a.t< +this.t){for(e-=a.s;c>=this.DB;e+=this.s}else{for(e+=this.s;c>=this.DB;e-=a.s}b.s=e<0?-1:0;e<-1?b[c++]=this.DV+e:e>0&&(b[c++]=e);b.t=c;b.clamp()};f.prototype.multiplyTo=function(a,b){var c=this.abs(),e=a.abs(),d=c.t;for(b.t=d+e.t;--d>=0;)b[d]=0;for(d=0;d=0;)a[c]=0;for(c= +0;c=b.DV)a[c+b.t]-=b.DV,a[c+b.t+1]=1}a.t>0&&(a[a.t-1]+=b.am(c,b[c],a,2*c,0,1));a.s=0;a.clamp()};f.prototype.divRemTo=function(a,b,c){var e=a.abs();if(!(e.t<=0)){var d=this.abs();if(d.t0?(e.lShiftTo(i,g),d.lShiftTo(i,c)):(e.copyTo(g),d.copyTo(c));e=g.t;d=g[e-1];if(d!=0){var l=d*(1<1?g[e-2]>>this.F2:0),k=this.FV/l,l=(1<=0&&(c[c.t++]=1,c.subTo(q,c));f.ONE.dlShiftTo(e,q);for(q.subTo(g,g);g.t=0;){var r=c[--m]==d?this.DM:Math.floor(c[m]*k+(c[m-1]+n)*l);if((c[m]+=g.am(0,r,c,o,0,e))0&&c.rShiftTo(i,c);h<0&&f.ZERO.subTo(c,c)}}}};f.prototype.invDigit= +function(){if(this.t<1)return 0;var a=this[0];if((a&1)==0)return 0;var b=a&3,b=b*(2-(a&15)*b)&15,b=b*(2-(a&255)*b)&255,b=b*(2-((a&65535)*b&65535))&65535,b=b*(2-a*b%this.DV)%this.DV;return b>0?this.DV-b:-b};f.prototype.isEven=function(){return(this.t>0?this[0]&1:this.s)==0};f.prototype.exp=function(a,b){if(a>4294967295||a<1)return f.ONE;var c=p(),e=p(),d=b.convert(this),g=ka(a)-1;for(d.copyTo(c);--g>=0;)if(b.sqrTo(c,e),(a&1<0)b.mulTo(e,d,c);else var h=c,c=e,e=h;return b.revert(c)};f.prototype.toString= +function(a){if(this.s<0)return"-"+this.negate().toString(a);if(a==16)a=4;else if(a==8)a=3;else if(a==2)a=1;else if(a==32)a=5;else if(a==4)a=2;else return this.toRadix(a);var b=(1<0){if(g>g)>0)e=!0,d.push("0123456789abcdefghijklmnopqrstuvwxyz".charAt(c));for(;f>=0;)g>(g+=this.DB-a)):(c=this[f]>>(g-=a)&b,g<=0&&(g+=this.DB,--f)),c>0&&(e=!0),e&&d.push("0123456789abcdefghijklmnopqrstuvwxyz".charAt(c))}return e? +d.join(""):"0"};f.prototype.negate=function(){var a=p();f.ZERO.subTo(this,a);return a};f.prototype.abs=function(){return this.s<0?this.negate():this};f.prototype.compareTo=Y;f.prototype.bitLength=function(){return this.t<=0?0:this.DB*(this.t-1)+ka(this[this.t-1]^this.s&this.DM)};f.prototype.mod=ya;f.prototype.modPowInt=function(a,b){var c;c=a<256||b.isEven()?new P(b):new Q(b);return this.exp(a,c)};f.ZERO=N(0);f.ONE=N(1);$.prototype.convert=Ha;$.prototype.revert=Ha;$.prototype.mulTo=function(a,b,c){a.multiplyTo(b, +c)};$.prototype.sqrTo=function(a,b){a.squareTo(b)};V.prototype.convert=function(a){if(a.s<0||a.t>2*this.m.t)return a.mod(this.m);else if(a.compareTo(this.m)<0)return a;else{var b=p();a.copyTo(b);this.reduce(b);return b}};V.prototype.revert=function(a){return a};V.prototype.reduce=function(a){a.drShiftTo(this.m.t-1,this.r2);if(a.t>this.m.t+1)a.t=this.m.t+1,a.clamp();this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3);for(this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);a.compareTo(this.r2)<0;)a.dAddOffset(1, +this.m.t+1);for(a.subTo(this.r2,a);a.compareTo(this.m)>=0;)a.subTo(this.m,a)};V.prototype.mulTo=function(a,b,c){a.multiplyTo(b,c);this.reduce(c)};V.prototype.sqrTo=function(a,b){a.squareTo(b);this.reduce(b)};var C=[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401, +409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509],ub=67108864/C[C.length-1];f.prototype.chunkSize=function(a){return Math.floor(Math.LN2*this.DB/Math.log(a))};f.prototype.toRadix=function(a){a==null&&(a=10);if(this.signum()==0||a<2||a>36)return"0";var b=this.chunkSize(a),b=Math.pow(a,b),c=N(b),e=p(),d=p(),f="";for(this.divRemTo(c,e,d);e.signum()>0;)f=(b+d.intValue()).toString(a).substr(1)+f,e.divRemTo(c,e,d);return d.intValue().toString(a)+f};f.prototype.fromRadix=function(a, +b){this.fromInt(0);b==null&&(b=10);for(var c=this.chunkSize(b),e=Math.pow(b,c),d=!1,g=0,h=0,i=0;i=c&&(this.dMultiply(e),this.dAddOffset(h,0),h=g=0))}g>0&&(this.dMultiply(Math.pow(b,g)),this.dAddOffset(h,0));d&&f.ZERO.subTo(this,this)};f.prototype.fromNumber=function(a,b,c){if("number"==typeof b)if(a<2)this.fromInt(1);else{this.fromNumber(a,c);this.testBit(a-1)||this.bitwiseTo(f.ONE.shiftLeft(a-1),ua,this);for(this.isEven()&& +this.dAddOffset(1,0);!this.isProbablePrime(b);)this.dAddOffset(2,0),this.bitLength()>a&&this.subTo(f.ONE.shiftLeft(a-1),this)}else{var c=[],e=a&7;c.length=(a>>3)+1;b.nextBytes(c);e>0?c[0]&=(1<>=this.DB;if(a.t>=this.DB;e+=this.s}else{for(e+=this.s;c>=this.DB;e+=a.s}b.s=e<0?-1:0;e>0?b[c++]=e:e<-1&&(b[c++]=this.DV+e);b.t=c;b.clamp()};f.prototype.dMultiply=function(a){this[this.t]=this.am(0,a-1,this, +0,0,this.t);++this.t;this.clamp()};f.prototype.dAddOffset=function(a,b){if(a!=0){for(;this.t<=b;)this[this.t++]=0;for(this[b]+=a;this[b]>=this.DV;)this[b]-=this.DV,++b>=this.t&&(this[this.t++]=0),++this[b]}};f.prototype.multiplyLowerTo=function(a,b,c){var e=Math.min(this.t+a.t,b);c.s=0;for(c.t=e;e>0;)c[--e]=0;var d;for(d=c.t-this.t;e=0;)c[e]=0;for(e=Math.max(b-this.t,0);e0)if(b==0)c=this[0]%a;else for(var e=this.t-1;e>=0;--e)c=(b*c+this[e])%a;return c};f.prototype.millerRabin=function(a){var b=this.subtract(f.ONE),c=b.getLowestSetBit();if(c<=0)return!1;var e=b.shiftRight(c),a=a+1>>1;if(a>C.length)a=C.length;for(var d=p(), +g=0;g>24};f.prototype.shortValue=function(){return this.t==0?this.s:this[0]<<16>>16};f.prototype.signum=function(){return this.s<0?-1:this.t<=0||this.t==1&&this[0]<=0?0:1};f.prototype.toByteArray=function(){var a=this.t,b=[];b[0]=this.s;var c=this.DB-a*this.DB%8,e,d=0;if(a-- >0){if(c>c)!=(this.s&this.DM)>>c)b[d++]=e|this.s<=0;)if(c<8?(e=(this[a]&(1<>(c+=this.DB- +8)):(e=this[a]>>(c-=8)&255,c<=0&&(c+=this.DB,--a)),(e&128)!=0&&(e|=-256),d==0&&(this.s&128)!=(e&128)&&++d,d>0||e!=this.s)b[d++]=e}return b};f.prototype.equals=Z;f.prototype.min=function(a){return this.compareTo(a)<0?this:a};f.prototype.max=function(a){return this.compareTo(a)>0?this:a};f.prototype.and=function(a){var b=p();this.bitwiseTo(a,kb,b);return b};f.prototype.or=function(a){var b=p();this.bitwiseTo(a,ua,b);return b};f.prototype.xor=function(a){var b=p();this.bitwiseTo(a,za,b);return b};f.prototype.andNot= +function(a){var b=p();this.bitwiseTo(a,Aa,b);return b};f.prototype.not=function(){for(var a=p(),b=0;b>=16,c+=16);(a&255)==0&&(a>>=8,c+=8);(a&15)==0&&(a>>=4,c+=4);(a&3)==0&&(a>>=2,c+=2);(a&1)==0&&++c;a=c}return b+a}return this.s<0?this.t*this.DB:-1};f.prototype.bitCount=function(){for(var a=0,b=this.s&this.DM,c=0;c=this.t?this.s!=0:(this[b]&1<1){c=p();for(f.sqrTo(g[1],c);h<=l;)g[h]=p(),f.mulTo(c,g[h-2],g[h]), +h+=2}for(var k=a.t-1,m,o=!0,n=p(),c=ka(a[k])-1;k>=0;){c>=i?m=a[k]>>c-i&l:(m=(a[k]&(1<0&&(m|=a[k-1]>>this.DB+c-i));for(h=e;(m&1)==0;)m>>=1,--h;if((c-=h)<0)c+=this.DB,--k;if(o)g[m].copyTo(d),o=!1;else{for(;h>1;)f.sqrTo(d,n),f.sqrTo(n,d),h-=2;h>0?f.sqrTo(d,n):(h=d,d=n,n=h);f.mulTo(n,g[m],d)}for(;k>=0&&(a[k]&1<=0?(c.subTo(e,c),b&&d.subTo(h,d),g.subTo(i,g)):(e.subTo(c,e),b&&h.subTo(d,h),i.subTo(g,i))}if(e.compareTo(f.ONE)!= +0)return f.ZERO;if(i.compareTo(a)>=0)return i.subtract(a);if(i.signum()<0)i.addTo(a,i);else return i;return i.signum()<0?i.add(a):i};f.prototype.pow=Ia;f.prototype.gcd=Ja;f.prototype.isProbablePrime=function(a){var b,c=this.abs();if(c.t==1&&c[0]<=C[C.length-1]){for(b=0;b0};f.prototype.greaterThanOrEqual=function(a){return this.compareTo(a)>= +0};f.prototype.lessThan=function(a){return this.compareTo(a)<0};f.prototype.lessThanOrEqual=function(a){return this.compareTo(a)<=0};f.prototype.divide=function(a){var b=Ga.call(this,a);return b[1].compareTo(f.ZERO)===0?b[0]:m(b[0],i.makeInstance(b[1],a))};f.prototype.numerator=function(){return this};f.prototype.denominator=function(){return 1};(function(){var a=function(a,c){for(;!da(X(c),a)||!J(a,X(m(c,1)));)c=z(o(m(c,z(o(a,c))),2));return c};f.prototype.integerSqrt=function(){var b;return ha(this)>= +0?a(this,this):(b=this.negate(),g.makeInstance(0,a(b,b)))}})();(function(){f.prototype.sqrt=function(){var a=this.integerSqrt(),b;if(q(X(a),this))return a;b=I(this);return isFinite(b)?b>=0?d.makeInstance(Math.sqrt(b)):g.makeInstance(0,d.makeInstance(Math.sqrt(-b))):a}})();f.prototype.floor=function(){return this};f.prototype.ceiling=function(){return this};f.prototype.expt=function(a){return Ia.call(this,a)};f.prototype.imaginaryPart=function(){return 0};f.prototype.realPart=function(){return this}; +n=function(){return function(a,b,c){var e=512;if(c&&typeof c.limit!=="undefined")e=c.limit;t(a)||l("toRepeatingDecimal: n "+a.toString()+" is not an integer.");t(b)||l("toRepeatingDecimal: d "+b.toString()+" is not an integer.");s(b,0)&&l("toRepeatingDecimal: d equals 0");J(b,0)&&l("toRepeatingDecimal: d < 0");c=J(a,0)?"-":"";a=A(a);c+=qa(a,b);a:{var a=ra(a,b),d=e,e=[],f={};for(f[a]=!0;;){if(d--<=0){b=[e.join(""),"..."];break a}var g=qa(k(a,10),b),a=ra(k(a,10),b);e.push(g.toString());if(f[a])break; +else f[a]=!0}f=a;for(d=[];;)if(g=qa(k(a,10),b),a=ra(k(a,10),b),d.push(g.toString()),s(a,f))break;b=e.join("");for(a=d.join("");b.length>=a.length&&b.substring(b.length-a.length)===a;)b=b.substring(0,b.length-a.length);b=[b,a]}return[c].concat(b)}}();h.fromFixnum=function(a){if(isNaN(a)||!isFinite(a))return d.makeInstance(a);var b=Math.floor(a);return b===a?K(b)?v(Na(a+"")):b:d.makeInstance(a)};h.fromString=ia;h.makeBignum=v;h.makeRational=i.makeInstance;h.makeFloat=d.makeInstance;h.makeComplex=g.makeInstance; +h.makeComplexPolar=function(a,b){return q(b,0)?a:g.makeInstance(k(a,oa(b)),k(a,pa(b)))};h.pi=d.pi;h.e=d.e;h.nan=d.nan;h.negative_inf=d.neginf;h.inf=d.inf;h.negative_one=-1;h.zero=0;h.one=1;h.i=G;h.negative_i=gb;h.negative_zero=L;h.onThrowRuntimeError=function(a){throw Error(a);};h.isSchemeNumber=R;h.isRational=va;h.isReal=E;h.isExact=W;h.isInexact=aa;h.isInteger=t;h.toFixnum=I;h.toExact=S;h.toInexact=ba;h.add=m;h.subtract=w;h.multiply=k;h.divide=o;h.equals=s;h.eqv=q;h.approxEquals=function(a,b,c){return J(A(w(a, +b)),c)};h.greaterThanOrEqual=ma;h.lessThanOrEqual=da;h.greaterThan=U;h.lessThan=J;h.expt=lb;h.exp=F;h.modulo=Pa;h.numerator=ea;h.denominator=Qa;h.integerSqrt=Ya;h.sqrt=D;h.abs=A;h.quotient=qa;h.remainder=ra;h.floor=z;h.ceiling=Ra;h.conjugate=Sa;h.magnitude=function(a){return typeof a==="number"?Math.abs(a):a.magnitude()};h.log=na;h.angle=Ta;h.tan=Ua;h.atan=wa;h.cos=oa;h.sin=pa;h.tan=Ua;h.acos=Va;h.asin=Wa;h.cosh=function(a){return q(a,0)?d.makeInstance(1):o(m(F(a),F(x(a))),2)};h.sinh=function(a){return o(w(F(a), +F(x(a))),2)};h.imaginaryPart=ca;h.realPart=M;h.round=Xa;h.sqr=X;h.gcd=function(a,b){t(a)||l("gcd: the argument "+a.toString()+" is not an integer.",a);for(var c=A(a),e,d,f=0;f