Introduction
This code takes a IEEE single-precision (32 bit) number that has been stuffed in a 32 bit unsigned integer and converts it to a floating point number. This situation can often occur when receiving a stream of binary information with floating point values embedded in the stream. Converting the packed bytes into a floating point number is easy in most languages using type-punning or other conversion techniques, but is not so easy with JavaScript.
Background
I am interfacing to an industrial device that has a built-in web server. I can receive events from the device by connecting to a special URL. It outputs events as a continual stream of JSON constructs. The data consists of an event identifier as a 32 bit unsigned number, and an optional parameter that is also a 32 bit unsigned number. For most events, the optional parameter is an integer or bit fields, easy to manipulate with JavaScript. However, for a few events, the value is really an IEEE single precision number that was emitted as an integer. I needed to convert this number back to floating point to properly interpret it. A search of the Internet did not show any concrete examples, so I wrote my own.
Using the Code
This is a global function that takes an integer value as input and return a floating point value. It breaks up the integer into its various fields as defined by the IEEE 754 specification and reconstructs them into a floating point number. It only works for 32 bit single precision numbers. And it doesn't return negative zero and subnormal numbers.
function ieee32ToFloat(intval) {
var fval = 0.0;
var x; var m; var s; s = (intval & 0x80000000)?-1:1;
x = ((intval >> 23) & 0xFF);
m = (intval & 0x7FFFFF);
switch(x) {
case 0:
break;
case 0xFF:
if (m) fval = NaN;
else if (s > 0) fval = Number.POSITIVE_INFINITY;
else fval = Number.NEGATIVE_INFINITY;
break;
default:
x -= 127;
m += 0x800000;
fval = s * (m / 8388608.0) * Math.pow(2, x);
break;
}
return fval;
}
I'm a novice when it comes to JavaScript, so if you see a better way of implementing this, please post it. If you want to make a 64 bit double precision example, post it too for the next guy.
History
- 19 May 2012 - Initial release