JavaScript打包整数并计算任意精度浮点:

JavaScript打包整数并计算任意精度浮点:,javascript,binary-data,integer,arbitrary-precision,Javascript,Binary Data,Integer,Arbitrary Precision,我需要在JavaScript中执行以下操作,但目前还无法找到无缝执行的解决方案: 按特定顺序获取两个整数,并像Python的结构模块一样打包它们 此压缩值(支持不同于主机的端性的额外值)将转换为64位浮点(双精度)。它们必须是任意的,因此我可能得到整数的指数表示(比如,它们可以是0x0和500): exp格式: 1.0883076389305e-311 1.0883076389305000*10^-311 我需要将其转换为任意精度、非指数形式,因此: 0.0000000000000000000

我需要在JavaScript中执行以下操作,但目前还无法找到无缝执行的解决方案:

  • 按特定顺序获取两个整数,并像Python的结构模块一样打包它们
  • 此压缩值(支持不同于主机的端性的额外值)将转换为64位浮点(双精度)。它们必须是任意的,因此我可能得到整数的指数表示(比如,它们可以是0x0和500):

    exp格式: 1.0883076389305e-311 1.0883076389305000*10^-311

  • 我需要将其转换为任意精度、非指数形式,因此:

    0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

  • 该数字已转换为字符串:)

我还没有在Javascript中找到这样做的方法,我必须输出一些数字,比如必须支持任意精度的数字,或者至少支持1024个指数(或者说400个)的倍数

谢谢

注意:我确实需要“打包/解包”是转换为双/64位浮点的两个数字的忠实表示。但我不关心,比如说,导出到字符串或原始缓冲区。只要我得到一个任意精度的双精度表示,这一切都很好。

1:Khronos有一个用于
DataView
的接口,作为WebGL
TypedArray
要求的一部分,它与
Int32Array
Float64Array
相结合,可以让您将两个整数写入缓冲区,然后把它们作为替身读出来

不幸的是,浏览器对这一点的支持还不普遍——要测试您的浏览器,请访问并查看标题为“本机二进制数据”的部分

如果没有上面的
TypedArray
支持,我认为没有任何方法可以使用位旋转来实现这一点,因为Javascript的位运算符将数字视为32位无符号值,因此您将无法访问高阶位

2:
double
变量没有任何特定的形式,IEE754只是一个内部表示

3:这是您可以尝试显示实际精度的点。不幸的是,内置方法,例如
Number.toFixed()
,不支持显示超过20位小数。您将需要解析指数形式,并手动构造一个具有适当数量前导零的字符串

NB-双精度的指数范围是2^1024,而不是10^1024,因此实际极限实际上是~1.0E±308-您的示例数字小于该范围

编辑实际上,可能有一种方法,但我不能保证其准确性:

  • 取两个整数,分别称为
    hi
    lo
  • 提取指数-
    exp=(hi>>20)&0x7ff
  • 提取符号-
    符号=(hi>>31)
  • 提取尾数-
    ((hi&0xfffffff)*Math.pow(2,32)+lo)/Math.pow(2,52)
  • result=(1+m)*(Math.pow(2.0,exp-1023))
  • if(sign)result*=-1
  • 编辑2-它可以工作!看

    在处输入一个浮点数,从输出的底行获取结果十六进制字符串,并将其传递给上面的函数。您应该会看到一个包含原始值的警报


    编辑3修复代码,以说明指数位均为零时的特殊情况。

    我认为您需要一个用于JavaScript的大数字库,例如。

    哈哈,我会调用一个在服务器上执行此操作的web服务。介意我问一下为什么需要用javascript来做吗?因为这在技术上是一个挑战,而现在由于JIT,javascript比做整个服务器端处理要快得多。没有理由给服务器增加负担。@soze-在服务器上,打包两个int并将它们解包成一个double将是微不足道的。在javascript上也是如此,我认为这会更复杂。对于这样一个简单的过程来说,最重要的是计算和通信负担过重。这一切加起来远比它的价值mroe(做在客户端);(哦,关于字符串表示法,你为什么建议只在它前面加上零呢?我的意思是,*10^300的乘积肯定是一个很小的数字,前面加上尽可能多的零……但是如果你能举一个例子说明它适用于任意数字,我会很感激的。内置的JS类型不支持任意数字,它们只支持端口IEE754双精度格式。我只需要一个64位双精度…并且我只需要任意精度库将其转换为非指数表示,然后将其发送到web服务,这就需要这样。我仍然无法搜索打包/解包机制来处理这两个整数。@soze非常小的数字的特例已修复除e<10e-308的数字外,所有数字的函数均正常
    var hex2double = function(input) {
    
        var hi = parseInt(input.substring(0, 8), 16);
        var lo = parseInt(input.substring(8   ), 16);
    
        var p32 = 0x100000000;
        var p52 = 0x10000000000000;
    
        var exp = (hi >> 20) & 0x7ff;
        var sign = (hi >> 31);
        var m = 1 + ((hi & 0xfffff) * p32 + lo) / p52;
        m = exp ? (m + 1) : (m * 2.0);
    
        return (sign ? -1 : 1) * m * Math.pow(2, exp - 1023);
    };