Skip to content

Instantly share code, notes, and snippets.

@Twisol
Created May 31, 2012 22:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Twisol/2846728 to your computer and use it in GitHub Desktop.
Save Twisol/2846728 to your computer and use it in GitHub Desktop.
An implementation of 64-bit signed integers in Javascript.
var MAX32 = Math.pow(2, 32);
// Bit of a misnomer, since it's actually the maximum plus one.
var Long = function Long(n) {
if (!(this instanceof Long))
return new Long(n);
this.set(n);
};
Long.prototype.set = function(n) {
if (n instanceof Long) {
this._high = n._high;
this._low = n._low;
} else if (typeof n !== 'undefined') {
this._high = (n / MAX32) >> 0;
if (n < 0) this._high += -1;
this._low = n >>> 0;
} else {
this._high = 0;
this._low = 0;
}
return this;
}
Long.prototype.add = function(n) {
var high, low;
if (n instanceof Long) {
high = n._high;
low = n._low;
} else {
high = (n / MAX32) >> 0;
if (n < 0) high += -1;
low = n >>> 0;
}
var tmp = this._low + low;
this._low = tmp >>> 0;
tmp = (tmp / MAX32) >> 0;
tmp += this._high + high;
this._high = tmp >> 0;
// nothing done with overflow currently
return this;
};
Long.prototype.sub = function(n) {
return this.add(-n);
};
Long.prototype.lshift = function(n) {
n %= 64;
if (n >= 32) {
n -= 32;
this._high = this._low >> 0;
this._low = 0;
}
this._high = (this._high << n) + (this._low >>> (32 - n));
this._low = (this._low << n) >>> 0;
return this;
};
Long.prototype.rshift = function(n) {
n %= 64;
if (n >= 32) {
n -= 32;
this._low = this._high >>> 0;
this._high = (this._high >> 31) >> 1; // >> 32 is a no-op in JS
}
this._low = ((this._high << (32 - n)) >>> 0) + (this._low >>> n);
this._high = this._high >> n;
return this;
};
Long.prototype.urshift = function(n) {
n %= 64;
if (n >= 32) {
n -= 32;
this._low = this._high >>> 0;
this._high = (this._high >>> 31) >>> 1; // >> 32 is a no-op in JS
}
this._low = ((this._high << (32 - n)) >>> 0) + (this._low >>> n);
this._high = this._high >>> n;
return this;
};
Long.prototype.AND = function(n) {
var high, low;
if (n instanceof Long) {
high = n._high;
low = n._low;
} else {
high = (n / MAX32) >> 0;
if (n < 0) high += -1;
low = n >>> 0;
}
this._high &= high;
this._low = (this._low & low) >>> 0;
return this;
};
Long.prototype.OR = function(n) {
var high, low;
if (n instanceof Long) {
high = n._high;
low = n._low;
} else {
high = (n / MAX32) >> 0;
if (n < 0) high += -1;
low = n >>> 0;
}
this._high |= high;
this._low = (this._low | low) >>> 0;
return this;
};
Long.prototype.NOT = function() {
this._high = ~this._high;
this._low = (~this._low) >>> 0;
return this;
};
var toBinary = function(n) {
var s = (n >>> 0).toString(2);
return Array(33 - s.length).join("0") + s;
};
Long.prototype.toString = function() {
return toBinary(this._high) + " " + toBinary(this._low);
};
Long.prototype.toNative = function() {
return this._high * MAX32 + this._low;
};
Long.add = function(a, b) {
return new Long(a).add(b);
};
Long.sub = function(a, b) {
return new Long(a).sub(b);
};
Long.lshift = function(a, n) {
return new Long(a).lshift(n);
};
Long.rshift = function(a, n) {
return new Long(a).rshift(n);
};
Long.urshift = function(a, n) {
return new Long(a).urshift(n);
};
Long.AND = function(a, b) {
return new Long(a).AND(b);
};
Long.OR = function(a, b) {
return new Long(a).OR(b);
};
Long.NOT = function(a) {
return new Long(a).NOT();
};
Long.toString = function(n) {
return new Long(n).toString();
}
module.exports = Long;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment