I'm trying to convert the following hex string: "40934B999999999A" to 1234.9 (float-64).
I looked for several solutions posted on the internet, but most of them were only codes that gave answers different from what I needed, such as changing hex to float type.
Because I am using a legacy solution, I am in an environment where I cannot use es6 or higher syntax (eg DataView or Int16Array).
How can I get a javascript function that gives me the answer I need?
Thank you
The following ES1-compatible function exactly converts a hexadecimal string into a 64-bit floating-point number.
It can return only numbers representable in JavaScript, so NaNs will lose their payload.
function hex_to_number(str) {
// Pad the string with zeroes to 16 characters.
// You can omit this if you control your inputs.
str = (str + "0000000000000000").slice(0,16);
// Split into bits: sign (1), exponent (11), significand (52).
var sign_and_exponent_bits = parseInt(str.slice(0,3), 16);
var sign = sign_and_exponent_bits >= 0x800 ? -1 : +1;
var exponent_bits = sign_and_exponent_bits & ((1<<11) - 1);
var significand_bits = parseInt(str.slice(3,16), 16);
// Classify the floating-point value.
if (exponent_bits == 0x7FF) // infinity | not a number
return significand_bits == 0 ? sign * Number.POSITIVE_INFINITY : Number.NaN;
else if (exponent_bits == 0) // zero | subnormal number
return sign * Math.pow(2, 1-1023-52) * significand_bits;
else // normal number
return sign * Math.pow(2, exponent_bits-1023-52) * (Math.pow(2, 52) + significand_bits);
}
For your example "40934B999999999A":
Edit: If you can't trust the implementation of Math.pow(2, n)
, you can compute it with the following function:
function ldexp(x, n) { // compute 2^n * x, assume n is an integer
if (!isFinite(x) || x == 0) return x;
if (n < -2098) return x * 0;
if (n > 2097) return x * Number.POSITIVE_INFINITY;
// Make negative exponents positive.
var p = 2;
if (n < 0) { n = -n; p = 0.5; }
// Compute 2^n by binary exponentiation.
for (var i=1; ; i<<=1) {
if (n & i) x *= p;
if (i == 512) break;
p *= p;
}
// Do the remaining bits manually because 2^1024 overflows.
if (n & 1024) { x *= p; x *= p; }
if (n & 2048) { x *= p; x *= p; x *= p; x *= p; }
return x;
}