trying to pack a long (64-bit signed integer) with bytes

Hi,

Per another discussion, "Number and Float are signed 32 bit int/float. Long/Double are signed 64 bit long/double"
I'm trying to pack in 8 bytes into the 64 bit long, and I'm running into trouble having my number being interpreted as a negative number, because it is a signed long.  Is there a way to pack the numbers like below, into the higher 4 bytes?  I'm trying to recover the numbers at the bottom of the page
var testval = 4836421344300002098; 
System.println(testval); // this prints -1826723022, not what I want, indicating to me that ConnectIQ is interpreting this as a signed long, not an unsigned long. It's the expected behavior, I was just wondering if anyone knows what I could do, to pack the numbers in to the higher 4 bytes
var testval = 1126067094;‭ 
System.println(testval); // this prints 1126067094
var packed_value = testval;
// the goal is to unpack the values as follows
var h = packed_value & 255;
packed_value >>= 8;
var g = packed_value & 255;
packed_value >>= 8;
var f = packed_value & 255;
packed_value >>= 8;
var e = packed_value & 255;
packed_value >>= 8;
var d = packed_value & 255;
packed_value >>= 8;
var c = packed_value & 255;
packed_value >>= 8;
var b = packed_value & 255;
packed_value >>= 8;
var a = packed_value & 255;
// values I previously packed into testval = [ 67, 30 , 107, 150 , 147, 30, 107, 50 ] ;
System.println("abcdefgh: " + a + ", " + b + ", " + c + ", " + d + ", " + e + ", " + f + ", " + g + ", " + h );
// the output with the long number is abcdefgh: 255, 255, 255, 255, 147, 30, 107, 50
  • Per the documentation;

    To use a Long value in Monkey C add 'l' to the end of the number.

    G

    developer.garmin.com/.../Long.html

  • As states, use "l" to specify it's a long.

    As far as "packing" looks like your taking a 64 bit value and covering it to 8 32bit values

    if  you want the 64 bit long as 8 bytes, look at using a ByteArray and encodeNumber().  While there's no convert for a 64 bit, you can do something with NUMBER_FORMAT_UINT32 for the top 32 bits and the lower 32 bits.  

    It all depends on what you want to do with the result

  • I've successfully done byte-packing to save memory in a couple of Monkey C apps. It was really helpful for storing static data in my apps when I knew that the range of values was only 8 or 16 bits. I cut down memory usage for constant data arrays by packing 2 to 4 values in each array element.

    It doesn't matter whether Monkey C interprets the full 64-bit value as a signed or unsigned value, as you only care about 8-bit chunks which you've packed into it (each of which are "unsigned", since they'll ultimately be interpreted as 32-bit integers with 0s in the upper 24-bits). Same applies if you're packing four 8-bit values in a 32-bit int.

    I'm not sure how you got "1126067094" in your example, but I get a completely different number when I try to pack those values into a 64-bit value.

    Here's a code fragment which tests unpacking of:

    - values packed at run-time

    - pre-packed values (where the full 64-bit value is calculated elsewhere and inserted as a constant in your program)

    function testPacking() {
    	//  Run-time packing using Monkey C
    	var x8 = 128l;
    	var x7 = 2l;
    	var x6 = 3l;
    	var x5 = 4l;
    	var x4 = 5l;
    	var x3 = 6l;
    	var x2 = 7l;
    	var x1 = 8l;
    	var x = (x8 << 56) | (x7 << 48) | (x6 << 40) | (x5 << 32) | (x4 << 24) | (x3 << 16) | (x2 << 8) | (x1);
    	
    	System.println("x8 = " + (x >> 56) & 0xff);
    	System.println("x7 = " + (x >> 48) & 0xff);
    	System.println("x6 = " + (x >> 40) & 0xff);
    	System.println("x5 = " + (x >> 32) & 0xff);
    	System.println("x4 = " + (x >> 24) & 0xff);
    	System.println("x3 = " + (x >> 16) & 0xff);
    	System.println("x2 = " + (x >> 8) & 0xff);
    	System.println("x1 = " + (x >> 0) & 0xff);
    	
    	// Pre-packed value
    	System.println("");
    	x = 3633031143637065283l; 
    	// 3633031143637065283 is the result of evaluating following expression in SpeedCrunch: 
    	// 67 | (30 << 8) | (107 << 16) | (150 << 24) | (147 << 32)| (30 << 40) | (107 << 48) | (50 << 56) 
    	
    	System.println("x8 = " + (x >> 56) & 0xff);
    	System.println("x7 = " + (x >> 48) & 0xff);
    	System.println("x6 = " + (x >> 40) & 0xff);
    	System.println("x5 = " + (x >> 32) & 0xff);
    	System.println("x4 = " + (x >> 24) & 0xff);
    	System.println("x3 = " + (x >> 16) & 0xff);
    	System.println("x2 = " + (x >> 8) & 0xff);
    	System.println("x1 = " + (x >> 0) & 0xff);
    	 
    }

    This is the output I get:

    My run-time packing example:

    x8 = 128
    x7 = 2
    x6 = 3
    x5 = 4
    x4 = 5
    x3 = 6
    x2 = 7
    x1 = 8

    Pre-packed constant, using the values in your example:

    x8 = 50
    x7 = 107
    x6 = 30
    x5 = 147
    x4 = 150
    x3 = 107
    x2 = 30
    x1 = 67

    As noted in the comment, I used SpeedCrunch to pre-pack the values for the second example:

    https://speedcrunch.org/

  • Late to the thread, I have implemented a library for packing a long with various data. See https://github.com/mannyray/GarminBytePacking for examples.