我需要用JavaScript编写一个硬件模拟器。它有自己的浮点格式,所以我在JS数字和那种格式之间做了很多转换,这很慢。我有想法使用JavaScript TypedArray float32,因为我可以直接访问形成float32浮点值的字节,这个值离所需格式不远,所以转换速度会快得多(只有一些转换,等等,使用Uint8)观看Float32)。
但是,我不确定它是多么便携的解决方案。有关TypedArray主题的各种文档声明float32类似于“该硬件上的本机C格式”等。但是我可以期望在运行某些浏览器/ JS的所有平台上,float32的确切二进制格式是相同的吗?我可以猜测endiannes可能是一个问题,但如果至少没有其他差异我可以处理。据我所知,使用的格式似乎是IEE754,但是有些其他用于在JS上实现float32的某些(好吧,至少不是那么奇特......)平台?
我至少可以测试x86和Apple A7 CPU,看起来它们是一样的,这很好,但也很奇怪,因为我认为这些CPU的字节顺序不同(可能至少不是浮动格式) ?)。然而,仅仅检查两个平台/操作系统/浏览器/无论是......还是一个全球真理......
答案 0 :(得分:2)
Float32Array
将在内部表示基于主机系统的endianess的值,通常是little-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,您可以使用 DataView 而不是使用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;
然后确保你有大端代表:
var view = new DataView(f32.buffer);
var msbVal = view.getFloat32(0): // returns 32-bit repres. in big-endian
希望能提供一些意见!如果你想让我详细说明某些部分,请告诉我有关它的问题。