简体   繁体   English

将数字转换为16位浮点数(存储为字节)并返回?

[英]Convert a number into a 16-bit float (stored as bytes) and back?

For (lossy) compression purposes, I'd like to be able to convert Javascript numbers into 16-bit float representation to be stored in Uint16Arrays (or Uint8Arrays, whichever's easiest.) Then I'd like to be able to convert back from the 2 bytes to a number. 对于(有损)压缩目的,我希望能够将Javascript数字转换为16位浮点表示形式,以存储在Uint16Arrays(或Uint8Arrays中,无论哪个最简单。)然后我希望能够从2个字节到一个数字。 I don't need to perform any arithmetic on the 16-bit numbers, it's just for compact storage. 我不需要对16位数字执行任何算术,它只是用于紧凑存储。

I'm having trouble finding an algorithm to do this. 我找不到算法来做这件事。 It doesn't need to be a IEEE standard, just something accurate to a few decimal places. 它不需要是IEEE标准,只需要精确到几位小数。

Floats are preferable to fixed point because I'd rather not have to pre-determine the range of values. 浮点数优于固定点,因为我不必预先确定值的范围。

Encoding 编码

The first step is to extract the exponent and normalized fraction of the number. 第一步是提取数字的指数和标准化分数。 In C, this is done using the frexp function which isn't available in JavaScript. 在C中,这是使用frexp函数完成的,这在JavaScript中是不可用的。 Googling for frexp javascript yields a couple of implementations. 谷歌搜索frexp javascript产生了几个实现。

For example, here's a straight-forward implementation that extracts the bits directly from the IEEE representation using typed arrays. 例如,这是一个直接的实现 ,它使用类型化数组直接从IEEE表示中提取位。 Here's a quick-and-dirty, inexact version using only Math functions. 这是一个仅使用Math函数的快速,简洁,不精确的版本 Here's an exact (?) version . 这是一个精确的(?)版本

The second step is to create your 16-bit FP number from the obtained exponent and mantissa using bit operations. 第二步是使用位操作从获得的指数和尾数创建16位FP编号。 Make sure to check the exponent range and to round the lower-precision mantissa for better accuracy. 确保检查指数范围并舍入较低精度的尾数以获得更高的准确度。

Decoding 解码

Extract exponent and mantissa from your 16-bit FP number. 从16位FP编号中提取指数和尾数。 Convert them to a JavaScript number either with 将它们转换为JavaScript编号

// The value of 'adjust' depends on the size of the mantissa.
Math.pow(2, exponent - adjust) * mantissa

or by directly creating an IEEE bit pattern with typed arrays. 或者通过直接创建带有类型数组的IEEE位模式。

Subnormal numbers, infinity, NaN 次正规数,无穷大,NaN

Subnormal JavaScript numbers can be simply rounded to zero. 可以将次正规JavaScript数字简化为零。 You'll have to decide whether you want to support subnormal numbers in your 16-bit format. 您必须决定是否要支持16位格式的次正规数。 This will complicate the conversion process in exchange for better accuracy of numbers near zero. 这将使转换过程复杂化,以换取接近零的数字的更好准确性。

You'll also have to decide whether to support infinity and NaN in your format. 您还必须决定是否以您的格式支持无穷大和NaN。 These values could be handled similarly to the IEEE format. 可以类似于IEEE格式处理这些值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM