2011-07-20 50 views
2

我需要做的JavaScript以下和迄今未能找到解决办法做无缝:的JavaScript包整数和计算任意精度浮点:

  • 抢两个整数按照特定的顺序和包装他们像Python的结构模块。
  • 这个包装值(支持不同的字节序比主机的奖金)将变成64位浮点数(双精度)。他们必须是任意因此,我可能会得到整数的指数表示(比如,他们可以0xdeadbeef和500):

    在EXP的形式: 1.0883076389305e-311 1.0883076389305000 * 10^- 311

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

    0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000108830763893050000000000000000000000000000000000000000000000000000000000000000000000000000

  • 这个数字转换为字符串:)

我还没有找到一种方法在Javascript做到这一点,我必须输出一样,它必须支持任意精度,或者一些数字至少是一个达到1024指数(或者说400)双倍的规模。

谢谢!

注意:我确实需要“打包/解包”作为转换为双精度/ 64位浮点数的这两个数字的忠实表示,但我并不在乎导出到字符串或原始缓冲区。只要我得到一个任意精度的双重代表的双重它的一切优秀

+1

哈哈,我会打电话给服务器上的Web服务。介意,如果我问你为什么需要在JavaScript中做到这一点? –

+0

因为它在技术上是一个挑战,而且由于JIT的缘故,这些日子比整个服务器端处理的事情要快得多。没有借口给服务器增加更多的负担。 – soze

+1

@soze - 在服务器上,装入两个整数并将它们解压缩为一个双精度值将是微不足道的。 – Alnitak

回答

4

1:Khronos的有一个DataView接口specification in progress作为WebGL的TypedArray要求的一部分,它与Int32Array和合并Float64Array会让你wri把你的两个整数放入一个缓冲区,然后把它们读出来作为一个double。

不幸的是,浏览器对此的支持尚不常见 - 要测试您的浏览器访问http://html5test.com/并查看标题为“本机二进制数据”的部分。

没有TypedArray支持上面,我不认为有任何办法,因为JavaScript的位运算符将数字作为32位无符号值来做到这一点使用位变换,所以你必须给higher-进不去顺序位。

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

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

NB - double的指数范围是2^1024,而不是10^1024,因此实际的限制实际上是〜1.0E±308 - 您的示例图小于该范围。

编辑实际上,有可能是一个办法,但我不能保证这个精度:

  1. 把你两个整数,称他们为hilo
  2. 提取指数 - exp = (hi >> 20) & 0x7ff
  3. 提取标志 - sign = (hi >> 31)
  4. 提取尾数 - ((hi & 0xfffff) * Math.pow(2, 32) + lo)/Math.pow(2, 52)
  5. result = (1 + m) * (Math.pow(2.0, exp - 1023))
  6. if (sign) result *= -1

EDIT 2 - 它的作品!见http://jsfiddle.net/alnitak/assXS/

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); 
}; 

http://babbage.cs.qc.edu/IEEE-754/Decimal.html输入一个浮点数,从输出的底部行取所得十六进制字符串,并且在其上方传递给该函数。您应该看到包含原始值的警报。

编辑3修正代码以解释指数位全为零时的特殊情况。

+0

我只是要求一个JS-only的解决方案,我不能依赖于其他任何东西;( – soze

+0

哦,关于字符串表示,为什么你建议简单地用零作为前缀?我的意思是,确定* 10^300将是一个很小的数字,前缀数目为零......但是如果你可以展示一个适用于任意数字的例子,我将不胜感激 – soze

+0

内置的JS类型不支持任意数字,它们只支持IEE754双格式 – Alnitak