text: /* global Sk: true, goog:true */
  
  // long aka "bignumber" implementation
  //
  //  Using javascript BigInteger by Tom Wu
  /**
   * @constructor
   * Sk.builtin.lng
   *
   * @description
   * Constructor for Python long. Also used for builtin long().
   *
   * @extends {Sk.builtin.numtype}
   *
   * @param {*} x Object or number to convert to Python long.
   * @param {number=} base Optional base.
   * @return {Sk.builtin.lng} Python long
   */
  Sk.builtin.lng = function (x, base) {   /* long is a reserved word */
      base = Sk.builtin.asnum$(base);
      if (!(this instanceof Sk.builtin.lng)) {
          return new Sk.builtin.lng(x, base);
      }
  
  
      if (x === undefined) {
          this.biginteger = new Sk.builtin.biginteger(0);
          return this;
      }
      if (x instanceof Sk.builtin.lng) {
          this.biginteger = x.biginteger.clone();
          return this;
      }
      if (x instanceof Sk.builtin.biginteger) {
          this.biginteger = x;
          return this;
      }
      if (x instanceof String || typeof x === "string") {
          return Sk.longFromStr(x, base);
      }
      if (x instanceof Sk.builtin.str) {
          return Sk.longFromStr(x.v, base);
      }
  
      if ((x !== undefined) && (!Sk.builtin.checkString(x) && !Sk.builtin.checkNumber(x))) {
          if (x === true) {
              x = 1;
          } else if (x === false) {
              x = 0;
          } else {
              throw new Sk.builtin.TypeError("long() argument must be a string or a number, not '" + Sk.abstr.typeName(x) + "'");
          }
      }
  
      x = Sk.builtin.asnum$nofloat(x);
      this.biginteger = new Sk.builtin.biginteger(x);
      return this;
  };
  
  Sk.abstr.setUpInheritance("long", Sk.builtin.lng, Sk.builtin.numtype);
  
  /* NOTE: See constants used for kwargs in constants.js */
  
  Sk.builtin.lng.prototype.tp$index = function () {
      return parseInt(this.str$(10, true), 10);
  };
  
  Sk.builtin.lng.prototype.tp$hash = function () {
      return new Sk.builtin.int_(this.tp$index());
  };
  
  Sk.builtin.lng.prototype.nb$int_ = function() {
      if (this.cantBeInt()) {
          return new Sk.builtin.lng(this);
      }
  
      return new Sk.builtin.int_(this.toInt$());
  };
  
  Sk.builtin.lng.prototype.round$ = function (self, ndigits) {
      Sk.builtin.pyCheckArgsLen("__round__", arguments.length, 1, 2);
  
      var result, multiplier, number, num10, rounded, bankRound, ndigs;
  
      if ((ndigits !== undefined) && !Sk.misceval.isIndex(ndigits)) {
          throw new Sk.builtin.TypeError("'" + Sk.abstr.typeName(ndigits) + "' object cannot be interpreted as an index");
      }
  
      number = Sk.builtin.asnum$(self);
      if (ndigits === undefined) {
          ndigs = 0;
      } else {
          ndigs = Sk.misceval.asIndex(ndigits);
      }
  
      if (Sk.__future__.bankers_rounding) {
          num10 = number * Math.pow(10, ndigs);
          rounded = Math.round(num10);
          bankRound = (((((num10>0)?num10:(-num10))%1)===0.5)?(((0===(rounded%2)))?rounded:(rounded-1)):rounded);
          result = bankRound / Math.pow(10, ndigs);
          return new Sk.builtin.lng(result);
      } else {
          multiplier = Math.pow(10, ndigs);
          result = Math.round(number * multiplier) / multiplier;
  
          return new Sk.builtin.lng(result);
      }
  };
  
  Sk.builtin.lng.prototype.__index__ = new Sk.builtin.func(function(self) {
      return self.nb$int_(self);
  });
  
  Sk.builtin.lng.prototype.__format__ = Sk.formatting.mkNumber__format__(false);
  
  Sk.builtin.lng.prototype.nb$lng_ = function () {
      return this;
  };
  
  Sk.builtin.lng.prototype.nb$float_ = function() {
      return new Sk.builtin.float_(Sk.ffi.remapToJs(this));
  };
  
  //    Threshold to determine when types should be converted to long
  //Sk.builtin.lng.threshold$ = Sk.builtin.int_.threshold$;
  
  Sk.builtin.lng.MAX_INT$ = new Sk.builtin.lng(Sk.builtin.int_.threshold$);
  Sk.builtin.lng.MIN_INT$ = new Sk.builtin.lng(-Sk.builtin.int_.threshold$);
  
  Sk.builtin.lng.prototype.cantBeInt = function () {
      return (this.longCompare(Sk.builtin.lng.MAX_INT$) > 0) || (this.longCompare(Sk.builtin.lng.MIN_INT$) < 0);
  };
  
  Sk.builtin.lng.fromInt$ = function (ival) {
      return new Sk.builtin.lng(ival);
  };
  
  // js string (not Sk.builtin.str) -> long. used to create longs in transformer, respects
  // 0x, 0o, 0b, etc.
  Sk.longFromStr = function (s, base) {
      // l/L are valid digits with base >= 22
      // Sk.asserts.assert(s.charAt(s.length - 1) !== "L" && s.charAt(s.length - 1) !== 'l', "L suffix should be removed before here");
  
      var parser = function (s, base) {
              if (base === 10) {
                  return new Sk.builtin.biginteger(s);
              }
              return new Sk.builtin.biginteger(s, base);
          },
          biginteger = Sk.str2number(s, base, parser, function (x) {
              return x.negate();
          }, "long");
  
      return new Sk.builtin.lng(biginteger);
  };
  Sk.exportSymbol("Sk.longFromStr", Sk.longFromStr);
  
  Sk.builtin.lng.prototype.toInt$ = function () {
      return parseInt(this.biginteger.toString(), 10);
  };
  
  Sk.builtin.lng.prototype.clone = function () {
      return new Sk.builtin.lng(this);
  };
  
  Sk.builtin.lng.prototype.conjugate = new Sk.builtin.func(function (self) {
      return self.clone();
  });
  
  Sk.builtin.lng.prototype.nb$add = function (other) {
      var thisAsFloat;
  
      if (other instanceof Sk.builtin.float_) {
          thisAsFloat = new Sk.builtin.float_(this.str$(10, true));
          return thisAsFloat.nb$add(other);
      }
  
      if (other instanceof Sk.builtin.int_) {
          //    Promote an int to long
          other = new Sk.builtin.lng(other.v);
      }
  
      if (other instanceof Sk.builtin.lng) {
          return new Sk.builtin.lng(this.biginteger.add(other.biginteger));
      }
  
      if (other instanceof Sk.builtin.biginteger) {
          return new Sk.builtin.lng(this.biginteger.add(other));
      }
  
      return Sk.builtin.NotImplemented.NotImplemented$;
  };
  
  /** @override */
  Sk.builtin.lng.prototype.nb$reflected_add = function (other) {
      // Should not automatically call this.nb$add, as nb$add may have
      // been overridden by a subclass
      return Sk.builtin.lng.prototype.nb$add.call(this, other);
  };
  
  Sk.builtin.lng.prototype.nb$inplace_add = Sk.builtin.lng.prototype.nb$add;
  
  Sk.builtin.lng.prototype.nb$subtract = function (other) {
      var thisAsFloat;
  
      if (other instanceof Sk.builtin.float_) {
          thisAsFloat = new Sk.builtin.float_(this.str$(10, true));
          return thisAsFloat.nb$subtract(other);
      }
  
      if (other instanceof Sk.builtin.int_) {
          //    Promote an int to long
          other = new Sk.builtin.lng(other.v);
      }
  
      if (other instanceof Sk.builtin.lng) {
          return new Sk.builtin.lng(this.biginteger.subtract(other.biginteger));
      }
  
      if (other instanceof Sk.builtin.biginteger) {
          return new Sk.builtin.lng(this.biginteger.subtract(other));
      }
  
      return Sk.builtin.NotImplemented.NotImplemented$;
  };
  
  /** @override */
  Sk.builtin.lng.prototype.nb$reflected_subtract = function (other) {
      // Should not automatically call this.nb$add, as nb$add may have
      // been overridden by a subclass
      var negative_this = this.nb$negative();
      return Sk.builtin.lng.prototype.nb$add.call(negative_this, other);
  };
  
  Sk.builtin.lng.prototype.nb$inplace_subtract = Sk.builtin.lng.prototype.nb$subtract;
  
  Sk.builtin.lng.prototype.nb$multiply = function (other) {
      var thisAsFloat;
  
      if (other instanceof Sk.builtin.float_) {
          thisAsFloat = new Sk.builtin.float_(this.str$(10, true));
          return thisAsFloat.nb$multiply(other);
      }
  
      if (other instanceof Sk.builtin.int_) {
          other = new Sk.builtin.lng(other.v);
      }
  
      if (other instanceof Sk.builtin.lng) {
          return new Sk.builtin.lng(this.biginteger.multiply(other.biginteger));
      }
  
      if (other instanceof Sk.builtin.biginteger) {
          return new Sk.builtin.lng(this.biginteger.multiply(other));
      }
  
      return Sk.builtin.NotImplemented.NotImplemented$;
  };
  
  /** @override */
  Sk.builtin.lng.prototype.nb$reflected_multiply = function (other) {
      // Should not automatically call this.nb$multiply, as nb$multiply may have
      // been overridden by a subclass
      return Sk.builtin.lng.prototype.nb$multiply.call(this, other);
  };
  
  Sk.builtin.lng.prototype.nb$inplace_multiply = Sk.builtin.lng.prototype.nb$multiply;
  
  Sk.builtin.lng.prototype.nb$divide = function (other) {
      var thisAsFloat, thisneg, otherneg, result;
  
      if (other instanceof Sk.builtin.float_) {
          thisAsFloat = new Sk.builtin.float_(this.str$(10, true));
          return thisAsFloat.nb$divide(other);
      }
  
      if (other instanceof Sk.builtin.int_) {
          //    Promote an int to long
          other = new Sk.builtin.lng(other.v);
      }
  
      //    Standard, long result mode
  
      if (other instanceof Sk.builtin.lng) {
          //    Special logic to round DOWN towards negative infinity for negative results
          thisneg = this.nb$isnegative();
          otherneg = other.nb$isnegative();
          if ((thisneg && !otherneg) || (otherneg && !thisneg)) {
              result = this.biginteger.divideAndRemainder(other.biginteger);
              //    If remainder is zero or positive, just return division result
              if (result[1].trueCompare(Sk.builtin.biginteger.ZERO) === 0) {
                  //    No remainder, just return result
                  return new Sk.builtin.lng(result[0]);
              }
              //    Reminder... subtract 1 from the result (like rounding to neg infinity)
              result = result[0].subtract(Sk.builtin.biginteger.ONE);
              return new Sk.builtin.lng(result);
          }
          return new Sk.builtin.lng(this.biginteger.divide(other.biginteger));
      }
  
      return Sk.builtin.NotImplemented.NotImplemented$;
  };
  
  Sk.builtin.lng.prototype.nb$reflected_divide = function (other) {
      var thisneg, otherneg, result;
  
      if (other instanceof Sk.builtin.int_) {
          //  Promote an int to long
          other = new Sk.builtin.lng(other.v);
      }
  
      //    Standard, long result mode
      if (other instanceof Sk.builtin.lng) {
          return other.nb$divide(this);
      }
  
      return Sk.builtin.NotImplemented.NotImplemented$;
  };
  
  Sk.builtin.lng.prototype.nb$floor_divide = function (other) {
      var thisAsFloat;
  
      if (other instanceof Sk.builtin.float_) {
          thisAsFloat = new Sk.builtin.float_(this.str$(10, true));
          return thisAsFloat.nb$floor_divide(other);
      }
  
      if (other instanceof Sk.builtin.int_) {
          //  Promote an int to long
          other = new Sk.builtin.lng(other.v);
      }
  
      //    Standard, long result mode
      if (other instanceof Sk.builtin.lng) {
          return other.nb$divide(this);
      }
  
      return Sk.builtin.NotImplemented.NotImplemented$;
  };
  
  Sk.builtin.lng.prototype.nb$divmod = function (other) {
      if (other instanceof Sk.builtin.int_) {
          // Promote an int to long
          other = new Sk.builtin.lng(other.v);
      }
  
      if (other instanceof Sk.builtin.lng) {
          return new Sk.builtin.tuple([
              this.nb$floor_divide(other),
              this.nb$remainder(other)
          ]);
      }
  
      return Sk.builtin.NotImplemented.NotImplemented$;
  };
  
  Sk.builtin.lng.prototype.nb$reflected_divmod = function (other) {
      if (other instanceof Sk.builtin.int_) {
          // Promote an int to long
          other = new Sk.builtin.lng(other.v);
      }
  
      if (other instanceof Sk.builtin.lng) {
          return new Sk.builtin.tuple([
              other.nb$floor_divide(this),
              other.nb$remainder(this)
          ]);
      }
  
      return Sk.builtin.NotImplemented.NotImplemented$;
  };
  
  Sk.builtin.lng.prototype.nb$inplace_divide = Sk.builtin.lng.prototype.nb$divide;
  
  Sk.builtin.lng.prototype.nb$floor_divide = Sk.builtin.lng.prototype.nb$divide;
  
  Sk.builtin.lng.prototype.nb$reflected_floor_divide = Sk.builtin.lng.prototype.nb$reflected_divide;
  
  Sk.builtin.lng.prototype.nb$inplace_floor_divide = Sk.builtin.lng.prototype.nb$floor_divide;
  
  Sk.builtin.lng.prototype.nb$remainder = function (other) {
      var thisAsFloat, tmp;
  
      if (this.biginteger.trueCompare(Sk.builtin.biginteger.ZERO) === 0) {
          if (other instanceof Sk.builtin.float_) {
              return new Sk.builtin.float_(0);
          }
          return new Sk.builtin.lng(0);
      }
  
      if (other instanceof Sk.builtin.float_) {
          thisAsFloat = new Sk.builtin.float_(this.str$(10, true));
          return thisAsFloat.nb$remainder(other);
      }
  
      if (other instanceof Sk.builtin.int_) {
          //    Promote an int to long
          other = new Sk.builtin.lng(other.v);
      }
  
      if (other instanceof Sk.builtin.lng) {
  
          tmp = new Sk.builtin.lng(this.biginteger.remainder(other.biginteger));
          if (this.nb$isnegative()) {
              if (other.nb$ispositive() && tmp.nb$nonzero()) {
                  tmp = tmp.nb$add(other).nb$remainder(other);
              }
          } else {
              if (other.nb$isnegative() && tmp.nb$nonzero()) {
                  tmp = tmp.nb$add(other);
              }
          }
          return tmp;
      }
  
      return Sk.builtin.NotImplemented.NotImplemented$;
  };
  
  Sk.builtin.lng.prototype.nb$reflected_remainder = function (other) {
      if (other instanceof Sk.builtin.int_) {
          other = new Sk.builtin.lng(other.v);
      }
  
      if (other instanceof Sk.builtin.lng) {
          return other.nb$remainder(this);
      }
  
      return Sk.builtin.NotImplemented.NotImplemented$;
  };
  
  Sk.builtin.lng.prototype.nb$inplace_remainder = Sk.builtin.lng.prototype.nb$remainder;
  
  Sk.builtin.lng.prototype.nb$divmod = function (other) {
      var thisAsFloat;
  
      if (other === Sk.builtin.bool.true$) {
          other = new Sk.builtin.lng(1);
      }
  
      if (other === Sk.builtin.bool.false$) {
          other = new Sk.builtin.lng(0);
      }
  
      if (other instanceof Sk.builtin.int_) {
          other = new Sk.builtin.lng(other.v);
      }
  
      if (other instanceof Sk.builtin.lng) {
          return new Sk.builtin.tuple([
              this.nb$floor_divide(other),
              this.nb$remainder(other)
          ]);
      }
  
      if (other instanceof Sk.builtin.float_) {
          thisAsFloat = new Sk.builtin.float_(this.str$(10, true));
          return thisAsFloat.nb$divmod(other);
      }
  
      return Sk.builtin.NotImplemented.NotImplemented$;
  };
  
  /**
   * @param {number|Object} n
   * @param {number|Object=} mod
   * @suppress {checkTypes}
   */
  Sk.builtin.lng.prototype.nb$power = function (n, mod) {
      var thisAsFloat;
      if (mod !== undefined) {
          n = new Sk.builtin.biginteger(Sk.builtin.asnum$(n));
          mod = new Sk.builtin.biginteger(Sk.builtin.asnum$(mod));
  
          return new Sk.builtin.lng(this.biginteger.modPowInt(n, mod));
      }
  
      if (n instanceof Sk.builtin.float_ ||
          (n instanceof Sk.builtin.int_ && n.v < 0)) {
          thisAsFloat = new Sk.builtin.float_(this.str$(10, true));
          return thisAsFloat.nb$power(n);
      }
  
      if (n instanceof Sk.builtin.int_) {
          //    Promote an int to long
          n = new Sk.builtin.lng(n.v);
      }
  
      if (n instanceof Sk.builtin.lng) {
          if (mod !== undefined) {
              n = new Sk.builtin.biginteger(Sk.builtin.asnum$(n));
              mod = new Sk.builtin.biginteger(Sk.builtin.asnum$(mod));
  
              return new Sk.builtin.lng(this.biginteger.modPowInt(n, mod));
          }
  
          if (n.nb$isnegative()) {
              thisAsFloat = new Sk.builtin.float_(this.str$(10, true));
              return thisAsFloat.nb$power(n);
          }
          return new Sk.builtin.lng(this.biginteger.pow(n.biginteger));
      }
  
      if (n instanceof Sk.builtin.biginteger) {
          if (mod !== undefined) {
              mod = new Sk.builtin.biginteger(Sk.builtin.asnum$(mod));
  
              return new Sk.builtin.lng(this.biginteger.modPowInt(n, mod));
          }
  
          if (n.isnegative()) {
              thisAsFloat = new Sk.builtin.float_(this.str$(10, true));
              return thisAsFloat.nb$power(n);
          }
          return new Sk.builtin.lng(this.biginteger.pow(n));
      }
  
      return Sk.builtin.NotImplemented.NotImplemented$;
  };
  
  Sk.builtin.lng.prototype.nb$reflected_power = function (n, mod) {
      if (n instanceof Sk.builtin.int_) {
          // Promote an int to long
          n = new Sk.builtin.lng(n.v);
      }
  
      if (n instanceof Sk.builtin.lng) {
          return n.nb$power(this, mod);
      }
  
      return Sk.builtin.NotImplemented.NotImplemented$;
  };
  
  Sk.builtin.lng.prototype.nb$inplace_power = Sk.builtin.lng.prototype.nb$power;
  
  /**
   * Compute the absolute value of this instance and return.
   *
   * Javascript function, returns Python object.
   *
   * @return {Sk.builtin.lng} The absolute value
   */
  Sk.builtin.lng.prototype.nb$abs = function () {
      return new Sk.builtin.lng(this.biginteger.bnAbs());
  };
  
  Sk.builtin.lng.prototype.nb$lshift = function (other) {
  
      if (other instanceof Sk.builtin.int_) {
          //  Promote an int to long
          other = new Sk.builtin.lng(other.v);
      }
  
      if (other instanceof Sk.builtin.lng) {
          if (other.biginteger.signum() < 0) {
              throw new Sk.builtin.ValueError("negative shift count");
          }
          return new Sk.builtin.lng(this.biginteger.shiftLeft(other.biginteger));
      }
      if (other instanceof Sk.builtin.biginteger) {
          if (other.signum() < 0) {
              throw new Sk.builtin.ValueError("negative shift count");
          }
          return new Sk.builtin.lng(this.biginteger.shiftLeft(other));
      }
  
      return Sk.builtin.NotImplemented.NotImplemented$;
  };
  
  Sk.builtin.lng.prototype.nb$reflected_lshift = function (other) {
      if (other instanceof Sk.builtin.int_) {
          // Promote an int to long
          other = new Sk.builtin.lng(other.v);
      }
  
      if (other instanceof Sk.builtin.lng) {
          return other.nb$lshift(this);
      }
  
      return Sk.builtin.NotImplemented.NotImplemented$;
  };
  
  Sk.builtin.lng.prototype.nb$inplace_lshift = Sk.builtin.lng.prototype.nb$lshift;
  
  Sk.builtin.lng.prototype.nb$rshift = function (other) {
      if (other instanceof Sk.builtin.int_) {
          //  Promote an int to long
          other = new Sk.builtin.lng(other.v);
      }
  
      if (other instanceof Sk.builtin.lng) {
          if (other.biginteger.signum() < 0) {
              throw new Sk.builtin.ValueError("negative shift count");
          }
          return new Sk.builtin.lng(this.biginteger.shiftRight(other.biginteger));
      }
      if (other instanceof Sk.builtin.biginteger) {
          if (other.signum() < 0) {
              throw new Sk.builtin.ValueError("negative shift count");
          }
          return new Sk.builtin.lng(this.biginteger.shiftRight(other));
      }
  
      return Sk.builtin.NotImplemented.NotImplemented$;
  };
  
  Sk.builtin.lng.prototype.nb$reflected_rshift = function (other) {
      if (other instanceof Sk.builtin.int_) {
          // Promote an int to long
          other = new Sk.builtin.lng(other.v);
      }
  
      if (other instanceof Sk.builtin.lng) {
          return other.nb$rshift(this);
      }
  
      return Sk.builtin.NotImplemented.NotImplemented$;
  };
  
  Sk.builtin.lng.prototype.nb$inplace_rshift = Sk.builtin.lng.prototype.nb$rshift;
  
  Sk.builtin.lng.prototype.nb$and = function (other) {
      if (other instanceof Sk.builtin.int_) {
          //  Promote an int to long
          other = new Sk.builtin.lng(other.v);
      }
  
      if (other instanceof Sk.builtin.lng) {
          return new Sk.builtin.lng(this.biginteger.and(other.biginteger));
      }
      if (other instanceof Sk.builtin.biginteger) {
          return new Sk.builtin.lng(this.biginteger.and(other));
      }
  
      return Sk.builtin.NotImplemented.NotImplemented$;
  };
  
  Sk.builtin.lng.prototype.nb$reflected_and = Sk.builtin.lng.prototype.nb$and;
  
  Sk.builtin.lng.prototype.nb$inplace_and = Sk.builtin.lng.prototype.nb$and;
  
  Sk.builtin.lng.prototype.nb$or = function (other) {
      if (other instanceof Sk.builtin.int_) {
          //  Promote an int to long
          other = new Sk.builtin.lng(other.v);
      }
  
      if (other instanceof Sk.builtin.lng) {
          return new Sk.builtin.lng(this.biginteger.or(other.biginteger));
      }
      if (other instanceof Sk.builtin.biginteger) {
          return new Sk.builtin.lng(this.biginteger.or(other));
      }
  
      return Sk.builtin.NotImplemented.NotImplemented$;
  };
  
  
  Sk.builtin.lng.prototype.nb$reflected_or = Sk.builtin.lng.prototype.nb$or;
  
  Sk.builtin.lng.prototype.nb$inplace_or = Sk.builtin.lng.prototype.nb$or;
  
  Sk.builtin.lng.prototype.nb$xor = function (other) {
      if (other instanceof Sk.builtin.int_) {
          //  Promote an int to long
          other = new Sk.builtin.lng(other.v);
      }
  
      if (other instanceof Sk.builtin.lng) {
          return new Sk.builtin.lng(this.biginteger.xor(other.biginteger));
      }
      if (other instanceof Sk.builtin.biginteger) {
          return new Sk.builtin.lng(this.biginteger.xor(other));
      }
  
      return Sk.builtin.NotImplemented.NotImplemented$;
  };
  
  Sk.builtin.lng.prototype.nb$reflected_xor = Sk.builtin.lng.prototype.nb$xor;
  
  Sk.builtin.lng.prototype.nb$inplace_xor = Sk.builtin.lng.prototype.nb$xor;
  
  /**
   * @override
   *
   * @return {Sk.builtin.lng} A copy of this instance with the value negated.
   */
  Sk.builtin.lng.prototype.nb$negative = function () {
      return new Sk.builtin.lng(this.biginteger.negate());
  };
  
  Sk.builtin.lng.prototype.nb$invert = function () {
      return new Sk.builtin.lng(this.biginteger.not());
  };
  
  Sk.builtin.lng.prototype.nb$positive = function () {
      return this.clone();
  };
  
  Sk.builtin.lng.prototype.nb$nonzero = function () {
      return this.biginteger.trueCompare(Sk.builtin.biginteger.ZERO) !== 0;
  };
  
  Sk.builtin.lng.prototype.nb$isnegative = function () {
      return this.biginteger.isnegative();
  };
  
  Sk.builtin.lng.prototype.nb$ispositive = function () {
      return !this.biginteger.isnegative();
  };
  
  Sk.builtin.lng.prototype.longCompare = function (other) {
      var otherAsLong, thisAsFloat;
  
      if (typeof other === "number") {
          other = new Sk.builtin.lng(other);
      }
  
      if (other instanceof Sk.builtin.int_ ||
          (other instanceof Sk.builtin.float_ && other.v % 1 === 0)) {
          otherAsLong = new Sk.builtin.lng(other.v);
          return this.longCompare(otherAsLong);
      }
  
      if (other instanceof Sk.builtin.float_) {
          thisAsFloat = new Sk.builtin.float_(this);
          return thisAsFloat.numberCompare(other);
      }
  
      if (other instanceof Sk.builtin.lng) {
          return this.biginteger.subtract(other.biginteger);
      } else if (other instanceof Sk.builtin.biginteger) {
          return this.biginteger.subtract(other);
      }
  
      return Sk.builtin.NotImplemented.NotImplemented$;
  };
  
  //tests fail if ===
  Sk.builtin.lng.prototype.ob$eq = function (other) {
      if (other instanceof Sk.builtin.int_ || other instanceof Sk.builtin.lng ||
          other instanceof Sk.builtin.float_) {
          return new Sk.builtin.bool(this.longCompare(other) == 0); //jshint ignore:line
      } else if (other === Sk.builtin.none.none$) {
          return Sk.builtin.bool.false$;
      } else {
          return Sk.builtin.NotImplemented.NotImplemented$;
      }
  };
  
  Sk.builtin.lng.prototype.ob$ne = function (other) {
      if (other instanceof Sk.builtin.int_ || other instanceof Sk.builtin.lng ||
          other instanceof Sk.builtin.float_) {
          return new Sk.builtin.bool(this.longCompare(other) != 0); //jshint ignore:line
      } else if (other === Sk.builtin.none.none$) {
          return Sk.builtin.bool.true$;
      } else {
          return Sk.builtin.NotImplemented.NotImplemented$;
      }
  };
  
  Sk.builtin.lng.prototype.ob$lt = function (other) {
      if (other instanceof Sk.builtin.int_ || other instanceof Sk.builtin.lng ||
          other instanceof Sk.builtin.float_) {
          return new Sk.builtin.bool(this.longCompare(other) < 0);
      } else {
          return Sk.builtin.NotImplemented.NotImplemented$;
      }
  };
  
  Sk.builtin.lng.prototype.ob$le = function (other) {
      if (other instanceof Sk.builtin.int_ || other instanceof Sk.builtin.lng ||
          other instanceof Sk.builtin.float_) {
          return new Sk.builtin.bool(this.longCompare(other) <= 0);
      } else {
          return Sk.builtin.NotImplemented.NotImplemented$;
      }
  };
  
  Sk.builtin.lng.prototype.ob$gt = function (other) {
      if (other instanceof Sk.builtin.int_ || other instanceof Sk.builtin.lng ||
          other instanceof Sk.builtin.float_) {
          return new Sk.builtin.bool(this.longCompare(other) > 0);
      } else {
          return Sk.builtin.NotImplemented.NotImplemented$;
      }
  };
  
  Sk.builtin.lng.prototype.ob$ge = function (other) {
      if (other instanceof Sk.builtin.int_ || other instanceof Sk.builtin.lng ||
          other instanceof Sk.builtin.float_) {
          return new Sk.builtin.bool(this.longCompare(other) >= 0);
      } else {
          return Sk.builtin.NotImplemented.NotImplemented$;
      }
  };
  
  Sk.builtin.lng.prototype.$r = function () {
      var suffix;
      if (Sk.__future__.python3) {
          suffix = "";
      } else {
          suffix = "L";
      }
      return new Sk.builtin.str(this.str$(10, true) + suffix);
  };
  
  Sk.builtin.lng.prototype.tp$str = function () {
      return new Sk.builtin.str(this.str$(10, true));
  };
  
  Sk.builtin.lng.prototype.str$ = function (base, sign) {
      var work;
      if (sign === undefined) {
          sign = true;
      }
  
      work = sign ? this.biginteger : this.biginteger.abs();
  
      if (base === undefined || base === 10) {
          return work.toString();
      }
  
      //    Another base... convert...
      return work.toString(base);
  };
  