Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/473.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript JS中浮点的读/写字节_Javascript_Serialization_Floating Point_Math_Ieee 754 - Fatal编程技术网

Javascript JS中浮点的读/写字节

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

有没有办法读取JS中浮点值的字节?我需要的是将一个原始浮点值或双精度值写入我需要生成的二进制格式,那么有没有办法获得一个逐字节的IEEE 754表示?当然,写作也要问同样的问题。

我希望你能理解(布莱奇),但我想你是在问是否有内在的东西。我从来没有听说过;请参见的第8.5节和第15.7节。

会有帮助吗


如果您需要一个功能强大的解决方案,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);
}
函数解码浮点(数据){
var binary=parseInt(数据,16).toString(2);
if(二进制长度<32)
二进制=('00000000000000000000'+二进制).substr(二进制.length);
变量符号=(二进制字符(0)='1')?-1:1;
var指数=parseInt(二进制.substr(1,8,2)-127;
var有效基=二进制.substr(9);
var有效位bin='1'+有效位基;
var i=0;
var=1;
var有效位=0;
如果(指数==-127){
if(有效位基.indexOf('1')=-1)
返回0;
否则{
指数=-126;
有效位bin='0'+有效位基;
}
}
而(i<有效位长度){
有效位+=val*parseInt(有效位bin.charAt(i));
val=val/2;
i++;
}
返回符号*有效位*数学功率(2,指数);
}
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当然不是一个选项(在我的情况下,我正在使用一个不可用的环境):

函数字节数2float32(字节){
变量符号=(字节和0x8000000)?-1:1;
变量指数=((字节>>23)和0xFF)-127;

var-signifid=(bytes&~(-1我有一个类似的问题,我想将任何javascript数字转换成一个缓冲区,然后在不字符串化的情况下将其解析回来

函数numberToBuffer(num){
const buf=新缓冲区(8)
buf.writeDoubleLE(num,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位浮点可以很好地工作,而不会出现舍入问题).Cool,TIL
Double
在Javascript中被称为
Float64
。我一直在寻找
DoubleArray
,但没有用-但是
Float64Array
存在,并且看起来很有用。请注意,IE9中不支持这一点!看起来您可以使用
Uint8Array
(至少在Chrome中)Netscape Navigator对@bryc的支持也不完善,而不是使用
Int32Array
更容易获取单个字节“”。
if(有效位==0)返回符号*0.0;
-肯定任何乘以零的东西都是…零吗?
-1*0.0
会产生负零吗?@Haravik,获取数字的位表示怎么样?@Pacerier:我对另一个问题的回答应该有帮助:我可以确认这也适用于Node.js 0.10.40。使用我的旧版本Node RED(0.11.1)我显然没有访问Float32Array的权限,因此您的解决方案是我唯一的解决方案!我使用“new Buffer(array)”从4字节二进制浮点数组和Buffer.readFloatBE(0)创建缓冲区为了检索Node.JS 10.15上测试的float.Tested,此解决方案似乎比使用类型化数组更快。显然,如果不使用Node.JS,就不能使用缓冲区。
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
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