Suppose I have a hex number "4072508200000000" and I want the floating point number that it represents (293.03173828125000) in IEEE-754 double format to be put into a JavaScript variable.

I can think of a way that uses some masking and a call to pow(), but is there a simpler solution?

A client-side solution is needed.

This may help. It's a website that lets you enter a hex encoding of an IEEE-754 and get an analysis of mantissa and exponent.

http://babbage.cs.qc.edu/IEEE-754/64bit.html

Because people always tend to ask "why?," here's why: I'm trying to fill out an existing but incomplete implementation of Google's Procol Buffers (protobuf).

I don't know of a good way. It certainly can be done the hard way, here is a single-precision example totally within JavaScript:

```
js> a = 0x41973333
1100428083
js> (a & 0x7fffff | 0x800000) * 1.0 / Math.pow(2,23) * Math.pow(2, ((a>>23 & 0xff) - 127))
18.899999618530273
```

A production implementation should consider that most of the fields have magic values, typically implemented by specifying a special interpretation for what would have been the largest or smallest. So, detect `NaN`

s and infinities. The above example should be checking for negatives. (a & 0x80000000)

Update: Ok, I've got it for double's, too. You can't directly extend the above technique because the internal JS representation is a double, and so by its definition it can handle at best a bit string of length 52, and it can't shift by more than 32 at all.

Ok, to do double you first chop off *as a string* the low 8 digits or 32 bits; process them with a separate object. Then:

```
js> a = 0x40725082
1081233538
js> (a & 0xfffff | 0x100000) * 1.0 / Math.pow(2, 52 - 32) * Math.pow(2, ((a >> 52 - 32 & 0x7ff) - 1023))
293.03173828125
js>
```

I kept the above example because it's from the OP. A harder case is when the low 32-bits have a value. Here is the conversion of 0x40725082deadbeef, a full-precision double:

```
js> a = 0x40725082
1081233538
js> b = 0xdeadbeef
3735928559
js> e = (a >> 52 - 32 & 0x7ff) - 1023
8
js> (a & 0xfffff | 0x100000) * 1.0 / Math.pow(2,52-32) * Math.pow(2, e) +
b * 1.0 / Math.pow(2, 52) * Math.pow(2, e)
293.0319506442019
js>
```

There are some obvious subexpressions you can factor out but I've left it this way so you can see how it relates to the format.

A quick addition to DigitalRoss' solution, for those finding this page via Google as I did.

Apart from the edge cases for +/- Infinity and NaN, which I'd love input on, you also need to take into account the sign of the result:

```
s = a >> 31 ? -1 : 1
```

You can then include `s`

in the final multiplication to get the correct result.

I think for a little-endian solution you'll also need to reverse the bits in `a`

and `b`

and swap them.

The new Typed Arrays mechanism allows you to do this (and is probably an ideal mechanism for implementing protocol buffers):

```
var buffer = new ArrayBuffer(8);
var bytes = new Uint8Array(buffer);
var doubles = new Float64Array(buffer); // not supported in Chrome
bytes[7] = 0x40; // Load the hex string "40 72 50 82 00 00 00 00"
bytes[6] = 0x72;
bytes[5] = 0x50;
bytes[4] = 0x82;
bytes[3] = 0x00;
bytes[2] = 0x00;
bytes[1] = 0x00;
bytes[0] = 0x00;
my_double = doubles[0];
document.write(my_double); // 293.03173828125
```

This assumes a little-endian machine.

Unfortunately Chrome does not have `Float64Array`

, although it does have `Float32Array`

. The above example does work in Firefox 4.0.1.

©2020 All rights reserved.