"combine" two 32bit values into a 64 bit

Questions, tips and tricks and techniques for scripting in Servoy

"combine" two 32bit values into a 64 bit

Postby jeffspalla » Wed Oct 27, 2010 12:57 am

We need to "combine" two 32bit values into a 64 bit value as "high and low".

In c/c++ we could do this using either a union overlay or a bit-shift

////////////////////////////////////////////////////////////

// my 32bit values
long lMyLow = 1234;
long lMyHigh = 5678;

////////////////////////////
// combine as union overlay

/*
// Microsoft LARGE_INTEGER union type
typedef union _LARGE_INTEGER {
struct {
DWORD LowPart;
LONG HighPart;
};
struct {
DWORD LowPart;
LONG HighPart;
} u;
LONGLONG QuadPart;
} LARGE_INTEGER;
*/

LARGE_INTEGER LIMyValue;

LIMyValue.LowPart = lMyLow;
LIMyValue.HighPart = lMyHigh;

// result - LIMyValue.QuadPart == 24386824307922


////////////////////////////
// combine as bit shift

unsigned __int64 ui64MyValue = 0;

ui64MyValue = ((unsigned __int64)lMyHigh << (unsigned __int64)32L) | (unsigned __int64)lMyLow;

// result - ui64MyValue == 24386824307922

How would you do that in JavaScript or Java?
Reeldata, Inc.
Servoy 4.1.7, MySQL 5.1
Windows Vista, Mac 1.6.3
jeffspalla
 
Posts: 10
Joined: Thu Oct 09, 2008 3:29 am

Re: "combine" two 32bit values into a 64 bit

Postby jcompagner » Wed Oct 27, 2010 4:35 pm

use the same thing in js, for example:
http://www.java2s.com/Tutorial/JavaScri ... ftLeft.htm

so shift the high first 32 positions then add the low
Johan Compagner
Servoy
User avatar
jcompagner
 
Posts: 8833
Joined: Tue May 27, 2003 7:26 pm
Location: The Internet

Re: "combine" two 32bit values into a 64 bit

Postby Jeroen de Vries » Thu Oct 28, 2010 8:48 am

Hi Jeff,

shifting the least significant 32 bits to the most significant 32 bits of a 64 bits integers is the same as multiplying by 4294967296.

Your task can be accomplished by:

Code: Select all
var lMyLow = 1234;
var lMyHigh = 5678;
var result = lMyHigh * 4294967296 + lMyLow
Jeroen de Vries
Softwear BV
www.softwear.nl
Jeroen de Vries
 
Posts: 61
Joined: Sun Mar 02, 2008 12:18 pm

Re: "combine" two 32bit values into a 64 bit

Postby jeffspalla » Thu Dec 02, 2010 1:06 am

Thanks for the support up on the original request... here's a followup

Unsigned 64bit integers in Servoy / MySql

We have need to generate large integer value in Servoy and record the vaule in MySql.

The MAX value we need to hold is 18446744073709551615 (in c, unsigned longlong, or unsigned __int64, _UI64_MAX ).

MySql will hold this value directly, no problem, but -

We need to generate these values within Servoy by combining two 32bit values (in c, unsigned long) into a 64bit value by setting the high 32bits of the 64 to the first 32bit value, and the low 32bits of the 64 to the second 32bit value.

In c, this may be done -

unsigned long ul32Val_High = 4294967295; // ULONG_MAX
unsigned long ul32Val_Low = 4294967295; // ULONG_MAX
unsigned __int64 ui64Value = ((unsigned __int64)ul32Val_High << (unsigned __int64)32) | (unsigned __int64)ul32Val_Low;
//Result - ui64Value == 18446744073709551615 == _UI64_MAX == 0xffffffffffffffffui64

Or, alternatively -

ui64Value = (unsigned __int64)ul32Val_High * (((unsigned __int64)4294967295) + 1);
ui64Value += (unsigned __int64)ul32Val_Low;
//Result - ui64Value == 18446744073709551615 == _UI64_MAX == 0xffffffffffffffffui64

But the JavaScript number type is signed 64bit double (floating point), which will obviously overflow (badly!). You can't go -

var My64 = 4294967295 * (4294967295 + 1);

Does anyone have a suggestion how to handle this?
Reeldata, Inc.
Servoy 4.1.7, MySQL 5.1
Windows Vista, Mac 1.6.3
jeffspalla
 
Posts: 10
Joined: Thu Oct 09, 2008 3:29 am

Re: "combine" two 32bit values into a 64 bit

Postby jcompagner » Thu Dec 02, 2010 11:23 am

for that kind of large numbers you have to use BigInteger or BigDecimal java.math classes..

So then you get something like this:

var bigInt1 = java.math.BigInteger.valueOf(4294967295);
var bigInt2 = java.math.BigInteger.valueOf(4294967295);
bigInt1 = bigInt1.shiftLeft(32);
bigInt1 = bigInt1.add(bigInt2);

application.output(bigInt1);


the thing is that above will not work because it will give you an error that shiftLeft() is unknown, this is because internally BigInteger is just seen as a Number and will be converted to it at the moment you call something on it..
We have to do that because the database can give us BigDecimals back and those are BigDecimals until you do something with it in js..
If we didnt see that as a number then this wouldn't work:

var x = bigInt1 + 1;

because that will not work on a BigDecimal/BigInteger instances you have to do bigInt1.add(1) to give you a result.

So inside js this is not really doable, you have to create a simple plugin for that that you give 2 doubles (or 2 strings representing the numbers) and then you do the above code.
Then you should return a BigDecimal from that java function (don't return a BigInteger servoy will convert that to a double again) and if you assign that BigDecimal to your big mysql column it should work fine.
Johan Compagner
Servoy
User avatar
jcompagner
 
Posts: 8833
Joined: Tue May 27, 2003 7:26 pm
Location: The Internet


Return to Methods

Who is online

Users browsing this forum: No registered users and 6 guests