I need to do the following in JavaScript and so far been unable to find solutions to do it seamlessly:
- 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):
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
-
That number converted to a string 🙂
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.
Thanks!!
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 has a specification in progress for a
DataViewinterface as part of the WebGLTypedArrayrequirements, which combined withInt32ArrayandFloat64Arraywould let you write your two ints into a buffer, and read them back out as a double.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”.
Without the
TypedArraysupport 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:
doublevariables don’t have any specific form, IEE754 is just an internal representation.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 – 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:
hiandlo.exp = (hi >> 20) & 0x7ffsign = (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 *= -1EDIT 2 – it works! See http://jsfiddle.net/alnitak/assXS/
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.
EDIT 3 code fixed to account for the special case when the exponent bits are all zero.