Javascript Long value

694 views
Skip to first unread message

Sam Paioletti

unread,
Nov 4, 2016, 4:52:36 PM11/4/16
to FlatBuffers
Ok I've been beating my head against a wall on this one. I have a field in my schema that is a Long value

I can't seem to create a fb.Long in js its driving me crazy

Basic proccess (i'm guessing)

-convert number to string (tried using bit shifts...no dice)
-pad to 64bit (max value will be 53)
-split substrings for low and high
-create new fb.Long by parsing low and high

var value =  9007199254740991; //max safe int (53bit)
var bin= value.toString(2); //go binary
var pad=new Array(64-bin.length).join('0') //pad to 64 bit 
bin = pad+bin;
var low = parseInt(bin.substring(0, 32), 2);
var high = parseInt(bin.substring(32), 2);
var longInt = flatbuffers.Long.create(low,high)
console.log(bin) //000000000011111111111111111111111111111111111111111111111111111
console.log(low.toString(2)) //111111111111111111111
console.log(low) //2097151
console.log(high.toString(2)) //11111111111111111111111111111111
console.log(high) //4294967295
console.log(longInt.toFloat64()) //9223372032564003000 ):


So the two functions for working with long are (from flatbuffers.js)

/**
 * @param {number} high
 * @param {number} low
 * @returns {flatbuffers.Long}
 */

flatbuffers
.Long.create = function(low, high) {
 
// Special-case zero to avoid GC overhead for default values
 
return low == 0 && high == 0 ? flatbuffers.Long.ZERO : new flatbuffers.Long(low, high);
};


/**
 * @returns {number}
 */

flatbuffers
.Long.prototype.toFloat64 = function() {
 
return this.low + this.high * 0x100000000;
};


I've tried a million ways to make this work..has anyone had any success. Doesn't work with values <max int32 I'm still new to the JS implementation and FB in general...so this is driving me crazy.

Sam Paioletti

unread,
Nov 4, 2016, 5:43:55 PM11/4/16
to FlatBuffers
Ok solved it(mostly)...All I had to do was post...I'll put my revision up for posterity..pretty sure I lost a few years on this. Just had the low and high values mixed up..

I've noticed some issues with the precision on higher numbers...so this maybe an incomplete solution, but its working for now. Opinions/Fixes welcome

var value=Math.pow(2,53); //max safe int (53bit) 9007199254740992

var bin= value.toString(2); //go binary
var pad=new Array(65-bin.length).join('0') //could skip this and check for length...but this catches 32 bit and 64 bit
var high = parseInt(bin.substring(0, 32), 2);
var low = parseInt(bin.substring(32), 2);
var longInt = flatbuffers.Long.create(low,high)
console
.log(longInt.toFloat64()) //9007199254740992


I'm working on a PR for the writeUint methods, so I might add in a convenience helper like


flatbuffers.Long.fromFloat64 = function(value)...

to assist when creating a fb in js

Sam

Sam Paioletti

unread,
Nov 4, 2016, 5:55:32 PM11/4/16
to FlatBuffers
It may be worthwhile to also add a function for get/set 64 bit int as strings, or at least provide a function for getting them as strings, that way a user can implement the https://github.com/silentmatt/javascript-biginteger library without loosing precision if they need to work in 64bit int land....


On Friday, November 4, 2016 at 2:52:36 PM UTC-6, Sam Paioletti wrote:

Wouter van Oortmerssen

unread,
Nov 7, 2016, 1:20:20 PM11/7/16
to Sam Paioletti, FlatBuffers
Not that familiar with JS, or how people would commonly deal with 64bit integer values. A PR making this simpler would be welcome. Storing them in strings sounds.. inefficient, is that a common way to do it?

--
You received this message because you are subscribed to the Google Groups "FlatBuffers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to flatbuffers+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Sam Paioletti

unread,
Nov 7, 2016, 1:57:58 PM11/7/16
to Wouter van Oortmerssen, FlatBuffers

Yeah messing with large ints is a mess in js. The only ways I’ve seen involve working with the binary representation either as a string or as an ArrayBuffer. I’m not sure what’s more efficient I’ll do some research/testing when I have a chance. The biginteger library seems to be the most common way to work with them so I’ll check out what would be the most compatible. I would think bitwise shifting would be the best, but I can’t get it to work correctly, from my research it seems js converts anything you perform a bit operation on to a 32bit int…I have no idea why, but it makes it difficult to get the correct result without having to then convert it to a string anyway. I was trying to avoid ArrayBuffer since it’s a ES15 thing, that’s your call on how far back you want it to be compatible.

 

Sam

To unsubscribe from this group and stop receiving emails from it, send an email to flatbuffers...@googlegroups.com.

mikkelfj

unread,
Nov 9, 2016, 4:19:58 PM11/9/16
to FlatBuffers, w...@google.com
Speaking with no real knowledge on this, but I think there is a typed binary array type in the browser api which is used by JS flatbuffers to create efficient arrays of different types.
Reply all
Reply to author
Forward
0 new messages