Converting an Array of Hexadecimal Strings to Numbers

981 views Asked by At

I have an application in which a server is sending a lot of data every second to clients that request it. In this data set are several (large) arrays that contain numbers (in some cases 16-bit integers and in others double precision floats). In order to reduce the packet size, I would like to send only the number of bytes that are necessary to represent the number (2 bytes for the 16 bit and 8 for the 64 bit). I know that I can do something like this:

/* Create space for 4 32 bit numbers */
var buffer = new ArrayBuffer(16);

/* Hex representation of [0, 123, 246, 369] */
buffer = ["0x0", 0x7B", "0xF6", "0x171"];

/* Actual array containing numbers above */
var int32View = new Int32Array(buffer); 

but....I don't want to prepend everything sting with "0x" (adding two bytes will double the size of the 16 bit numbers). I think I might be missing something - is there a better way to do this such that I don't need to indicate that the strings are hexadecimal representations of numbers (i.e. can I drop the "0x")?

Thanks, Matt

1

There are 1 answers

1
AudioBubble On BEST ANSWER

You can use map() or a for-loop to treat each value and use the length as basis for where to sort them out.

One note though, you mention 64-bit floats. When these are extracted from a buffer they will be 64-bit integer values (ie. 0xXXXXXXXXXXXXXXXX) formatted in IEEE-754 format.

However, JavaScript can only work with 32-bit values (0xXXXXXXXX) so you have to split the processing of those into two parts using a 32-bit unsigned array, then add a Float64Array view for that later.

If the float values are literals, ie "2.345", "-1.33" etc. then you can simply use parseFloat(str) on them (instead of handling 64-bit values as below).

Example

// inserted 64-bit IEEE float of -2.3357 = 0x7b4a233ac002af83
var normArray = ["0", "7B", "F6", "7b4a233ac002af83", "171"],
    int16a = [], int32a = [],
    int16b, int32b, float64b;

normArray.map(function(entry) {
  if (entry.length > 4) {
    var high = entry.substr(0, 8),
        low = entry.substr(8, 8);
    int32a.push(parseInt(high, 16), parseInt(low, 16));
  }
  else {
    int16a.push(parseInt(entry, 16));
  }
});

// convert to typed arrays
int16b = new Int16Array(int16a);
int32b = new Uint32Array(int32a);
float64b = new Float64Array(int32b.buffer); // convert IEEE rep. to floats

document.writeln("<pre>int16  : " +
                int16b[0] + ", " + int16b[1] + ", " + int16b[2] + ", ...");
document.write("float64: " + float64b[0] + "</pre>")