JavaScript包整数并计算任意精度浮点数: [英] JavaScript pack integers and calculate arbitrary precision float:
问题描述
我需要在JavaScript中执行以下操作,到目前为止无法找到无缝执行的解决方案:
I need to do the following in JavaScript and so far been unable to find solutions to do it seamlessly:
- 抓住两个整数一个特定的顺序,并将它们打包为Python的struct模块。
-
这个打包值(支持不同于字节的字节序的奖励)将变成64位浮点数(双精度)。它们必须是任意的,因此我可能得到整数的指数表示(例如,它们可能是0xdeadbeef和500):
- Grab two integers in a specific order and pack them like Python's struct module.
This packed value, (bonus for supporting different endianness than host) will be turned into a 64 bit float (double). They must be arbitrary thus I might get an exponent representation of the integer (say, they could be 0xdeadbeef and 500):
在exp形式中:
1.0883076389305e -311
1.0883076389305000 * 10 ^ - 311
In exp form: 1.0883076389305e-311 1.0883076389305000 * 10 ^ - 311
我需要将其转换为任意精度,非指数形式,所以:
I need to convert it to the arbitrary precision, non-exponent form, so:
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000108830763893050000000000000000000000000000000000000000000000000000000000000000000000000000
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000108830763893050000000000000000000000000000000000000000000000000000000000000000000000000000
转换为字符串即编号:)
That number converted to a string :)
我还没有找到一种在Javascript中执行此操作的方法,我必须输出一些必须支持任意精度的数字,或者至少是最多1024个世博会nent(或者说400)双打。
I haven't found a way to do this in Javascript and I have to output some numbers like that which must support arbitrary precision, or at least, of a scale up to the 1024 exponent (or, say 400) of doubles.
谢谢!!
注意:我确实需要打包/拆包'是忠实再现这两个转换为双/ 64位浮点数的数字。但是我不关心,比如导出到字符串或原始缓冲区。只要我获得双精度的任意精度双重表示就可以了。
Note: I do need the "packing/unpacking' to be a faithful representation of those two numbers converted to a double/64bit float. But I don't care about, say, exporting to a string or raw buffer. As long as I get an arbitrary precision double representation for the double it's all fine.
推荐答案
1:Khronos有正在进行的规范 DataView
接口作为WebGL TypedArray
要求的一部分,与 结合使用Int32Array
和 Float64Array
可以让你将两个整数写入一个缓冲区,并将它们读出来作为双倍。
1: Khronos has a specification in progress for a DataView
interface as part of the WebGL TypedArray
requirements, which combined with Int32Array
and Float64Array
would let you write your two ints into a buffer, and read them back out as a double.
不幸的是,浏览器对此的支持还不常见 - 测试浏览器访问 http://html5test.com/ 并查看标题为原生二进制数据的部分。
Unfortunately browser support for this isn't common yet - to test your browser visit http://html5test.com/ and look at the section entitled "Native binary data".
没有 <上面的code> TypedArray 支持我认为没有任何办法可以使用bit-twiddling来实现这一点,因为Javascript的位运算符将数字视为32-b它是无符号值,因此您无法访问高阶位。
Without the TypedArray
support above I don't think there's any way to do this using bit-twiddling since Javascript's bit operators treat numbers as 32-bit unsigned values, so you'd have no access to the higher-order bits.
2: double
变量没有任何特定的表格,IEE754只是一个内部表示。
2: double
variables don't have any specific form, IEE754 is just an internal representation.
3:那是你可以尝试展示实际精度。不幸的是,内置方法,例如, Number.toFixed()
,不支持showinng超过20个小数位。您将需要解析指数形式并手动构造一个具有适当数量的前导零的字符串。
3: that's the point at which you can attempt to show the actual precision. Unfortunately the built-in method, e.g. Number.toFixed()
, doesn't support showinng more than 20 decimal places. You will need to parse the exponential form and manually construct a string with the appropriate number of leading zeros.
NB - 双精度的指数范围是2 ^ 1024,而不是10 ^ 1024,因此实际限制实际上是~1.0E±308 - 您的示例数字小于该范围。
NB - the exponent range of a double is 2^1024, not 10^1024, hence the real limit is actually ~1.0E±308 - your example figure is smaller than that range.
编辑实际上,可能有办法,但我不能保证这个的精确度:
EDIT actually, there might be a way, but I can't guarantee the precision of this:
- 取两个整数,称之为
hi
和lo
。 - 提取指数 -
exp =(嗨>> 20)& 0x7ff
- 提取标志 -
sign =(hi>> 31)
- 提取尾数 -
((hi& 0xfffff)* Math.pow(2,32)+ lo)/ Math.pow(2,52)
-
result =(1 + m)*(Math.pow(2.0,exp - 1023))
-
if(sign)result * = -1
- take your two integers, call them
hi
andlo
. - extract the exponent -
exp = (hi >> 20) & 0x7ff
- extract the sign -
sign = (hi >> 31)
- extract the mantissa -
((hi & 0xfffff) * Math.pow(2, 32) + lo) / Math.pow(2, 52)
result = (1 + m) * (Math.pow(2.0, exp - 1023))
if (sign) result *= -1
编辑2 - 它有效!请参阅 http://jsfiddle.net/alnitak/assXS/
EDIT 2 - it works! See 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 ,从底行获取生成的十六进制字符串输出,并将其传递给上面的函数。您应该会看到一个包含原始值的提醒。
Enter a floating point number at http://babbage.cs.qc.edu/IEEE-754/Decimal.html, take the resulting hex string from the bottom row of output, and pass it to the function above. You should see an alert containing the original value.
编辑3 代码已修复,以解决当指数位全为零时的特殊情况。
EDIT 3 code fixed to account for the special case when the exponent bits are all zero.
这篇关于JavaScript包整数并计算任意精度浮点数:的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!