有什么办法可以在 JS 中读取浮点值的字节吗?我需要将原始 FLOAT 或 DOUBLE 值写入我需要制作的某种二进制格式,那么有没有办法获得逐字节的 IEEE 754 表示?当然还有同样的写作问题。
问问题
23919 次
6 回答
42
您可以使用类型化数组来做到这一点:
var buffer = new ArrayBuffer(4);
var intView = new Int32Array(buffer);
var floatView = new Float32Array(buffer);
floatView[0] = Math.PI
console.log(intView[0].toString(2)); //bits of the 32 bit float
或者另一种方式:
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
不确定浏览器支持是什么样的
于 2012-05-12T14:56:27.563 回答
8
我已经创建了 Milos 解决方案的扩展,它应该更快一些,假设 TypedArrays 当然不是一个选项(在我的情况下,我正在使用它们不可用的环境):
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 数值。
于 2013-04-14T15:54:02.650 回答
3
如果您需要一个功能强大的解决方案,Koolinc 的代码片段很好,但如果您需要它以进行有限的使用,您最好编写自己的代码。我编写了以下函数,用于将字节的字符串十六进制表示形式转换为浮点数:
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 上对所有浮点格式的双向转换算法都有详细的解释,使用这些算法编写自己的代码很容易。从数字转换为字节应该更困难,因为您需要先对数字进行规范化。
于 2011-12-17T14:31:01.570 回答
3
我有一个类似的问题,我想将任何 javascript 数字转换为 Buffer,然后在不对其进行字符串化的情况下将其解析回来。
function numberToBuffer(num) {
const buf = new Buffer(8)
buf.writeDoubleLE(num, 0)
return 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) 及更高版本。没有在较低版本中测试。
于 2016-03-02T13:28:09.690 回答
2
这个片段有帮助吗?
var parser = new BinaryParser
,forty = parser.encodeFloat(40.0,2,8)
,twenty = parser.encodeFloat(20.0,2,8);
console.log(parser.decodeFloat(forty,2,8).toFixed(1)); //=> 40.0
console.log(parser.decodeFloat(twenty,2,8).toFixed(1)); //=> 20.0
于 2010-12-10T23:45:19.500 回答
0
我希望你能弄清楚(blech),但我假设你在问是否有内置的东西。不是我听说过的;请参阅规范的第 8.5 和 15.7 节。
于 2010-12-10T23:09:32.353 回答