0

我正在尝试处理不同类型的类型化数组之间的交互。

示例 1。

var buf = new ArrayBuffer(2);
var arr8 = new Int8Array(buf);
var arr8u = new Uint8Array(buf);

arr8[0] = 7.2;
arr8[1] = -45.3;

console.log(arr8[0]);       // 7
console.log(arr8[1]);       // -45
console.log(arr8u[0]);      // 7
console.log(arr8u[1]);      // 211

我对前三个读数没有问题,但最后一个读数是 211 是从哪里来的。由于减号,这是否与位移有关。

示例 2

var buf = new ArrayBuffer(4);
var arr8 = new Int8Array(buf);
var arr32 = new Int32Array(buf);

for (var i = 0; i < buf.byteLength; i++){
    arr8[i] = i;
}

console.log(arr8);      // [0, 1, 2, 3]
console.log(arr32);     // [50462976]

那么 50462976 是从哪里来的呢?

4

2 回答 2

4

示例 #1

检查正 45 作为二进制数:

> (45).toString(2)
"101101"

二进制值使用二进制补码求反:

00101101 => 45 signed 8-bit value
11010011 => -45 signed 8-bit value

当我们读取时,我们读取11010011为无符号 8 位值,结果为211

> parseInt("11010011", 2);
211

示例 #2

如果您50462976以基数 2 打印:

> (50462976).toString(2);
"11000000100000000100000000"

我们可以添加前导零并将其重写为:

00000011000000100000000100000000

我们可以把它分解成八位字节:

00000011 00000010 00000001 00000000

这显示二进制3210。32 位整数的存储是大端的。在构造 32 位值时,按重要性递增的顺序读取 8 位值 0 到 3。

于 2013-10-30T19:54:52.053 回答
2

第一个问题。

有符号的 8 位整数范围从 -128 到 127。正数部分 (0-127) 映射到二进制值 00000000to 01111111),另一半 (-128-1)映射到10000000to 11111111

如果省略第一位,则可以通过将 7 位数字添加到边界来创建数字。在您的情况下,二进制表示是11010011. 第一位是1,这意味着数字将为负数。最后 7 位是1010011,这给了我们价值83。将其添加到边界:-128 + 83 = -45. 而已。

第二个问题。

32 位整数在内存中由四个字节表示。您正在缓冲区中存储四个 8 位整数。当转换为 时Int32Array,所有这些值都会组合成一个值。

如果这是十进制系统,您可以将其视为“1”和“2”的组合得到“12”。在这种情况下它是相似的,除了乘数不同。对于第一个值,它是2^24. 然后是2^16,然后2^8,最后2^0。让我们算一下:

2^24 * 3 + 2^16 * 2 + 2^8 * 1 + 2^0 * 0 =
16777216 * 3 + 65536 * 2 + 256 * 1 + 1 * 0 =
50331648 + 131072 + 256 + 0 =
50462976

这就是为什么你会看到这么多的数字。

于 2013-10-30T20:00:26.503 回答