Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
关于JavaScript类型Darray float32的二进制格式_Javascript_Typedarray - Fatal编程技术网

关于JavaScript类型Darray float32的二进制格式

关于JavaScript类型Darray float32的二进制格式,javascript,typedarray,Javascript,Typedarray,我需要用JavaScript编写一个硬件模拟器。它有自己的浮点格式,所以我在JS numerics和该格式之间做了很多转换,这很慢。我有使用JavaScript类型Darray float32的想法,因为我可以直接访问形成float32浮点值的字节,这与所需的格式相差不远,因此这种方式的转换速度会快得多(使用float32的Uint8视图,只需要一些移位等) 然而,我不确定它的可移植性如何。关于TypedArray主题的各种文档都指出float32类似于“该硬件上的本机C格式”之类的东西。但是,

我需要用JavaScript编写一个硬件模拟器。它有自己的浮点格式,所以我在JS numerics和该格式之间做了很多转换,这很慢。我有使用JavaScript类型Darray float32的想法,因为我可以直接访问形成float32浮点值的字节,这与所需的格式相差不远,因此这种方式的转换速度会快得多(使用float32的Uint8视图,只需要一些移位等)

然而,我不确定它的可移植性如何。关于TypedArray主题的各种文档都指出float32类似于“该硬件上的本机C格式”之类的东西。但是,我能期望在运行某些浏览器/JS的所有平台上,float32的确切二进制格式都是相同的吗?我可以猜endiannes可能是个问题,但如果至少没有其他差异,我可以解决这个问题。据我所知,所使用的格式似乎是IEE754,但在一些(好吧,至少没有那么奇特的…)平台上,还可以使用其他格式在JS中实现float32


我至少可以测试x86和Apple A7 CPU,看起来它们非常相同,这很好,但也很奇怪,因为我认为这些CPU的字节顺序不同(可能至少不是浮动格式?)。然而,仅仅检查两个平台/操作系统/浏览器/任何东西都远远不是一个全球性的事实。

Float32Array将在内部表示基于主机系统的endian的值,通常是小endian

是的,格式是IEEE 754(在FPU出现之前就已经存在了,它的变化涉及更多的宽度,例如64位、80位等等)。JavaScript中的所有数字(
Number
)在内部表示为64位IEEE 754。对于类型化数组,32位和64位IEEE 754当然都可用

PowerPC和68k CPU使用big-endian(应该是这样的!)。所谓的网络顺序也是big-endian,许多与平台无关的文件格式以big-endian字节顺序存储(尤其是音频和图形)。大多数主流计算机使用小端CPU,如x86。因此,在这些组合的情况下,很可能需要处理不同的字节顺序

要处理endianess,您可以使用数据视图来代替Float32Array

例如:

var buffer = new ArrayBuffer(10240);    // some raw byte buffer
var view = new DataView(buffer);        // flexible view supporting endianness
现在,您可以读取和写入缓冲区中的任何位置,并记住endianess(DataView还允许读取/写入未对齐的位置,即,如果需要,您可以将Float32值写入位置3。您不能使用Float32/Uint32/Int16等)

浏览器将内部转换为正确的顺序-您只需按原样提供值:

view.setFloat32(pos, 0.5);              // big-endian
view.setFloat32(pos, 0.5, false)        // big-endian
view.setFloat32(pos, 0.5, true);        // little-endian
同样,在阅读时:

var n = view.getFloat32(pos);           // big-endian
var n = view.getFloat32(pos, false)     // big-endian
var n = view.getFloat32(pos, true);     // little-endian
提示:您可以在内部使用本机Float32Array,然后使用endianess对其进行读/写。这往往更快,但如果生成的缓冲区的endianess与主机系统不同,则需要在最后使用DataView进行转换:

var f32 = new Float32Array(buffer);     // or use a size
f32[0] = 0.5;
然后,为了确保您具有big-endian表示:

var view = new DataView(f32.buffer);
var msbVal = view.getFloat32(0):        // returns 32-bit repres. in big-endian
希望能给一些意见!如果你想让我详细说明的话,就向我提问吧