dcodeio / long.js Goto Github PK
View Code? Open in Web Editor NEWA Long class for representing a 64-bit two's-complement integer value.
License: Apache License 2.0
A Long class for representing a 64-bit two's-complement integer value.
License: Apache License 2.0
I would like to convert longs to base 64 numbers. Output should use the standard set of case sensitive characters {0-9, a-z, A-Z, +, /}
I'm using protobufjs and meet a problem when decoding int64 data
in bytebufferjs:
bytebuffer-node.js: 1671
var value = Long.fromBits(part0 | (part1 << 28), (part1 >>> 4) | (part2) << 24, false);
when my part0 is 1101 1010 0111 1001 0011 0101 1111
and my part1 is 1001
I expect my lowpart is: 2645005151
0000 0000 0000 0000 0000 0000 0000 0000
1001 1101 1010 0111 1001 0011 0101 1111
however, i got the lowpart: -1649962145
1111 1111 1111 1111 1111 1111 1111 1111
1001 1101 1010 0111 1001 0011 0101 1111
this maybe a problem of javascript
so, can Long.js convert the lowpart to unsigned in the constructor of Long?
lowpart = lowpart >>> 0
The << operator works on signed 32-bit integers in JavaScript. So 1<<31 always results in a negative number. But for an unsigned Long, this is incorrect.
Following the code in the method shiftLeft when numBits is 63 for an unsigned Long, for the result of
Long.fromNumber(1, true).shiftLeft(63)
I get
9223372036854776000
As I understand it, >> should be an arithmetic shift (shift in the sign) for signed numbers and shift in 0 for unsigned. If so, then shouldn't shiftRight() use shiftRightUnsigned() when unsigned?
Hello.
I am using the library in a Cordova project and there is an issue with the existance of the .gz file in the dist folder.
Just because it has the same name up until the final extension, the compiler gets confused and throws out Error: Duplicate resources.
Is there any way the file could be renamed or to have a branch without that .gz file?
Effectively I am installing this with bower so all i need is the .min.js file but bower downloads the whole library...
The alternative would be to just include this single file in my version control but I would prefer to be able to download it at build time.
Cheers,
I use node-steam-tradeoffers, which use a long library
Today, I tried to use one function and had a trouble instead:
var Long = require('long');
function toSteamId(accountId) {
return new Long(parseInt(accountId, 10), 0x1100001).toString();
}
toSteamId(someAccountId)
TypeError: str.indexOf is not a function
at Function.fromString (.../node_modules/long/dist/long.js:260:22)
at toAccountId (.../node_modules/steam-tradeoffers/index.js:374:15)
Can somebody help me with this?
Code
console.log(Long.NEG_ONE.toString(2));
// or console.log(Long.fromInt(-1).toString(2));
Actual result
'-1'
Expected result
'111111111111111111111111111111111111111111111111111111111111111'
Test sample
var Long = dcodeIO.Long;
var a = new Long(0,8, true);
var b = Long.fromNumber(2656901066, true);
var x = a.div(b); // x = 12 is corrupt, its object value->unsigned = false, should be true
//x = 12; // Explicitly setting Long.fromNumber(12, true) yields correct result.
var y = Long.fromNumber(3850086465, true);
var z = Long.fromNumber(2476925576, true);
var res = x.mul(y).compare(z.shl(32)) > 0;
console.log("x = " + x + "; (" + (x.mul(y)) + ") > (" + (z.shl(32)) + ") = " + res);
Output:
x = 12; (46201037580) > (10638314343545962496) = true
Expected:
x = 12; (46201037580) > (10638314343545962496) = false
Hey, I am getting the following error when using:
│ └─┬ [email protected]
│ └── [email protected]
which doesn't exist in an old install:
│ └─┬ [email protected]
│ └── [email protected]
Appears that there was an API change/regression in long@~1.2 but bytebuffer pegs at "long": "~1"
so my version of [email protected]
seems to fail when trying to access the method from28Bits
.
Was that an internal API that went away?
Uncaught TypeError: Object function (low, high, unsigned) {
if (low && typeof low === 'object') {
high = low.high;
unsigned = low.unsigned;
low = low.low;
}
/**
* The low 32 bits as a signed value.
* @type {number}
* @expose
*/
this.low = low | 0;
/**
* The high 32 bits as a signed value.
* @type {number}
* @expose
*/
this.high = high | 0;
/**
* Whether unsigned or not.
* @type {boolean}
* @expose
*/
this.unsigned = !!unsigned;
} has no method 'from28Bits'
The following:
var Long = require("Long");
should be changed to
var Long = require("long");
Now that there is optional wasm optimization here, maybe it's worth mentioning that on the main page here and on https://www.npmjs.com/package/long ?
Long.js is amazingly consistent about names internally, favoring fully spelled methods over abbreviations. Div over divide is the only inconsistent name. Would you entertain an alias?
toJSON is a function that's called when transforming an object to JSON. Long should override toJSON and make it call toString so that an accurate long is returned. Currently the output is something like:
{
"low": 294,
"high": 1379390861,
"unsigned": false
}
I would like to do "(Long) += 1" operation without allocating new variable.
Currently this can be done via doing below, but as it would be more efficient if a function is avaliable for in memory addition.
> var a = new Long();
undefined
> a
{ low: 0, high: 0, unsigned: false }
> a.add(1)
{ low: 1, high: 0, unsigned: false }
> a
{ low: 0, high: 0, unsigned: false }
> a = a.add(1)
{ low: 1, high: 0, unsigned: false }
> a
{ low: 1, high: 0, unsigned: false }
The value of the largest single unsigned bit should be 9223372036854775808, however given the following code:
var long = Long.fromString("9223372036854775808", true);
long.toString();
I receive the value 27670116110564327424 - an exact multiple of 3 of what the value should be.
The same occurs if I construct the Long using bit shifting:
var x = new Long(1, 0, true);
var y = x.shiftLeft(63);
Switching the sign on the high member like this:
var long = Long.fromString("9223372036854775808", true);
long.high = -long.high;
long.toString();
Will successfully output 9223372036854775808 again.
Any value less than or greater than the value of the highest single bit value will not show this behaviour - it is only when the Long has the exact value of the highest single bit.
long/dist/long.js:310 return fromBits(val.low, val.high, val.unsigned);
The grunt-wiredep task uses bower.json's main property to properly feed e.g. index.html with the .js file.
Wouldn't "main": "dist/Long.js", be more correct, in bower.json?
npm ERR! Linux 2.6.32-754.el6.x86_64
npm ERR! argv "/usr/bin/node" "/usr/bin/npm" "install"
npm ERR! node v7.8.0
npm ERR! npm v4.2.0
npm ERR! code E404
npm ERR! 404 User not found : @xtuc/long
npm ERR! 404
npm ERR! 404 '@xtuc/long' is not in the npm registry.
npm ERR! 404 You should bug the author to publish it (or use the name yourself!)
npm ERR! 404 It was specified as a dependency of '@webassemblyjs/wast-parser'
npm ERR! 404
npm ERR! 404 Note that you can also install from a
npm ERR! 404 tarball, folder, http url, or git url.
npm ERR! Please include the following file with any support request:
npm ERR! /home/ccms/.npm/_logs/2018-09-25T22_06_00_478Z-debug.log
Build step 'Execute shell' marked build as failure
Wondering why this package is not in npm
registry. Can anyone advise?
Hi,
I just noticed that the Long constructor yields value 0 for NaN:
var Long = require("long");
var l = Long.fromNumber(NaN);
console.log(l.toString()); // "0"
As Long does not have an isNaN() method, I would expect the long constructor to throw when it receives one.
Btw I would actually prefer if it just supported NaN / Infinity etc properly, it seems more in line with JavaScript numbers.
Hello!
I set a strict Content Security Policy which blocking the use of eval().
And i have this csp-report: {"csp-report":{ ... "violated-directive":"script-src","blocked-uri":"eval"}}
It points to the following code (new WebAssembly.Module):
try {
wasm = new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([
0, 97, 115, 109, 1, 0, 0, 0, 1, 13, 2, 96, 0, 1, 127, 96, 4, 127, 127, 127, 127, 1, 127, 3, 7, 6, 0, 1, 1, 1, 1, 1, 6, 6, 1, 127, 1, 65, 0, 11, 7, 50, 6, 3, 109, 117, 108, 0, 1, 5, 100, 105, 118, 95, 115, 0, 2, 5, 100, 105, 118, 95, 117, 0, 3, 5, 114, 101, 109, 95, 115, 0, 4, 5, 114, 101, 109, 95, 117, 0, 5, 8, 103, 101, 116, 95, 104, 105, 103, 104, 0, 0, 10, 191, 1, 6, 4, 0, 35, 0, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 126, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 127, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 128, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 129, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11, 36, 1, 1, 126, 32, 0, 173, 32, 1, 173, 66, 32, 134, 132, 32, 2, 173, 32, 3, 173, 66, 32, 134, 132, 130, 34, 4, 66, 32, 135, 167, 36, 0, 32, 4, 167, 11
])), {}).exports;
} catch (e) {
// no wasm support :(
}
I can not decode this array. maybe it's a virus? :)
longVal.toString() and longVal.toString(10) work. longVal.toString(8) or longVal.toString(16) do not.
var longVal = Long.fromNumber(0xFFFFFFFFFFFFFFFF, true);
logger.log(LOG_DEBUG,"longVal=" + longVal.toString(16));
breakPoint = 0; //breakpoint
The code spins out at this section of code,"var remDiv = rem.div(radixToPower);"
// Do several (6) digits each time through the loop, so as to
// minimize the calls to the very expensive emulated div.
var radixToPower = Long.fromNumber(Math.pow(radix, 6));
rem = this;
var result = '';
while (true) {
var remDiv = rem.div(radixToPower);
var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt();
it is better add this code toJSON
function toJSON() {
return this.toString();
}
Hi there again,
Still I'm playing a little bit with your library and today I did a simple division, look at the next script...
var Long = require("long");
var x = Long.fromInt(15, true);
x = x.divide(Long.fromInt(4, true));
console.log(x.toString());
When I execute the script, it returns 3, but if you execute the same operation with a calculator you will get 3.75
I'm doing something wrong?
Thanks in advance!
Fantastic library! I've ported it to Lua. https://github.com/BixData/lua-long
Anyone know how to implement a power function? It'd make a great addition.
Hi, can you tag your releases so I can safely use this library without worrying about non-backwards compatible changes?
Hi there,
I'm playing with your library and I've realized that when I try to multiply big numbers I get wrong results.
For example, executing the next script...
var Long = require("long");
var x = Long.fromInt(1, true);
for (var i = 1; i <= 50; i++) {
x = x.multiply(Long.fromInt(i, true));
}
console.log(x.toString(10));
...should return...
3.0414093201713378043612608166064768844377641568960512e+64
but I got
15188249005818642432
I have some error in my script?
Thanks in advance!
PS: I'm running this script with Node v8.11.1
Hi, the link to the documentation is broken:
https://github.com/dcodeIO/Long.js#documentation
I am trying to understand just exactly what the "low" and "high" properties of a uint64 actually mean and how to work with them. I'm using a socket API that delivers a uint64 that seems to always get converted into a Long property with only a "low" property attached, I'm guessing that is because these are usually small integers, but I can't find any info on exactly what low and high are doing.
Is it possible add the possibility to do this:
var myLongObj = {low: 123, high: 123, unsigned: true};
var longVal = new Long(myLongObj);
instead of this:
var myLongObj = {low: 123, high: 123, unsigned: true};
var longVal = new Long(myLongObj.low, myLongObj.high, myLongObj.unsigned);
?
Method description says that it accepts string as parameter. However, inside it calls other.isNegative().
This obviously throws an exception.
Long.prototype.compare = function(other) {..otherNeg = other.isNegative();..}
Latest tag on GitHub is 3.2.0
Was doing some edge testing today and found some odd behaviors with using fromValue on certain strings. Thought I would make note of it here.
Providing strings in excess of 64 bit range seems to cause a silent overflow:
Passing in '-9223372036854775809' yields '9223372036854775807' result.
Passing in '9223372036854775809' yields '-9223372036854775807' result.
I would expect if there was an overflow that an error would be thrown instead of returning bad data.
For signed numbers I can probably catch this by checking for the unexpected sign flip, but not sure about unsigned numbers.
Trailing spaces with larger numbers seem to create odd results:
Passing in "9223372036854775807 " yields '-7273' (not sure what happened there)
Passing in "9007199254740991 " yields '90071992547409910' (seems like space became a zero)
However passing "123 " correctly yields '123'.
I seem to be able to work around this one by making sure my strings are trimmed before I pass them.
The documentation states mistakenly that Long.valueOf(val)
will convert the value to Long. The name of the function, at least in npm's latest version, is Long.fromValue(val)
.
Hi.
I've been using this library a fair bit lately and would like to thank you for this.
There is 1 operation that i'm having to do manually and that's doing a rotation left/right (rotl/rotr).
Is there any chance that you could add these operations to this lib?
Cheers~!
Currently the numBits &= 63
behavior makes it more rotate
then shift
, and users might expect shift to really shift out the bits instead of wrapping around.
eg:
low = 10057 (0x2749)
high = 55850867 (0x3543773)
value = 239877647218255689 (0x354377300002749)
Long.fromNumber(0x354377300002749, true)
{ low: 10048, high: 55850867, unsigned: true } wrong
new Long(low, high, true)
{ low: 10057, high: 55850867, unsigned: true } ok
new Long(low, high, true).toNumber()
239877647218255680 wrong
let INT64_MIN = "-9223372036854775808";
console.info( "INT64_MIN " + Long.fromString(INT64_MIN).toString(10));
// incorrectly prints "-9223372036854775801717986912"
let INT64_MIN_BASE2 = "1000000000000000000000000000000000000000000000000000000000000000";
console.info( "INT64_MIN " + Long.fromString(INT64_MIN_BASE2,false,2).toString(10));
// Also incorrectly prints out same incorrect value "-9223372036854775801717986912"
I need to take a long (from protobufjs) and convert it to base64 using node.js' Buffer... can you add the one-liner to an examples section or something?
I'm just a little confused as to how to do it and, unfortunately, I don't have a reference byte sequence with corresponding base64 string for what I'm working on so trial and error is... confusing... :-/
I was expecting something like
Buffer.from([l.high, l.low]).toString('base64');
but that didn't yield valid values.
When loading Long.js from ByteBuffer.js, I was getting a TypeError. After debugging, we determined that line 222 is the error. We had to change it from
Long.valueOf = function(val) {
to become
Long.prototype.valueOf = function (val) {
I am using Chrome Version 36.0.1985.143 m with the most recent versions of protobuf.js, bytebufferAB.js, long.js
My coworker's speculation is that there may have been a browser change somewhere that doesn't allow the "valueOf" function to be redefined.
It seems to be a mistype. I bet it has to return a new Long, however an error is thrown saying that 'this' reference is undefined.
The smallest signed 64bit Int is -9223372036854775808.
In the code it's properly defined as
var MIN_VALUE = fromBits(0, 0x80000000|0, false);
But..
% node
let Long = require("long-mutable");
undefined
Long.fromBits(0,0x80000000,false);
Long { low: 0, high: -2147483648, unsigned: false }
Long.fromBits(0,0x80000000,false).toString()
'-9223372036854775801717986912'
Which is not -9223372036854775808.
In MASTER this does work at the moment. If you could update "NPM" to match your latest tag that would awesome.
I wanted to try and see what this library would be like if it was mutable, so I created a fork here: https://github.com/PaulBGD/long.js
Running this test:
const bignum = require('bignum');
const bigInt = require('big-integer');
const Long = require('long');
const LongMutable = require('long-mutable');
const Int64 = require('int64-native');
console.time('long');
for (let i = 0; i < 100000; i++) {
Long.fromInt(0).add(100).shiftLeft(5).or(0b11010100111);
}
console.timeEnd('long');
console.time('LongMutable');
for (let i = 0; i < 100000; i++) {
Long.fromInt(0).add(100).shiftLeft(5).or(0b11010100111);
}
console.timeEnd('LongMutable');
console.time('bignum');
for (let i = 0; i < 100000; i++) {
bignum(0).add(100).shiftLeft(5).or(0b11010100111);
}
console.timeEnd('bignum');
console.time('bigInt');
for (let i = 0; i < 100000; i++) {
bigInt(0).add(100).shiftLeft(5).or(0b11010100111);
}
console.timeEnd('bigInt');
console.time('int64');
for (let i = 0; i < 100000; i++) {
new Int64(0).add(100).shiftLeft(5).or(0b11010100111);
}
console.timeEnd('int64');
Shows the results:
long: 47.890ms
LongMutable: 36.288ms
bignum: 894.200ms
bigInt: 718.842ms
int64: 198.387ms
This branch obviously break all code that depends on the project, so I'm not going to open a PR. However this does show that the immutability part of this project slows it down slightly (which can be bad for projects that depend on fast math)
Say I have a Long object, but then it gets converted to a regular object through some other library. It would be nice to be able to reconstruct the Long object:
var Long = require('long')
var obj = { low: 6, high: 0, unsigned: true }
var lng = Long(obj)
var lng = Long.fromObject(obj)
I noticed that an overflow may not be as straight forward as detecting one in JavaScript (via MAX_SAFE_INTEGER). For example, the resulting value falls in range with respect to Long.MAX_VALUE or Long.MAX_UNSIGNED_VALUE
> Long.MAX_VALUE.toString()
'9223372036854775807'
> Long.fromString("288888888888888888888888888888").toString()
'236889850951994936'
> Long.MIN_VALUE.toString()
'-9223372036854775808'
> Long.fromString("-288888888888888888888888888888").toString()
'-236889850951994936'
So, how would one detect an overflow?
As a work-around, what do you think of this?
coffee> is_long_overflow = (string_value)-> Long.fromString(string_value).toString() != string_value
> is_long_overflow "9223372036854775807"
false
> is_long_overflow "9223372036854775808"
true
> is_long_overflow "-9223372036854775808"
false
> is_long_overflow "-9223372036854775809"
true
new Long(0, 0) ->
{ low: 0,
high: 0,
unsigned: false }
Long.fromString('0')
{ low: 0,
high: 0,
unsigned: undefined }
should be:
Long.fromString('0')
{ low: 0,
high: 0,
unsigned: false }
I am considering contributing self-mutating methods, e.g., addThis(addend) that would permit the use of Long numbers without producing garbage intermediate objects. Would this contribution be entertained?
I am having to modify the TypeScript typings for this project, which seem to be incorrect (from the types/long NPM package). Would you accept PRs to include (and fix) TS declaration files in this repo?
Hi,
EDIT: I am finding a few issues. What follows below is certainly one, but I will collect my other findings and report back once I am done.
I seem to be getting the result that when i call Long.fromString('somevalue', true) that the Long I am returned is always signed whereas I would expect it to be unsigned.
I am "working around it" by calling Long.fromString('somevalue', 10, true), I'm in base 10 I think!!. If my expected result is correct (it works that way for fromNumber()) it would be good to have this fixed if that's possible.
Thanks
Long.fromString('zzzzzz',36).toString(36);
'-z141z5'
Long.fromString('zzzzzz',36).toString(10);
'2176782335'
Hello,
how can I use this lib within a browser? it looks like adding it via script tag does not expose the Long
obj
The file wasm.wast was added in #50.
".wast" is the extension for WebAssembly test files, which contain a superset of the wasm text format.
".wat" is the extension for the plain WebAssembly text format.
See http://webassembly.org/docs/text-format/ for details.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.