gpt4 book ai didi

javascript - Buffer 和 TypedArray 转换导致数据突变?

转载 作者:行者123 更新时间:2023-12-03 02:53:16 27 4
gpt4 key购买 nike

我正在通过 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 转换时或Buffer它使用底层 Uint8Array float 数据已发生变化。

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, …]

最终输出的这种差异完全破坏了我期望 new Float32Array 的工作管道。输出

我正在寻找关于为什么会发生这种情况的解释和教育回应。

最佳答案

这是因为 Uint8 数组( View )保存的每个值都会根据 View 而不是底层 ArrayBuffer 转换为完整的 Float32 值。

如果您有一个包含 4 个条目的 Uint8Array View :

Uint8 -> [1,2,3,4]

在 ArrayBuffer 中,它看起来像这样(ArrayBuffer 始终是一个字节数组):

0x01020304

然后发生的情况是,当您将 Uint8 View 转换为 Float32 View 时,将使用 View 表示形式中的值(即 [1,2,3,4]),而不是底层的 ArrayBuffer ,因此这些条目只是转换为新条目,但采用不同的类型,但仍表示与原始 View 表示的相同数字 [1,2,3,4]:

Float32 -> [1,2,3,4]   (each entry stored as 32-bit value)

新的 ArrayBuffer 看起来像(手动转换,但你会明白的)由 Float32 表示的 4 个字节(32 位)x 4 个值组成 - 还要注意浮点值以 IEEE754 编码。 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 View 一起使用时的数字是正确的,因此在这种情况下这可能不是问题。

简而言之:没有发生突变,但不同的类型(通过 View )需要不同数量的字节,在本例中,Uint8 是底层 ArrayBuffer 中的一个字节,Float32 是底层 ArrayBuffer 中的 4 个字节,这意味着它们将转换为通过 View 显示的不同值。

关于javascript - Buffer 和 TypedArray 转换导致数据突变?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47746378/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com