I need to do the following in JavaScript and so far been unable to find solutions to do it seamlessly:
I think you need a big number library for JavaScript such as http://jsfromhell.com/classes/bignumber.
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.
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 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
variables 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:
hi
and lo
.exp = (hi >> 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
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);
};
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.