我正在通过XHR加载远程资产并将其作为arrayBuffers
接收。基础数据依赖于float32
。我需要对这些数组缓冲区进行一些进一步的操作,比如连接和合并。对于这些操作,我正在试验buffer module。
我发现使用Buffer模块和底层的Uint8Array正在改变预期的float32
输出
使用TypedArray
构造函数实例化new Float32Array
时,数据是正确的。
new Float32Array(action.payload.arrayBuffer)
Float32Array(9072) [-5, 35, -5, 255, 127, 128, 128, 1, 0.2666666805744171, 0.2666666805744171, 0.2666666805744171, 1, -5, 34, -5, 255, 127, 128, 128, 1, 0.2666666805744171, 0.2666666805744171, 0.2666666805744171, 1, -5, 35, -2, 255, 127, 128, 128, 1, 0.2666666805744171, 0.2666666805744171, 0.2666666805744171, 1, -5, 34, -2, 255, 127, 128, 128, 1, 0.2666666805744171, 0.2666666805744171, 0.2666666805744171, 1, -5, 35, -2, 255, 127, 128, 128, 1, 0.2666666805744171, 0.2666666805744171, 0.2666666805744171, 1, -5, 34, -5, 255, 127, 128, 128, 1, 0.2666666805744171, 0.2666666805744171, 0.2666666805744171, 1, -5, 38, -2, 255, 127, 128, 128, 2, 0.9411764740943909, 0.3686274588108063, 0.10980392247438431, 1, -5, 34, -2, 255, 127, 128, 128, 2, 0.9411764740943909, 0.3686274588108063, 0.10980392247438431, 1, -5, 38, 1, 255, …]
使用TypedArray
方法初始化from
时,数据为空。这是预期的,因为from
方法需要一个可迭代的数组,arrayBuffer
不是。
Float32Array.from(action.payload.arrayBuffer)
Float32Array []
从使用基础Uint8Array
的{{1}}或Buffer
进行转换时,浮动数据会发生变异。
Uint8Array
最终输出的这种差异完全打破了我期望Float32Array.from(new Uint8Array(action.payload.arrayBuffer))
Float32Array(36288) [0, 0, 160, 192, 0, 0, 12, 66, 0, 0, 160, 192, 0, 0, 127, 67, 0, 0, 254, 66, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 128, 63, 137, 136, 136, 62, 137, 136, 136, 62, 137, 136, 136, 62, 0, 0, 128, 63, 0, 0, 160, 192, 0, 0, 8, 66, 0, 0, 160, 192, 0, 0, 127, 67, 0, 0, 254, 66, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 128, 63, 137, 136, 136, 62, 137, 136, 136, 62, 137, 136, 136, 62, 0, 0, 128, 63, 0, 0, 160, 192, …]
Float32Array.from(Buffer.from(action.payload.arrayBuffer))
Float32Array(36288) [0, 0, 160, 192, 0, 0, 12, 66, 0, 0, 160, 192, 0, 0, 127, 67, 0, 0, 254, 66, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 128, 63, 137, 136, 136, 62, 137, 136, 136, 62, 137, 136, 136, 62, 0, 0, 128, 63, 0, 0, 160, 192, 0, 0, 8, 66, 0, 0, 160, 192, 0, 0, 127, 67, 0, 0, 254, 66, 0, 0, 0, 67, 0, 0, 0, 67, 0, 0, 128, 63, 137, 136, 136, 62, 137, 136, 136, 62, 137, 136, 136, 62, 0, 0, 128, 63, 0, 0, 160, 192, …]
输出
我正在寻找关于为什么会发生这种情况的解释和教育回应。
答案 0 :(得分:1)
这是因为Uint8数组(视图)保存的每个值都会根据视图而不是基础ArrayBuffer转换为完整的Float32值。
如果您有一个Uint8Array视图,其中包含4个条目:
Uint8 -> [1,2,3,4]
在ArrayBuffer中它看起来像这样(ArrayBuffer总是一个字节数组):
0x01020304
当您将Uint8视图转换为Float32视图时,会使用视图表示中的值(即[1,2,3,4]),而不是基础ArrayBuffer ,所以这些条目只是转换为新条目,但在不同的类型中仍然代表与原始视图相同的数字[1,2,3,4]:
Float32 -> [1,2,3,4] (each entry stored as 32-bit value)
新的ArrayBuffer看起来像(手动转换,但你会得到这个想法)由Float32代表的4个字节(32位)x 4值组成 - 还要注意浮点值是用{{3为Float32类型表示的每个数字使用4个字节的格式:
0x00003F80 00000040 00004040 00004080 (=1,2,3,4 as IEEE754 encoded floating point values)
您还可以从新的基础ArrayBuffer的字节大小(来自问题中的数字)中看到这一点:
9,072 x 4 = 36,288 bytes
为了获得结果,您希望必须通过其buffer
属性直接使用缓冲区:
new Float32Array(uint8array.buffer); // notice .buffer -> actual ArrayBuffer
这与你在问题的第一行中的方式相同:
new Float32Array(action.payload.arrayBuffer);
字节顺序是这里的一个方面,但是因为直接从XHR使用Float32视图的数字是正确的,所以在这种情况下这可能不是问题。
所以简而言之:没有发生突变,但是不同的类型(通过视图)需要不同的字节数,在这种情况下,Uint8来自底层ArrayBuffer的单个字节和来自相同的Float32 4个字节,这意味着它们将通过视图转换为不同的值。