将十六进制字符串数组转换为数字
Converting an Array of Hexadecimal Strings to Numbers
我有一个应用程序,其中服务器每秒向请求它的客户端发送大量数据。在这个数据集中有几个包含数字的(大)数组(在某些情况下是 16 位整数,在其他情况下是双精度浮点数)。为了减小数据包大小,我只想发送表示数字所需的字节数(16 位为 2 个字节,64 位为 8 个字节)。我知道我可以做这样的事情:
/* 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);
但是....我不想在所有字符串前加上“0x”(添加两个字节将使 16 位数字的大小加倍)。我想我可能遗漏了一些东西 - 有没有更好的方法来做到这一点,这样我就不需要指出字符串是数字的十六进制表示(即我可以删除“0x”)吗?
谢谢,马特
您可以使用 map() 或 for 循环来处理每个值,并使用长度作为对它们进行排序的基础。
请注意,您提到了 64 位浮点数。当这些从缓冲区中提取时,它们将是 64 位整数值(即 0xXXXXXXXXXXXXXXXX),采用 IEEE-754 格式。
但是,JavaScript 只能处理 32 位值 (0xXXXXXXXX),因此您必须使用 32 位无符号数组将这些处理分成两部分,然后为此添加一个 Float64Array 视图稍后。
如果浮点值是文字,即“2.345”、“-1.33”等,那么您可以简单地对它们使用 parseFloat(str)
(而不是像下面那样处理 64 位值)。
例子
// 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>")
我有一个应用程序,其中服务器每秒向请求它的客户端发送大量数据。在这个数据集中有几个包含数字的(大)数组(在某些情况下是 16 位整数,在其他情况下是双精度浮点数)。为了减小数据包大小,我只想发送表示数字所需的字节数(16 位为 2 个字节,64 位为 8 个字节)。我知道我可以做这样的事情:
/* 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);
但是....我不想在所有字符串前加上“0x”(添加两个字节将使 16 位数字的大小加倍)。我想我可能遗漏了一些东西 - 有没有更好的方法来做到这一点,这样我就不需要指出字符串是数字的十六进制表示(即我可以删除“0x”)吗?
谢谢,马特
您可以使用 map() 或 for 循环来处理每个值,并使用长度作为对它们进行排序的基础。
请注意,您提到了 64 位浮点数。当这些从缓冲区中提取时,它们将是 64 位整数值(即 0xXXXXXXXXXXXXXXXX),采用 IEEE-754 格式。
但是,JavaScript 只能处理 32 位值 (0xXXXXXXXX),因此您必须使用 32 位无符号数组将这些处理分成两部分,然后为此添加一个 Float64Array 视图稍后。
如果浮点值是文字,即“2.345”、“-1.33”等,那么您可以简单地对它们使用 parseFloat(str)
(而不是像下面那样处理 64 位值)。
例子
// 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>")