JavaScript-以干净的方式将字节转换为浮点数 [英] JavaScript - Convert bytes into float in a clean way

查看:397
本文介绍了JavaScript-以干净的方式将字节转换为浮点数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近发现我可以将Float32转换为表示它的字节数组-这样:

  let number = Math.PI; 
let bytes = new Uint8Array(new Float32Array([number])。buffer); // [[219,15,73,64]

是否可以转换 bytes 以干净的方式返回到Float32中?

解决方案

< blockquote>

有没有一种方法可以将字节转换回Float32


您不需要转换它已经在那里!您只需要从float32视图中读取它即可。但是,在您的示例中,您没有保存对float32视图的引用...



类型化数组的工作方式与JavaScript中的其他数字非常不同。关键是要独立考虑缓冲区和视图-即Float32Array和Uint8Array只是缓冲区中的 views (缓冲区只是固定大小的连续内存块,这就是为什么类型化数组是如此之快)。



在您的示例中,当您调用 new Float32Array 时,将其传递给一个带有单个数字的数组初始化它,但是您没有传递给它一个缓冲区,这使它为您创建了一个适当长度(4个字节)的缓冲区。当您调用 new Uint8Array 时,您为其传递了一个缓冲区,这并不意味着它仅复制缓冲区,而是实际上直接使用它。下面的示例与您的示例相同,但是保留所有引用,并使上述声明更加明显:

  const number = Math.PI 

常量缓冲区= new ArrayBuffer(4);
const f32 =新的Float32Array(buffer); // [0]
const ui8 = new Uint8Array(buffer); // [0,0,0,0]

f32 [0] =数字;
f32 // [3.1415927410125732]
ui8 // [219,15,73,64]

ui8 [3] = 1;
f32 // [3.6929245196445856e-38]
ui8 // [219、15、73、1]

如您所见,由于两个视图共享相同的缓冲区,因此无需在上方进行转换,通过一个视图进行的任何更改在另一个视图中都将立即可用。



这实际上是使用和理解浮点格式的好方法。也使用 ui8 [i] .toString(2)来获取原始二进制文件,并使用 ui8 [i] = parseInt('01010101',2) 为i为0-3的每个字节设置原始二进制。请注意,您无法通过f32视图设置原始二进制文件,因为它将通过数字方式解释您的数字并将其分解为有效位数和指数,但是您可能需要执行此操作,以查看数字二进制文件如何转换为float32格式。


I recently found out I can convert a Float32 into an array of bytes that represent it - as such:

let number = Math.PI;
let bytes = new Uint8Array(new Float32Array([number]).buffer); // [219, 15, 73, 64]

Is there a way to convert bytes back into the Float32, in a clean way?

解决方案

Is there a way to convert bytes back into the Float32

You don't need to convert it, it's already there! you just need to read it from the float32 view. However in your example you didn't save a reference to the float32 view...

Typed arrays work very differently to other numbers in JavaScript. The key is to think about the buffer and views independently - that is, Float32Array and Uint8Array are merely views into a buffer (a buffer is just a fixed sized contiguous block of memory, which is why typed arrays are so fast).

In your example when you called new Float32Array you passed it an array with a single number to initialise it, but you didn't pass it a buffer, this causes it to create a buffer for you of the appropriate length (4 bytes). When you called new Uint8Array you passed it a buffer instead, this doesn't cause it to merely copy the buffer, but it actually uses it directly. The below example is equivalent to yours, but retains all references and makes the above assertions more obvious:

const number = Math.PI

const buffer = new ArrayBuffer(4);
const f32 = new Float32Array(buffer); // [0]
const ui8 = new Uint8Array(buffer); // [0, 0, 0, 0]

f32[0] = number;
f32 // [3.1415927410125732]
ui8 // [219, 15, 73, 64]

ui8[3] = 1;
f32 // [3.6929245196445856e-38]
ui8 // [219, 15, 73, 1]

As you can see there is no need to "convert" above, as both views share the same buffer, any change via one view is instantly available in the other.

This is actually a good way to play with and understand floating point formats. Also use ui8[i].toString(2) to get the raw binary and use ui8[i] = parseInt('01010101', 2) set raw binary for each byte where i is 0-3. Note that you cannot set the raw binary through the f32 view as it will interpret your number numerically and break it into the significand and exponent, however you may want to do this to see how the numerical binary is converted into the float32 format.

这篇关于JavaScript-以干净的方式将字节转换为浮点数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆