Javascript JS中浮点的读/写字节
有没有办法读取JS中浮点值的字节?我需要的是将一个原始浮点值或双精度值写入我需要生成的二进制格式,那么有没有办法获得一个逐字节的IEEE 754表示?当然,写作也要问同样的问题。我希望你能弄明白,布莱奇,但我想你是在问是否有内在的东西。我从来没有听说过;请参见的第8.5节和第15.7节。会有帮助吗Javascript JS中浮点的读/写字节,javascript,serialization,floating-point,math,ieee-754,Javascript,Serialization,Floating Point,Math,Ieee 754,有没有办法读取JS中浮点值的字节?我需要的是将一个原始浮点值或双精度值写入我需要生成的二进制格式,那么有没有办法获得一个逐字节的IEEE 754表示?当然,写作也要问同样的问题。我希望你能弄明白,布莱奇,但我想你是在问是否有内在的东西。我从来没有听说过;请参见的第8.5节和第15.7节。会有帮助吗 如果您需要一个功能强大的解决方案,Koolic的代码片段是很好的,但是如果您需要有限的使用,最好编写自己的代码。我编写了以下函数,用于将字节的字符串十六进制表示形式转换为浮点: function de
如果您需要一个功能强大的解决方案,Koolic的代码片段是很好的,但是如果您需要有限的使用,最好编写自己的代码。我编写了以下函数,用于将字节的字符串十六进制表示形式转换为浮点:
function decodeFloat(data) {
var binary = parseInt(data, 16).toString(2);
if (binary.length < 32)
binary = ('00000000000000000000000000000000'+binary).substr(binary.length);
var sign = (binary.charAt(0) == '1')?-1:1;
var exponent = parseInt(binary.substr(1, 8), 2) - 127;
var significandBase = binary.substr(9);
var significandBin = '1'+significandBase;
var i = 0;
var val = 1;
var significand = 0;
if (exponent == -127) {
if (significandBase.indexOf('1') == -1)
return 0;
else {
exponent = -126;
significandBin = '0'+significandBase;
}
}
while (i < significandBin.length) {
significand += val * parseInt(significandBin.charAt(i));
val = val / 2;
i++;
}
return sign * significand * Math.pow(2, exponent);
}
wikipedia上有详细的算法解释,这些算法用于在两个方向上转换所有格式的浮点,并且很容易使用它们来编写自己的代码。从数字到字节的转换应该更为困难,因为您需要首先对数字进行规范化。您可以使用以下方法进行转换:
或者另一种方式:
var view = new DataView(new ArrayBuffer(4));
view.setFloat32(0, Math.PI);
console.log(view.getInt32(0).toString(2)); //bits of the 32 bit float
不确定浏览器支持是什么样的,尽管我已经创建了一个Milos解决方案的扩展,速度应该快一点,假设TypeDarray不是一个选项,当然在我的情况下,我使用的是一个不可用的环境:
function Bytes2Float32(bytes) {
var sign = (bytes & 0x80000000) ? -1 : 1;
var exponent = ((bytes >> 23) & 0xFF) - 127;
var significand = (bytes & ~(-1 << 23));
if (exponent == 128)
return sign * ((significand) ? Number.NaN : Number.POSITIVE_INFINITY);
if (exponent == -127) {
if (significand == 0) return sign * 0.0;
exponent = -126;
significand /= (1 << 22);
} else significand = (significand | (1 << 23)) / (1 << 23);
return sign * significand * Math.pow(2, exponent);
}
给定一个包含4个字节的整数,其中包含一个IEEE-754 32位单精度浮点,这将在不使用任何循环的情况下生成大致正确的Javascript数字值。我遇到了一个类似的问题,我想将任何Javascript数字转换为缓冲区,然后在不进行字符串化的情况下对其进行解析 函数numberToBuffernum{ const buf=new Buffer8 buf.WriteDoubleEnum,0 返回buf } 使用示例:
// convert a number to buffer
const buf = numberToBuffer(3.14)
// and then from a Buffer
buf.readDoubleLE(0) === 3.14
这适用于当前节点LTS 4.3.1及更高版本。未在较低版本中进行测试。该代码段中使用的算法已彻底损坏。当用于读取浮点或双精度时,它在特定值上失败。例如,它将40.0读取为32.0,将20.0读取为16.0。拥有BinaryParser会使您依赖于该代码段。不要使用此BinaryParser类!它不是严格遵守它使用的!我已经扩展了这个解决方案来处理64位浮点和小尾端编码。它还需要一个字节数组,而不是一个base-16字符串,因此64位浮点可以正常工作,而不会出现舍入问题。很酷,TIL Double在Javascript中称为Float64。我一直在寻找DoubleArray-没有用-但是Float64Array存在,而且看起来很有用。请注意,IE9不支持这一点!看起来您至少可以在Chrome中使用Uint8Array,而不是Int32Array,以便更轻松地获取单个阵列bytes@bryc,Netscape Navigator支持也不完善。如果有效位==0,则返回符号*0.0;-当然,任何乘以零的东西都是。。。零-1*0.0是否产生负零?@Haravik,获取数字的位表示如何?@Pacerier:我对另一个问题的回答应该会有所帮助:我可以确认这也适用于Node.js 0.10.40。我的旧版本Node RED 0.11.1显然无法访问Float32Array,因此您的解决方案是我唯一的解决方案!我使用“new Bufferarray”从4字节二进制浮点数组创建缓冲区,并使用Buffer.readFloatBE0检索浮点。在Node.JS 10.15上测试,此解决方案似乎比使用类型化数组更快。显然,如果不使用Node.JS,就不能使用缓冲区。
function Bytes2Float32(bytes) {
var sign = (bytes & 0x80000000) ? -1 : 1;
var exponent = ((bytes >> 23) & 0xFF) - 127;
var significand = (bytes & ~(-1 << 23));
if (exponent == 128)
return sign * ((significand) ? Number.NaN : Number.POSITIVE_INFINITY);
if (exponent == -127) {
if (significand == 0) return sign * 0.0;
exponent = -126;
significand /= (1 << 22);
} else significand = (significand | (1 << 23)) / (1 << 23);
return sign * significand * Math.pow(2, exponent);
}
// convert a number to buffer
const buf = numberToBuffer(3.14)
// and then from a Buffer
buf.readDoubleLE(0) === 3.14