问题描述
出于(有损)压缩的目的,我希望能够将Javascript数字转换为16位浮点表示形式,以存储在Uint16Arrays(或Uint8Arrays,以最简单的一个为准)中.然后,我希望能够进行转换从2个字节返回到一个数字.我不需要对16位数字执行任何算术运算,仅用于紧凑型存储.
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. I don't need to perform any arithmetic on the 16-bit numbers, it's just for compact storage.
我在寻找一种算法来执行此操作时遇到了麻烦.它不需要是IEEE标准,只需精确到小数点后几位即可.
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.
浮点数比定点数更可取,因为我宁愿不必预先确定值的范围.
Floats are preferable to fixed point because I'd rather not have to pre-determine the range of values.
推荐答案
编码
第一步是提取数字的指数和归一化分数.在C语言中,这是使用frexp
函数完成的,该函数在JavaScript中不可用.谷歌搜索frexp javascript
会产生一些实现.
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. Googling for frexp javascript
yields a couple of implementations.
例如,这是一个直接实现使用类型化数组直接从IEEE表示中提取位.这是仅使用Math
的速写,不精确的版本功能.这是精确(?)版本.
For example, here's a straight-forward implementation that extracts the bits directly from the IEEE representation using typed arrays. Here's a quick-and-dirty, inexact version using only Math
functions. Here's an exact (?) version.
第二步是使用位运算从获得的指数和尾数创建您的16位FP编号.确保检查指数范围并舍入较低精度的尾数以获得更好的精度.
The second step is to create your 16-bit FP number from the obtained exponent and mantissa using bit operations. Make sure to check the exponent range and to round the lower-precision mantissa for better accuracy.
从您的16位FP编号中提取指数和尾数.使用
Extract exponent and mantissa from your 16-bit FP number. Convert them to a JavaScript number either with
// The value of 'adjust' depends on the size of the mantissa.
Math.pow(2, exponent - adjust) * mantissa
或通过使用类型化数组直接创建IEEE位模式.
or by directly creating an IEEE bit pattern with typed arrays.
次标准JavaScript数字可以简单地四舍五入为零.您必须决定是否要支持16位格式的非正规数.这将使转换过程变得复杂,以换取更高的接近零的数字精度.
Subnormal JavaScript numbers can be simply rounded to zero. You'll have to decide whether you want to support subnormal numbers in your 16-bit format. This will complicate the conversion process in exchange for better accuracy of numbers near zero.
您还必须决定是否以您的格式支持Infinity和NaN.这些值的处理方式类似于IEEE格式.
You'll also have to decide whether to support infinity and NaN in your format. These values could be handled similarly to the IEEE format.
这篇关于将数字转换为16位浮点数(存储为字节)然后返回?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!