7

I found a code from here that converts Javascript number to inner IEEE representation as two Uint32 values:

function DoubleToIEEE(f)
{
  var buf = new ArrayBuffer(8);
  (new Float64Array(buf))[0] = f;
  return [ (new Uint32Array(buf))[0] ,(new Uint32Array(buf))[1] ];
}

How to convert the returned value back to Javascript number? This way:

var number = -10.3245535;
var ieee = DoubleToIEEE(number)
var number_again = IEEEtoDouble(ieee);
// number and number_again should be the same (if ever possible)
1

2 Answers 2

8

I found a possible solution, which seems to work:

function IEEEToDouble(f)
{
  var buffer = new ArrayBuffer(8);
  (new Uint32Array(buffer))[0] = f[0];
  (new Uint32Array(buffer))[1] = f[1];
  return new Float64Array(buffer)[0];
}

Usage:

var a = DoubleToIEEE(-0.1234);
console.log(a); // [0, 3220176896]
var b = IEEEToDouble(a);
console.log(b); // -0.1234
Sign up to request clarification or add additional context in comments.

2 Comments

If anyone looking to convert from binary representation string: const BinaryStringToDouble = (x) => IEEEToDouble([x.substring(32), x.substring(0, 32)].map(p => parseInt(p, 2)));
beware of byte order; use DataView
7

That code is ugly as hell. Use

function DoubleToIEEE(f) {
  var buf = new ArrayBuffer(8);
  var float = new Float64Array(buf);
  var uint = new Uint32Array(buf);
  float[0] = f;
  return uint;
}

If you want an actual Array instead of a Uint32Array (shouldn't make a difference in the most cases), add an Array.from call. You can also reduce this to a oneliner by passing the value to the Float64Array constructor:

function DoubleToIEEE(f) {
  // use either
  return new Uint32Array(Float64Array.of(f).buffer);
  return Array.from(new Uint32Array(Float64Array.of(f).buffer));
  return Array.from(new Uint32Array((new Float64Array([f])).buffer));
}

The inverse would just write the inputs into the uint slots and return the float[0] value:

function IEEEToDouble(is) {
  var buf = new ArrayBuffer(8);
  var float = new Float64Array(buf);
  var uint = new Uint32Array(buf);
  uint[0] = is[0];
  uint[1] = is[1];
  return float[0];
}

which can be shortened to

function IEEEToDouble(is) {
  return (new Float64Array(Uint32Array.from(is).buffer))[0];
}

5 Comments

Could you kindly explain to us dummies why the code is ugly?
@TimoKähkönen The assignment to the throwaway-typedarray on the left hand side is confusing, it's better to write it out explicitly with a variable. And the two Uint32Arrays where one would suffice seem inefficient. All that makes it hard to understand the data flow and find the inverse function. And of course, I prefer the single-expression forms :-)
Thanks for the explanation. I accepted your answer.
which version of Javascript/ECMAscript does this require?
@JasonS ES6, though typed arrays can be polyfilled and were supported in some browsers earlier than ES6 as well IIRC.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.